/*
 * FreeRTOS Kernel V10.3.1
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/*
	BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0.
*/

/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 * all the API functions to use the MPU wrappers. That should only be done when
 * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

#include "main.h"
#include "serial.h"
#include "log_creat.h"
#include "croutine.h"
#include "uart_type.h"
#include "Lpuart_Uart_Ip.h"
#include "Lpuart_Uart_Ip_Defines.h"

/*-----------------------------------------------------------*/
#define SHELL_PORT_TX_BUF_SZ		512
#define SHELL_PORT_RX_BUF_SZ		256

uint8_t Data_Get(uint8_t com,signed char * ptr,TickType_t xBlockTime);
void Data_Send(uint8_t cChar);
#ifdef _OS_STATISTICS_
extern void openStatistics(uint8_t );
#endif
 static ST_UART_CHAN_DATA ShellPortChannelData;
 static uint8_t ShellPortTxBuf[SHELL_PORT_TX_BUF_SZ];
 static uint8_t ShellPortRxBuf[SHELL_PORT_RX_BUF_SZ];
#define BUFFER_SIZE 3U


uint8_t uatxBuffer;
uint8_t txBufferIdx;

uint8_t uarxBuffer;
uint8_t rxBufferIdx = 0;

//QM_DATA static Uart_Peri_IntrCfg_t* lcfg = SAF_NULL;

//QM_DATA uint8_t ucUartChSelect; 
//QM_DATA uint8_t ucUartChType;


/*-----------------------------------------------------------*/

/* The queue used to hold received characters. */
//static QueueHandle_t xRxedChars;
//static QueueHandle_t xCharsForTx;

/*-----------------------------------------------------------*/

/* UART interrupt handler. */
 
//void vUARTInterruptHandler( void );




/*-----------------------------------------------------------*/

/*
 * See the serial2.h header file.
 */
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, base_t uxQueueLength )
{
	(void)uxQueueLength;
	(void)ulWantedBaud;
	xComPortHandle xReturn = ( xComPortHandle ) 0;

	ShellPortChannelData.RxDroped = 0;
	ShellPortChannelData.RxTrigger = 1;
	vCirqBuffInit(&ShellPortChannelData.TxCycBuffer, (void *)&ShellPortTxBuf[0], sizeof(ShellPortTxBuf), sizeof(uint8_t));
	vCirqBuffInit(&ShellPortChannelData.RxCycBuffer, (void *)&ShellPortRxBuf[0], sizeof(ShellPortRxBuf), sizeof(uint8_t));
	/* If the queue/semaphore was created correctly then setup the serial port
	hardware. */
	//if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) )
	
	xReturn = ( xComPortHandle ) 0;

	/* This demo file only supports a single port but we have to return
	something to comply with the standard demo header file. */
	return xReturn;
}
/*-----------------------------------------------------------*/
uint8_t Data_Get(uint8_t com, signed char *ptr, TickType_t xBlockTime)
{
		(void)com;
		(void)xBlockTime;
		uint8_t fResult = SAF_FALSE;

		if(0 == lCirqBuffPop(&ShellPortChannelData.RxCycBuffer,(void *)ptr))
		{
			fResult = SAF_TRUE;
		}
		else
		{
			;
		}

    	return (fResult);
}

base_t xSerialGetChar(uint8_t com, xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
{
	/* The port handle is not required as this driver only supports one port. */
	uint8_t ret;
	( void ) pxPort;

	/* Get the next character from the buffer.  Return false if no characters
	are available, or arrive before xBlockTime expires. */
	if( Data_Get(com,pcRxedChar, xBlockTime ) )
	{
		ret = OS_TRUE;
	}
	else
	{
		ret = OS_FALSE;
	}
	return ret;
}

/*-----------------------------------------------------------*/

void vSerialPutString( uint8_t ch,xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
{
	signed char *pxNext;

	/* A couple of parameters that this port does not use. */
	( void ) usStringLength;
	( void ) pxPort;
	( void ) ch;
	/* NOTE: This implementation does not handle the queue being full as no
	block time is used! */

	/* The port handle is not required as this driver only supports UART1. */
	( void ) pxPort;

	/* Send each character in the string, one at a time. */
	pxNext = ( signed char * ) pcString;
	while( *pxNext )
	{
		//xSerialPutChar( ch,pxPort, *pxNext, serNO_BLOCK );
		pxNext++;
	}
}
/*-----------------------------------------------------------*/


/*-----------------------------------------------------------*/
void Data_Send(uint8_t cChar)
{
	uint8_t k = 0;
	for ( k = 0; k < 1; k++)
	{
		if(0 != lCirqBuffPush(&ShellPortChannelData.RxCycBuffer, &cChar))
		{
			/*push data error*/
			ShellPortChannelData.TxDroped++;
		}
		else
		{
			; /*do nothing*/
		}
	}	
}

/****************************************************************************************************
 * @brief Receive data via UART
 * @param ch: UART ch(range:0-2)
 * @param rxbuff: Pointer of start address of data to be received
 * @param size: size of rxbuff
 * @return 0-successful, 1-unsuccessful
****************************************************************************************************/

// void LPUART_UART_IP_2_Callback(const uint8 HwInstance,const Lpuart_Uart_Ip_EventType Event,void *UserData)
// {
// 	(void) HwInstance;
// 	(void) UserData;
	

// 	switch(Event)
// 	{
// 		/**< @brief Rx buffer is full */
// 		case LPUART_UART_IP_EVENT_RX_FULL:
// 			/* The reception stops when newline is received or the buffer is full */
// 			/* Update the buffer index and the rx buffer */
// 			Data_Send(uarxBuffer);
// 			Lpuart_Uart_Ip_SetRxBuffer(LPUART_UART_IP_INSTANCE_USING_2,&uarxBuffer,1U);
// 			break;
// 		default :
// 			break;
// 	}
// }


