/*
	This is a pseudo code demonstrate simple uart bi-directional protocol
	some of the functions are not defined, but by name explins there job
*/




// timeout definitions
QUIET_TIMEOUT 
KEEP_ALIVE_TIMEOUT 
TX_RETRY_TIMEOUT 
TX_MAX_RETRY_COUNT 

//tx definitions
TX_READY
TX_BUSY


//event definitions
RX_ISSUE
MESSAGE_RECEIVED
TX_COMMAND
TX_ENDED
TIMEOUT_EXPIRED



//whenever activity occures in rx pin, switch it to uart rx
pinIoCallback()
{
	setRxAsUartPin();
	EventPost(RX_ACTIVITY);
}


//called by application
putCommandInQueue(cmd)
{
	QueuePut(cmd);
	EventPost(TX_COMMAND)
}


uartTaskFcn(void)
{
	timeout = KEEP_ALIVE_TIMEOUT;
	while(1)
	{
		event = EventPend(timeout);
		wokenTimeout = timeout;
		timeout = KEEP_ALIVE_TIMEOUT;
		if(event == RX_ISSUE)
		{
			uartRead(1);
			timeout = QUIET_TIMEOUT;
		}
		
		if(event == MESSAGE_RECEIVED)
		{
			if( checkIfMessageIsAck(rxBuff) )
			{
				//if first message in queue is acknowledge by the received message,
				//extract it from queue
				QueueExtract(cmd);
				//stop tx timer
				TxTimerStop();
			}
			else
			{
				//upload recieved message to app
				putRecievedMsgInApp(rxBuff);
			}
		
			timeout = KEEP_ALIVE_TIMEOUT;
		}
		if(event == TX_COMMAND)
		{
			//command handle and send mechanism
			handleCommandAndSend();
			timeout = QUIET_TIMEOUT;
		}
		
		if(event == TX_ENDED)
		{
			//command handle and send mechanism
			txState = TX_READY;
			timeout = QUIET_TIMEOUT;
		}
		
		if(event == TIMEOUT_EXPIRED )
		{
			//if the timeout expired was keepalive, close uart (power consumption considerations)
			if(wokenTimeout == KEEP_ALIVE_TIMEOUT )
			{
				closeUart();
				setRxAsGpioPin();
			}
		}

		
	}
	
}


handleCommandAndSend()
{
//check if tx is ready to sent
	if(txState == TX_READY)
	{

		//take (not extract) first waiting message
		QueuePeek(cmd);
		
		
		
		if(retryCnt < TX_MAX_RETRY_COUNT)
		{
			txState = TX_BUSY;
			WriteCmdBytesInBuffer(cmd,txBuffer);
			uartWrite(txBuffer);
			//open timer, and wait for ack
			TxTimerStart(TX_RETRY_TIMEOUT );
		}
		else
		{
			retryCnt =0;
			//no more retries, throw message away
			QueueExtract(cmd);
		}
		
	}
	
}

uartReadCallback(byte)
{
	//prasing message, according to application protocol
	//if succed, notify task
	if(PARSE_OK == parse(byte,rxBuffer) )
	{
		EventPost(MESSAGE_RECEIVED);
	}
	//initiate next read
	uartRead(1);	
}


uartWriteCallback()
{
	EventPost(TX_ENDED);
}