/*
    FreeRTOS V7.5.3 - Copyright (C) 2013 Real Time Engineers Ltd. 
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that has become a de facto standard.             *
     *                                                                       *
     *    Help yourself get started quickly and support the FreeRTOS         *
     *    project by purchasing a FreeRTOS tutorial book, reference          *
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
     *                                                                       *
     *    Thank you!                                                         *
     *                                                                       *
    ***************************************************************************

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.

    >>! NOTE: The modification to the GPL is included to allow you to distribute
    >>! a combined work that includes FreeRTOS without being obliged to provide
    >>! the source code for proprietary components outside of the FreeRTOS
    >>! kernel.

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
    link: http://www.freertos.org/a00114.html

    1 tab == 4 spaces!

    ***************************************************************************
     *                                                                       *
     *    Having a problem?  Start by reading the FAQ "My application does   *
     *    not run, what could be wrong?"                                     *
     *                                                                       *
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
    license and Real Time Engineers Ltd. contact details.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/


/*
 * Creates a task and a timer that operate on an interrupt driven serial port.
 * This demo assumes that the characters transmitted on a port will also be
 * received on the same port.  Therefore, the UART must either be connected to
 * an echo server, or the uart connector must have a loopback connector fitted.
 * See http://www.serialporttool.com/CommEcho.htm for a suitable echo server
 * for Windows hosts.
 *
 * The timer sends a string to the UART, toggles an LED, then resets itself by 
 * changing its own period.  The period is calculated as a pseudo random number 
 * between comTX_MAX_BLOCK_TIME and comTX_MIN_BLOCK_TIME.
 *
 * The task blocks on an Rx queue waiting for a character to become available.  
 * Received characters are checked to ensure they match those transmitted by the 
 * Tx timer.  An error is latched if characters are missing, incorrect, or 
 * arrive too slowly.
 *
 * How characters are actually transmitted and received is port specific.  Demos
 * that include this test/demo file will provide example drivers.  The Tx timer
 * executes in the context of the timer service (daemon) task, and must 
 * therefore never attempt to block.
 *
 */

/* Scheduler include files. */
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

#ifndef configUSE_TIMERS
	#error This demo uses timers.  configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
#endif

#if configUSE_TIMERS != 1
	#error This demo uses timers.  configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
#endif


/* Demo program include files. */
#include "serial.h"
#include "comtest_strings.h"
#include "partest.h"

/* The size of the stack given to the Rx task. */
#define comSTACK_SIZE				configMINIMAL_STACK_SIZE

/* See the comment above the declaraction of the uxBaseLED variable. */
#define comTX_LED_OFFSET			( 0 )
#define comRX_LED_OFFSET			( 1 )

/* The Tx timer transmits the sequence of characters at a pseudo random
interval that is capped between comTX_MAX_BLOCK_TIME and
comTX_MIN_BLOCK_TIME. */
#define comTX_MAX_BLOCK_TIME		( ( portTickType ) 0x96 )
#define comTX_MIN_BLOCK_TIME		( ( portTickType ) 0x32 )
#define comOFFSET_TIME				( ( portTickType ) 3 )

/* States for the simple state machine implemented in the Rx task. */
#define comtstWAITING_START_OF_STRING 	0
#define comtstWAITING_END_OF_STRING		1

/* A short delay in ticks - this delay is used to allow the Rx queue to fill up
a bit so more than one character can be processed at a time.  This is relative
to comTX_MIN_BLOCK_TIME to ensure it is never longer than the shortest gap
between transmissions.  It could be worked out more scientifically from the
baud rate being used. */
#define comSHORT_DELAY				( comTX_MIN_BLOCK_TIME >> ( portTickType ) 2 )

/* The string that is transmitted and received. */
#define comTRANSACTED_STRING		"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

/* A block time of 0 simply means "don't block". */
#define comtstDONT_BLOCK			( portTickType ) 0

/* Handle to the com port used by both tasks. */
static xComPortHandle xPort = NULL;

/* The callback function allocated to the transmit timer, as described in the
comments at the top of this file. */
static void prvComTxTimerCallback( xTimerHandle xTimer );

/* The receive task as described in the comments at the top of this file. */
static void vComRxTask( void *pvParameters );

/* The Rx task will toggle LED ( uxBaseLED + comRX_LED_OFFSET).  The Tx task
will toggle LED ( uxBaseLED + comTX_LED_OFFSET ). */
static unsigned portBASE_TYPE uxBaseLED = 0;

/* The Rx task toggles uxRxLoops on each successful iteration of its defined
function - provided no errors have ever been latched.  If this variable stops
incrementing, then an error has occurred. */
static volatile unsigned portBASE_TYPE uxRxLoops = 0UL;

/* The timer used to periodically transmit the string.  This is the timer that
has prvComTxTimerCallback allocated to it as its callback function. */
static xTimerHandle xTxTimer = NULL;

/* The string length is held at file scope so the Tx timer does not need to
calculate it each time it executes. */
static size_t xStringLength = 0U;

/*-----------------------------------------------------------*/

void vStartComTestStringsTasks( unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED )
{
	/* Store values that are used at run time. */
	uxBaseLED = uxLED;

	/* Calculate the string length here, rather than each time the Tx timer
	executes. */
	xStringLength = strlen( comTRANSACTED_STRING );

	/* Include the null terminator in the string length as this is used to
	detect the end of the string in the Rx task. */
	xStringLength++;

	/* Initialise the com port, then spawn the Rx task and create the Tx
	timer. */
	xSerialPortInitMinimal( ulBaudRate, ( xStringLength * 2U ) );

	/* Create the Rx task and the Tx timer.  The timer is started from the
	Rx task. */
	xTaskCreate( vComRxTask, ( signed char * ) "COMRx", comSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );
	xTxTimer = xTimerCreate( ( const signed char * ) "TxTimer", comTX_MIN_BLOCK_TIME, pdFALSE, NULL, prvComTxTimerCallback );
	configASSERT( xTxTimer );
}
/*-----------------------------------------------------------*/

static void prvComTxTimerCallback( xTimerHandle xTimer )
{
portTickType xTimeToWait;

	/* The parameter is not used in this case. */
	( void ) xTimer;

	/* Send the string.  How this is actually performed depends on the
	sample driver provided with this demo.  However - as this is a timer,
	it executes in the context of the timer task and therefore must not
	block. */
	vSerialPutString( xPort, ( const signed char * const ) comTRANSACTED_STRING, xStringLength );

	/* Toggle an LED to give a visible indication that another transmission
	has been performed. */
	vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET );

	/* Wait a pseudo random time before sending the string again. */
	xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME;

	/* Ensure the time to wait is not greater than comTX_MAX_BLOCK_TIME. */
	xTimeToWait %= comTX_MAX_BLOCK_TIME;

	/* Ensure the time to wait is not less than comTX_MIN_BLOCK_TIME. */
	if( xTimeToWait < comTX_MIN_BLOCK_TIME )
	{
		xTimeToWait = comTX_MIN_BLOCK_TIME;
	}

	/* Reset the timer to run again xTimeToWait ticks from now.  This function
	is called from the context of the timer task, so the block time must not
	be anything other than zero. */
	xTimerChangePeriod( xTxTimer, xTimeToWait, comtstDONT_BLOCK );
}
/*-----------------------------------------------------------*/

static void vComRxTask( void *pvParameters )
{
portBASE_TYPE xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE;
signed char *pcExpectedByte, cRxedChar;
const xComPortHandle xPort = NULL;

	/* The parameter is not used in this example. */
	( void ) pvParameters;

	/* Start the Tx timer.  This only needs to be started once, as it will
	reset itself thereafter. */
	xTimerStart( xTxTimer, portMAX_DELAY );

	/* The first expected Rx character is the first in the string that is
	transmitted. */
	pcExpectedByte = ( signed char * ) comTRANSACTED_STRING;

	for( ;; )
	{
		/* Wait for the next character. */
		if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE )
		{
			/* A character definitely should have been received by now.  As a
			character was not received an error must have occurred (which might
			just be that the loopback connector is not fitted). */
			xErrorOccurred = pdTRUE;
		}

		switch( xState )
		{
			case comtstWAITING_START_OF_STRING:
				if( cRxedChar == *pcExpectedByte )
				{
					/* The received character was the first character of the
					string.  Move to the next state to check each character
					as it comes in until the entire string has been received. */
					xState = comtstWAITING_END_OF_STRING;
					pcExpectedByte++;

					/* Block for a short period.  This just allows the Rx queue 
					to contain more than one character, and therefore prevent
					thrashing reads to the queue, and repetitive context 
					switches as	each character is received. */
					vTaskDelay( comSHORT_DELAY );
				}
				break;

			case comtstWAITING_END_OF_STRING:
				if( cRxedChar == *pcExpectedByte )
				{
					/* The received character was the expected character.  Was
					it the last character in the string - i.e. the null
					terminator? */
					if( cRxedChar == 0x00 )
					{
						/* The entire string has been received.  If no errors
						have been latched, then increment the loop counter to
						show this task is still healthy. */
						if( xErrorOccurred == pdFALSE )
						{
							uxRxLoops++;

							/* Toggle an LED to give a visible sign that a
							complete string has been received. */
							vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
						}

						/* Go back to wait for the start of the next string. */
						pcExpectedByte = ( signed char * ) comTRANSACTED_STRING;
						xState = comtstWAITING_START_OF_STRING;
					}
					else
					{
						/* Wait for the next character in the string. */
						pcExpectedByte++;
					}
				}
				else
				{
					/* The character received was not that expected. */
					xErrorOccurred = pdTRUE;
				}
				break;

			default:
				/* Should not get here.  Stop the Rx loop counter from
				incrementing to latch the error. */
				xErrorOccurred = pdTRUE;
				break;
		}
	}
}
/*-----------------------------------------------------------*/

portBASE_TYPE xAreComTestTasksStillRunning( void )
{
portBASE_TYPE xReturn;

	/* If the count of successful reception loops has not changed than at
	some time an error occurred (i.e. a character was received out of sequence)
	and false is returned. */
	if( uxRxLoops == 0UL )
	{
		xReturn = pdFALSE;
	}
	else
	{
		xReturn = pdTRUE;
	}

	/* Reset the count of successful Rx loops.  When this function is called
	again it should have been incremented again. */
	uxRxLoops = 0UL;

	return xReturn;
}

