/*
 * hal_adapter.c
 *中间层函数调用库
 *  Created on: 2022年1月18日
 *      Author: QiXiang_CHENJIE
 */
#include "hal_adapter.h"
#include "AppGlobalVar.h"
#include "stdio.h"
#include "stdarg.h"

/********************************/
#include "Icu.h"
#include "Gpt.h"

uint8_t __attribute__((section(".non_cacheable_data"))) RX_Buffer[3][BUFFER_SIZE];
uint32_t bufferIdx[3] = {0};
volatile uint32 VarNotification_0 = 0;
volatile uint32 VarNotification_1 = 0;
TP_Value_Type ConvertedBuffer[NUM_RESULTS];
Adc_ValueGroupType ResultBuffer[NUM_RESULTS];
volatile Uart_StatusType Uart_TransmitStatus[3] = {UART_STATUS_TIMEOUT,UART_STATUS_TIMEOUT,UART_STATUS_TIMEOUT};
QueueHandle_t UartRecvQueue[3];
QueueHandle_t TcpRecvQueue;
QueueHandle_t UartSendQueue[3];
QueueHandle_t UartHalQueueHandle;
Std_ReturnType UartStartRecvFunc(uint8 channel);
Std_ReturnType ADC_Converter(Adc_ValueGroupType *Buffer, TP_Value_Type *ConvertedValueR);
void create_ringBuffer(ringbuffer_t *ringBuf, uint8_t *buf, uint32_t buf_len);
void clear_ringBuffer(ringbuffer_t *ringBuf);
uint32_t write_ringBuffer(uint8_t *buffer, uint16_t size, ringbuffer_t *ringBuf,uint32 *uartDataAddr);
uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf);
uint8 ringBufferforUart[3][BUFFER_SIZE];
ringbuffer_t uartRingBuffer[3];
sint8 AtcmdDelayRecvFunc(uint8 recvChannel,char *ResultStrPtr,uint16 delayTime)
{
	sint8 outValue = -1;
	uint8 delayCnt = 0;
	uint8 UartData[256];
	uint16 ReadLen = 0;
	char *retptr = NULL;
	while (delayCnt<(delayTime/1000)&&outValue!=0)
	{
		UART_Receive_Data(recvChannel,UartData, &ReadLen,1000);
		if(ReadLen>0)
		{
			retptr = (char *)strstr((char *)UartData, ResultStrPtr);
			if (retptr)
			{
				outValue = 0;
				break;
			}
		}
		else
		{
			delayCnt++;
		}
	}
	return outValue;
}
#if 0
	uint16 myPrintf(const char *fmt, ...)
	{
		int n;
		uint8 databuffer[512]={0};
		va_list args;
		va_start(args, fmt);
		n = vsprintf((char *)databuffer, fmt, args);
		va_end(args);
	    if( (printfRingBuffer.bw + n) <= printfRingBuffer.length  )
	    {
	        memcpy(printfRingBuffer.source + printfRingBuffer.bw, databuffer, n);
	        UART_Send_Data(UART_LPUART0, printfRingBuffer.source + printfRingBuffer.bw, n, 10);
	        printfRingBuffer.bw = printfRingBuffer.bw + n;
	    }
	    else
	    {
	    	printfRingBuffer.bw = 0;
	    	memcpy(printfRingBuffer.source + printfRingBuffer.bw, databuffer, n);
	    	UART_Send_Data(UART_LPUART0, printfRingBuffer.source + printfRingBuffer.bw, n, 10);
	    }
		return n;
	}
#endif
void create_ringBuffer(ringbuffer_t *ringBuf, uint8_t *buf, uint32_t buf_len)
{
    ringBuf->br         = 0;
    ringBuf->bw         = 0;
    ringBuf->btoRead    = 0;
    ringBuf->source     = buf;
    ringBuf->length     = buf_len;
}
void clear_ringBuffer(ringbuffer_t *ringBuf)
{
    ringBuf->br         = 0;
    ringBuf->bw         = 0;
    ringBuf->btoRead    = 0;
}
uint32_t write_ringBuffer(uint8_t *buffer, uint16_t size, ringbuffer_t *ringBuf,uint32 *uartDataAddr)
{
    volatile uint32_t ringBuf_bw     = ringBuf->bw;
    uint32_t ringBuf_len    = ringBuf->length;
    uint8_t *ringBuf_source = ringBuf->source;
    if( (ringBuf_bw + size + 1) > ringBuf_len  )
    {
    	ringBuf_bw = 0;
    }
    memcpy(ringBuf_source + ringBuf_bw, buffer, size);
    memset(ringBuf_source + ringBuf_bw + size + 1,0x00,1);//环形buffer 插入分隔符截断字符串
    ringBuf->bw = (ringBuf_bw + size + 1) % ringBuf_len;//数据长度不变,起始地址移位1
    ringBuf->btoRead += size;
    *uartDataAddr = (uint32)(ringBuf->source + ringBuf->bw - size - 1);
/*
    if(ringBuf->br!=0)
    {
        memcpy(ringBuf_source, buffer, size);
        ringBuf->br = 0;
    }
*/
/*
    if( (ringBuf_bw + size) <= ringBuf_len  )
    {
        memcpy(ringBuf_source + ringBuf_bw, buffer, size);
    }
    else
    {
        len = ringBuf_len - ringBuf_bw;
        memcpy(ringBuf_source + ringBuf_bw, buffer, len);
        memcpy(ringBuf_source, buffer + ringBuf_bw, size - len);
    }
    ringBuf->bw = (ringBuf->bw + size) % ringBuf_len;
    ringBuf->btoRead += size;
*/

    return size;
}
uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
{
    uint32_t len            = 0;
    volatile uint32_t ringBuf_br     = ringBuf->br;
    uint32_t ringBuf_len    = ringBuf->length;
    uint8_t *ringBuf_source = ringBuf->source;

    memcpy(buffer, ringBuf_source, size);
    ringBuf->br = size;
//    if( (ringBuf_br + size ) <= ringBuf_len )
//    {
//        memcpy(buffer, ringBuf_source + ringBuf_br, size);
//    }
//    else
//    {
//        len = ringBuf_len - ringBuf_br;
//        memcpy(buffer, ringBuf_source + ringBuf_br, len);
//        memcpy(buffer + len, ringBuf_source, size - len);
//    }
//    ringBuf->br = (ringBuf->br + size) % ringBuf_len;
//    ringBuf->btoRead -= size;

    return size;
}
Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
{
	UartMsg_t UartRecvMsg;
	UartMsg_t UartSendMsg;
	BaseType_t Sendret = pdFALSE;
	BaseType_t Recvret = pdFALSE;
	uint32 retVal = E_NOT_OK;
	UartSendMsg.DataLen = sendLength;
	UartSendMsg.dataPtr = txBuffer;
	*rxlen = 0;
	Sendret = xQueueSend(UartSendQueue[transChannel],&UartSendMsg,50);
	if(Sendret == pdTRUE)
	{
		Recvret = xQueueReceive(UartRecvQueue[recvChannel],&UartRecvMsg,T_timeout);
		if(Recvret == pdTRUE)
		{
			*rxlen = UartRecvMsg.DataLen;
			memcpy(rxBuffer,(uint8 *)(UartRecvMsg.dataAddr),UartRecvMsg.DataLen);
			retVal = E_OK;
		}
		else
		{
			retVal = 3;
		}
	}
	else
	{
		retVal = 2;
	}
	return retVal;
}
Std_ReturnType UART_Receive_Data(uint8 recvChannel, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
{
	UartMsg_t UartRecvMsg;
	BaseType_t ret = pdFALSE;
	uint32 retVal = E_NOT_OK;
	*rxlen = 0;
	ret = xQueueReceive(UartRecvQueue[recvChannel],&UartRecvMsg,T_timeout);
	if(ret == pdTRUE)
	{
		*rxlen = UartRecvMsg.DataLen;
		memcpy(rxBuffer,(uint8 *)UartRecvMsg.dataAddr,UartRecvMsg.DataLen);
		retVal = E_OK;
	}
	return retVal;
}
Std_ReturnType Tcp_Receive_Data(uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
{
	UartMsg_t UartRecvMsg;
	BaseType_t ret = pdFALSE;
	uint32 retVal = E_NOT_OK;
	*rxlen = 0;
	ret = xQueueReceive(TcpRecvQueue,&UartRecvMsg,T_timeout);
	if(ret == pdTRUE)
	{
		*rxlen = UartRecvMsg.DataLen;
		memcpy(rxBuffer,(uint8 *)UartRecvMsg.dataAddr,UartRecvMsg.DataLen);
		retVal = E_OK;
	}
	return retVal;
}
Std_ReturnType UART_Reset(uint8 recvChannel)
{
	uint32 retVal = E_NOT_OK;
	retVal = xQueueReset(UartRecvQueue[recvChannel]);
	return retVal;
}
Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32 sendLength, uint32 T_timeout)
{
	UartMsg_t UartSendMsg;
	BaseType_t ret = pdFALSE;
	uint32 retVal = E_NOT_OK;
	UartSendMsg.DataLen = sendLength;
	UartSendMsg.dataPtr = txBuffer;
	ret = xQueueSend(UartSendQueue[transChannel],&UartSendMsg,T_timeout);
	if(ret == pdTRUE)
	{
		retVal = E_OK;
	}
	return retVal;
}
 void UartInit(void)
 {
	 create_ringBuffer(&uartRingBuffer[0],ringBufferforUart[0],sizeof(ringBufferforUart[0]));
	 create_ringBuffer(&uartRingBuffer[1],ringBufferforUart[1],sizeof(ringBufferforUart[1]));
	 create_ringBuffer(&uartRingBuffer[2],ringBufferforUart[2],sizeof(ringBufferforUart[2]));
	 UartRecvQueue[0] = xQueueCreate(6, sizeof(UartMsg_t));
	 UartRecvQueue[1] = xQueueCreate(6, sizeof(UartMsg_t));
	 UartRecvQueue[2] = xQueueCreate(6, sizeof(UartMsg_t));
	 TcpRecvQueue = xQueueCreate(2, sizeof(UartMsg_t));
	 UartSendQueue[0] = xQueueCreate(3, sizeof(UartMsg_t));
	 UartSendQueue[1] = xQueueCreate(1, sizeof(UartMsg_t));
	 UartSendQueue[2] = xQueueCreate(1, sizeof(UartMsg_t));
	 UartHalQueueHandle = xQueueCreate(9, sizeof(UartHalMsg_t));

	 xTaskCreate(Uart_Hal_RecvTask, (const char *const)"UartRecv", 256, (void *)0, main_TASK_PRIORITY + 5, &Uart_Hal_RecvTask_Handle);
	 xTaskCreate(Uart_Hal_SendTask, (const char *const)"UartSend", 256, (void *)0, main_TASK_PRIORITY + 4, &Uart_Hal_SendTask_Handle);
 }
 Std_ReturnType UartStartRecvFunc(uint8 channel)
 {
	 sint8 out = 0;
	 volatile Std_ReturnType R_Uart_Status=E_NOT_OK;
	 bufferIdx[channel]=0;
	 memset(RX_Buffer[channel],0x00,BUFFER_SIZE);
	 switch(channel)
	 {
		case 0:
			IP_LPUART0->CTRL |= LPUART_CTRL_ILIE(1);
			break;
		case 1:
			IP_LPUART1->CTRL |= LPUART_CTRL_ILIE(1);
			break;
		case 2:
			IP_LPUART2->CTRL |= LPUART_CTRL_ILIE(1);
			break;
		default:
			break;
	 }
	 Uart_SetBuffer(channel, RX_Buffer[channel], DMA_SIZE, UART_RECEIVE);
	 R_Uart_Status = Uart_AsyncReceive(channel, RX_Buffer[channel], DMA_SIZE);
	  if (E_OK != R_Uart_Status)
	  {
		  Uart_Abort(channel, UART_RECEIVE);
		  out = E_NOT_OK;
	  }
	 return out;
 }
 void Uart_Hal_RecvTask(void *pvParameters)
 {
	 UartHalMsg_t UartHalMsgRecv;
	 UartMsg_t UartRecvMsg;
	 uint16 recvSize = 0;
	 BaseType_t ret = pdFALSE;
	 BaseType_t ret_send = pdFALSE;
	 uint32 T_bytesRemaining[3] = {0};
	 uint16 T_timeout[3] = {0};
	 volatile Uart_StatusType Uart_ReceiveStatus[3] = {UART_STATUS_TIMEOUT,UART_STATUS_TIMEOUT,UART_STATUS_TIMEOUT};
	 uint8 UartIdx = UART_LPUART0;
	 uint8 UartState[3] = {UartAbortRecv,UartAbortRecv,UartAbortRecv};
	 while(1)
	 {
		 if((T_timeout[UartIdx]>1000) && (Uart_ReceiveStatus[UartIdx] != UART_STATUS_NO_ERROR) )
		 {
			  Uart_Abort(UartIdx, UART_RECEIVE);
			  UartState[UartIdx] = UartAbortRecv;
			  T_timeout[UartIdx] = 0;
		 }
		 else if(Uart_ReceiveStatus[UartIdx] == UART_STATUS_NO_ERROR)
		 {
			 UartState[UartIdx] = UartRecvComplete;
		 }

		 if((UartState[UartIdx] == UartAbortRecv) || (UartState[UartIdx] == UartRecvComplete))
		 {
			 if(E_OK == UartStartRecvFunc(UartIdx))
			 {
				 UartState[UartIdx] = UartStartRecv;
			 }
		 }
		 Uart_ReceiveStatus[UartIdx] = Uart_GetStatus(UartIdx, &T_bytesRemaining[UartIdx], UART_RECEIVE);
		 T_timeout[UartIdx]++;
		 UartIdx = (UartIdx + 1) > 2 ? 1 : (UartIdx + 1);
		 ret = xQueueReceive(UartHalQueueHandle,&UartHalMsgRecv,1);
		  if(ret==pdTRUE)
		  {
			  if(UartHalMsgRecv.event==LPUART_UART_IP_EVENT_RECV_IDLE)
			  {
					if(UartHalMsgRecv.value>0)
					{
						recvSize = write_ringBuffer(RX_Buffer[UartHalMsgRecv.Channel],UartHalMsgRecv.value,&uartRingBuffer[UartHalMsgRecv.Channel],&(UartRecvMsg.dataAddr));
						UartRecvMsg.DataLen = UartHalMsgRecv.value;
						if(UartHalMsgRecv.Channel==1 && strstr((char *)UartRecvMsg.dataAddr, (char *)("RECV FROM")))//网络接收数据放入其他队列
						{
							ret_send = xQueueSend(TcpRecvQueue,&UartRecvMsg,10);
						}
						else
						{
							ret_send = xQueueSend(UartRecvQueue[UartHalMsgRecv.Channel],&UartRecvMsg,10);
						}
						T_timeout[UartHalMsgRecv.Channel] = 0;
						UartState[UartHalMsgRecv.Channel] = UartRecvComplete;
					}
			  }
		  }
	 }
 }
 void Uart_Hal_SendTask(void *pvParameters)
 {
	 UartMsg_t UartSendMsg;
	 BaseType_t ret = pdFALSE;
	 uint32 T_bytesRemaining[3] = {0};
	 uint16 T_timeout[3] = {0};
	 volatile Std_ReturnType T_Uart_Status[3];
	 uint8 UartIdx = UART_LPUART0;
	 uint8 UartSendState[3] = {UartNoDataSend,UartNoDataSend,UartNoDataSend};
	 while(1)
	 {
		 ret = xQueueReceive(UartSendQueue[UartIdx],&UartSendMsg,1);
		 if(ret==pdTRUE)
		 {
			 T_Uart_Status[UartIdx] = Uart_AsyncSend(UartIdx, UartSendMsg.dataPtr, UartSendMsg.DataLen);
		     if (E_OK != T_Uart_Status[UartIdx])
		     {
		         Uart_Abort(UartIdx, UART_SEND);
		         UartSendState[UartIdx] = UartAbortSend;
		     }
		     else
		     {
		    	 UartSendState[UartIdx] = UartStartSend;
		     }
		 }
		 /*开始发送后的判定*/
		 if(UartSendState[UartIdx] == UartStartSend)
		 {
			 Uart_TransmitStatus[UartIdx] = Uart_GetStatus(UartIdx, &T_bytesRemaining[UartIdx], UART_SEND);
			 T_timeout[UartIdx]++;
		 }
		 if(T_timeout[UartIdx]>=1000 || ((Uart_TransmitStatus[UartIdx] != UART_STATUS_OPERATION_ONGOING) && (UartSendState[UartIdx] == UartStartSend)))
		 {
			 if(T_timeout[UartIdx]>=1000)
			 {
				 Uart_Abort(UartIdx, UART_SEND);
				 UartSendState[UartIdx] = UartAbortSend;
			 }
			 else if(Uart_TransmitStatus[UartIdx] == UART_STATUS_NO_ERROR)
			 {
				 UartSendState[UartIdx] = UartSendComplete;
			 }
			 T_timeout[UartIdx] = 0;
		 }

		 UartIdx = (UartIdx + 1) > 2 ? 0 : (UartIdx + 1);
	 }

 }
//
//Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, const uint8 *txBuffer, uint32 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
//{
//    volatile Std_ReturnType R_Uart_Status;
//    volatile Std_ReturnType T_Uart_Status;
//    volatile Uart_StatusType Uart_ReceiveStatus = UART_STATUS_TIMEOUT;
//    volatile Uart_StatusType Uart_TransmitStatus = UART_STATUS_TIMEOUT;
//    uint32 T_bytesRemaining;
//    uint32 R_bytesRemaining;
//    uint32 timeout = T_timeout;
//    uint32 retVal = E_NOT_OK;
//    bufferIdx[recvChannel] = 0;
//    switch (recvChannel)
//    {
//    case 0:
//        IP_LPUART0->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    case 1:
//        IP_LPUART1->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    case 2:
//        IP_LPUART2->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    default:
//        break;
//    }
//    if (txBuffer == NULL || rxBuffer == NULL)
//    {
//        return retVal;
//    }
//
//    /* Uart_AsyncSend transmit data */
//    Uart_SetBuffer(transChannel, txBuffer, sendLength, UART_SEND);
//    T_Uart_Status = Uart_AsyncSend(transChannel, txBuffer, sendLength);
//    if (E_OK != T_Uart_Status)
//    {
//        Uart_Abort(transChannel, UART_SEND);
//        return E_NOT_OK;
//    }
//    Uart_SetBuffer(recvChannel, &RX_Buffer[recvChannel][0], DMA_SIZE, UART_RECEIVE);
//    R_Uart_Status = Uart_AsyncReceive(recvChannel, rxBuffer, DMA_SIZE);
//    if (E_OK != R_Uart_Status)
//    {
//        Uart_Abort(recvChannel, UART_RECEIVE);
//        return E_NOT_OK;
//    }
//    /* Check for no on-going transmission */
//    do
//    {
//        if (Uart_TransmitStatus != UART_STATUS_NO_ERROR)
//        {
//            Uart_TransmitStatus = Uart_GetStatus(transChannel, &T_bytesRemaining, UART_SEND);
//        }
//        if (Uart_ReceiveStatus != UART_STATUS_NO_ERROR)
//        {
//            Uart_ReceiveStatus = Uart_GetStatus(recvChannel, &R_bytesRemaining, UART_RECEIVE);
//        }
//        vTaskDelay(pdMS_TO_TICKS(1));
//    } while (((UART_STATUS_NO_ERROR != Uart_TransmitStatus || UART_STATUS_NO_ERROR != Uart_ReceiveStatus) && 0 < --timeout));
//    if ((UART_STATUS_NO_ERROR != Uart_TransmitStatus))
//    {
//        Uart_Abort(transChannel, UART_SEND);
//        retVal = E_NOT_OK;
//    }
//    else
//    {
//        retVal = E_OK;
//    }
//    if ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus))
//    {
//        Uart_Abort(recvChannel, UART_RECEIVE);
//        *rxlen = bufferIdx[recvChannel];
//        retVal = E_NOT_OK;
//    }
//    else
//    {
//        *rxlen = bufferIdx[recvChannel];
//        retVal = E_OK;
//    }
//    return retVal;
//}
//
//Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32 sendLength, uint32 T_timeout)
//{
//
//    volatile Std_ReturnType T_Uart_Status;
//    volatile Uart_StatusType Uart_TransmitStatus = UART_STATUS_TIMEOUT;
//    uint32 T_bytesRemaining;
//    uint32 timeout = T_timeout;
//    uint32 retVal = E_NOT_OK;
//    if (txBuffer == NULL)
//    {
//        return retVal;
//    }
//
//    /* Uart_AsyncSend transmit data */
//    T_Uart_Status = Uart_AsyncSend(transChannel, txBuffer, sendLength);
//    if (E_OK != T_Uart_Status)
//    {
//        Uart_Abort(transChannel, UART_SEND);
//        return E_NOT_OK;
//    }
//    /* Check for no on-going transmission */
//    do
//    {
//        Uart_TransmitStatus = Uart_GetStatus(transChannel, &T_bytesRemaining, UART_SEND);
//        vTaskDelay(pdMS_TO_TICKS(1));
//    } while ((UART_STATUS_NO_ERROR != Uart_TransmitStatus && 0 < --timeout));
//
//    if ((UART_STATUS_NO_ERROR != Uart_TransmitStatus))
//    {
//        retVal = E_NOT_OK;
//    }
//    else
//    {
//        retVal = E_OK;
//    }
//    return retVal;
//}
//
//Std_ReturnType UART_Receive_Data(uint8 recvChannel, uint8 *rxBuffer, uint16 *rxlen, sint32 T_timeout)
//{
//    volatile Std_ReturnType R_Uart_Status = E_NOT_OK;
//    volatile Uart_StatusType Uart_ReceiveStatus = UART_STATUS_TIMEOUT;
//    uint32 T_bytesRemaining = 0;
//    uint32 retVal = E_NOT_OK;
//    //    uint8 Rx_Buffer[MSG_LEN];
//    bufferIdx[recvChannel] = 0;
//    *rxlen = 0;
//    if (rxBuffer == NULL)
//    {
//        return retVal;
//    }
//    /* Uart_AsyncReceive transmit data */
//    switch (recvChannel)
//    {
//    case 0:
//        IP_LPUART0->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    case 1:
//        IP_LPUART1->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    case 2:
//        IP_LPUART2->CTRL |= LPUART_CTRL_ILIE(1);
//        break;
//    default:
//        break;
//    }
//    Uart_SetBuffer(recvChannel, rxBuffer, DMA_SIZE, UART_RECEIVE);
//    R_Uart_Status = Uart_AsyncReceive(recvChannel, rxBuffer, DMA_SIZE);
//    if (E_OK != R_Uart_Status)
//    {
//        Uart_Abort(recvChannel, UART_RECEIVE);
//        return E_NOT_OK;
//    }
//    /* Check for no on-going transmission */
//    do
//    {
//        Uart_ReceiveStatus = Uart_GetStatus(recvChannel, &T_bytesRemaining, UART_RECEIVE);
//        vTaskDelay(pdMS_TO_TICKS(1));
//
//    } while ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus) && 0 < T_timeout--);
//    if ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus))
//    {
//        Uart_Abort(recvChannel, UART_RECEIVE);
//        *rxlen = bufferIdx[recvChannel];
//        retVal = E_NOT_OK;
//    }
//    else
//    {
//        *rxlen = bufferIdx[recvChannel];
//        retVal = E_OK;
//    }
//    return retVal;
//}
extern Lpuart_Uart_Ip_StateStructureType *Lpuart_Uart_Ip_apStateStructuresArray[LPUART_UART_IP_NUMBER_OF_INSTANCES];
void UART_Callback(uint32 hwInstance, Lpuart_Uart_Ip_EventType event)
{
    //    (void)userData;
		Lpuart_Uart_Ip_StateStructureType * UartState;
		UartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[hwInstance];
    /* Check the event type */
    if (event == LPUART_UART_IP_EVENT_RX_FULL)
    {
        /* The reception stops when receiving idle is detected or the buffer is full */
        if (bufferIdx[hwInstance] <= (BUFFER_SIZE - DMA_SIZE))
        {
            /* Update the buffer index and the rx buffer */
            bufferIdx[hwInstance] += DMA_SIZE;
            Uart_SetBuffer(hwInstance, &RX_Buffer[hwInstance][bufferIdx[hwInstance]], DMA_SIZE, UART_RECEIVE);
            // Lpuart_Uart_Ip_SetRxBuffer(hwInstance, &RX_Buffer[bufferIdx], DMA_SIZE);
        }
    }
    if (event == LPUART_UART_IP_EVENT_ERROR)
    {
        //     	/*Get the transfered data size. DMA Channel 1 is used for LPUART DMA receiving, please modify accordingly.*/
        //     	temp = DMA_SIZE - (uint32_t)IP_DMA->TCD->CITER.ELINKNO;
        //     	/*Add the remaining data size to the sum of the received size*/
        //     	bufferIdx[hwInstance] += temp;
        /*Abort the receiving after detecting IDLE receiving*/
        Lpuart_Uart_Ip_AbortReceivingData(hwInstance);
        Lpuart_Uart_Ip_AbortSendingData(hwInstance);
        //    	bufferIdx = 0;
    }
    if (event == LPUART_UART_IP_EVENT_RECV_IDLE)
    {
         uint32_t temp;
         UartHalMsg_t UartHalMsg;
         UartHalMsg.Channel = hwInstance;
         UartHalMsg.event = event;
        /*Get the transfered data size. DMA Channel 1 is used for LPUART DMA receiving, please modify accordingly.*/
        temp = DMA_SIZE - (uint32_t)IP_DMA->TCD[hwInstance].CITER.ELINKNO;
        /*Add the remaining data size to the sum of the received size*/
        bufferIdx[hwInstance] += temp;
        /*Abort the receiving after detecting IDLE receiving*/
 		UartHalMsg.value = bufferIdx[hwInstance];
 		xQueueSendFromISR(UartHalQueueHandle,&UartHalMsg,pdFALSE);
    }
}

/*CAN*/
Can_PduType Can_CreatePduInfo(Can_IdType id, CAN_IdFrameType idFrame, PduIdType swPduHandle, uint8 length, uint8 *sdu)
{
    Can_PduType PduInfo;
    switch (idFrame)
    {
    case CAN_STANDARD_ID_TYPE:
        id = id & 0x7FF;
        break;
    case CANFD_STANDARD_ID_TYPE:
        id = (id & 0x7FF) | 0x40000000;
        break;
    case CAN_EXTENDED_ID_TYPE:
        id = id | 0x80000000;
        break;
    case CANFD_EXTENDED_ID_TYPE:
        id = id | 0xC0000000;
        break;
    default:
        id = id & 0x7FF;
        break;
    }
    PduInfo.id = id;
    PduInfo.swPduHandle = swPduHandle;
    PduInfo.length = length;
    PduInfo.sdu = sdu;
    return PduInfo;
}
Std_ReturnType CanIf_SendMessage(uint8 ControllerId, Can_Msg_Type CanMsg)
{
    volatile Can_PduType Can_PduInfo;
    volatile Std_ReturnType CAN_Write_Status;
    Std_ReturnType retVal = E_NOT_OK;
    uint32 u8TimeOut = 100 * 100;
    Can_HwHandleType Hth = Can0HardwareObject_TX + (Can_HwHandleType)ControllerId; // controller 0 --> Can0HardwareObject_TX

    Can_PduInfo = Can_CreatePduInfo(CanMsg.id, CanMsg.idFrame, 0, CanMsg.length, CanMsg.sdu);

    CAN_Write_Status = Can_Write(Hth, &Can_PduInfo);

    CanIf_bTxFlag = FALSE;
    if (CAN_Write_Status == E_OK)
    {
        while ((!CanIf_bTxFlag) && (u8TimeOut != 0U))
        {
            Can_MainFunction_Write();
            u8TimeOut--;
        }
    }

    if (CanIf_bTxFlag == TRUE)
    {
        retVal = E_OK;
    }
    else
    {
        retVal = E_NOT_OK;
    }
    return retVal;
}
Can_Msg_Type Can_GetMsgInfo(Can_IdType id, uint8 length, uint8 *sdu)
{
    Can_Msg_Type CanMsgInfo;

    CanMsgInfo.idFrame = (CAN_IdFrameType)((id >> 30) & 0x03);
    if (CanMsgInfo.idFrame & 0x01)
    {
        CanMsgInfo.id = id & 0x7FF;
    }
    else
    {
        CanMsgInfo.id = id & 0x1FFFFFFF;
    }
    CanMsgInfo.length = length;
    CanMsgInfo.sdu = sdu;

    return CanMsgInfo;
}

void CanIf_ControllerBusOff(uint8 ControllerId)
{
    (void)ControllerId;
}

void CanIf_ControllerModeIndication(uint8 ControllerId, Can_ControllerStateType ControllerMode)
{
    (void)ControllerId;
    (void)ControllerMode;
}
void CanIf_TxConfirmation(PduIdType CanTxPduId)
{
    CanIf_u8TxConfirmCnt++;
    CanIf_bTxFlag = TRUE;
    (void)CanTxPduId;
}
void CanIf_RxIndication(const Can_HwType *Mailbox, const PduInfoType *PduInfoPtr)
{
    Can_Msg_Type canRxMsg_Buff;
    Can_Msg_Type_Data canRxMsgQueueData;
    CanIf_bRxFlag = TRUE; // should not be delete
    // should put the msg into message queue
    canRxMsg_Buff = Can_GetMsgInfo(Mailbox->CanId, PduInfoPtr->SduLength, PduInfoPtr->SduDataPtr);
    canRxMsgQueueData.id = canRxMsg_Buff.id;
    canRxMsgQueueData.length = canRxMsg_Buff.length;
    memcpy(canRxMsgQueueData.data, canRxMsg_Buff.sdu, canRxMsgQueueData.length);
    switch(Mailbox->Hoh)
    {
	    case 0:
	    	xQueueSend(CanRecvQueueHandle0, &canRxMsgQueueData, 0);
	    	break;
	    case 1:
	    	xQueueSend(CanRecvQueueHandle1, &canRxMsgQueueData, 0);
	    	break;
	    case 2:
	    	xQueueSend(CanRecvQueueHandle2, &canRxMsgQueueData, 0);
	    	break;
    }
}

void CanIf_CurrentIcomConfiguration(uint8 ControllerId, IcomConfigIdType ConfigurationId, IcomSwitch_ErrorType Error)
{
    (void)ControllerId;
    (void)ConfigurationId;
    (void)Error;
}

void Notification_0(void)
{
    ADC_Converter(ResultBuffer, ConvertedBuffer);
    memcpy(BattTempR, &ConvertedBuffer[3], 4 * sizeof(uint32));
}

void Notification_1(void)
{
    VarNotification_1++;
}

Std_ReturnType ADC_Converter(Adc_ValueGroupType *Buffer, TP_Value_Type *ConvertedValueR)
{
    Adc_ValueGroupType REFH, REFL;
    REFH = Buffer[0];
    REFL = Buffer[2];
    for (int i = 3; i < NUM_RESULTS; i++)
    {
        if (Buffer[i] >= REFH)
        {
            ConvertedValueR[i] = 40930000;
        }
        else if (Buffer[i] <= REFL)
        {
            ConvertedValueR[i] = 0x00;
        }
        else
        {
            ConvertedValueR[i] = (TP_Value_Type)((float)(10000 * (Buffer[i] - REFL) / (float)(REFH - REFL)) / (1 - (float)((Buffer[i] - REFL) / (float)(REFH - REFL))));
        }
    }
    return 0;
}

Std_ReturnType ADC_ReadValue()
{
    Std_ReturnType ret = E_NOT_OK;
    for (uint8 i = 0; i < NUM_RESULTS; i++)
    {
        ResultBuffer[i] = 0xFFFF;
        ConvertedBuffer[i] = 0x00;
    }
    Adc_SetupResultBuffer(AdcGroupSoftwareOneShot, ResultBuffer);
    Adc_EnableGroupNotification(AdcGroupSoftwareOneShot);
    VarNotification_0 = 0;
    Adc_StartGroupConversion(AdcGroupSoftwareOneShot);
    return ret;
}

/*EEP*/
static Std_ReturnType TestEep_FlexNvmProgramPartCmd(
    VAR(TestEep_CsecKeySize, AUTOMATIC) eepKeysize,
    VAR(TestEep_SfeType, AUTOMATIC) eepSecurityFlagExtension,
    VAR(TestEep_LoadFlexRamType, AUTOMATIC) eepLoadFlexRamAtReset,
    VAR(TestEep_Eeprom_FlexRamPartitionType, AUTOMATIC) eepFlexRamPartition,
    VAR(TestEep_Eeprom_FlexNvmPartitionType, AUTOMATIC) eepFlexNvmPartition)
{
    Std_ReturnType u8RetVal = (Std_ReturnType)E_OK;
    uint32 u32FlexNvmPartSize = 0;

    uint32 u32RegSimFcfg1 = 0UL;

    u32RegSimFcfg1 = IP_SIM->FCFG1;

    /*get DEPART value */
    u32FlexNvmPartSize = (uint32)((u32RegSimFcfg1 & SIM_FCFG1_DEPART_MASK) >> SIM_FCFG1_DEPART_SHIFT);

    /* check that it was not partitioned before */
    if (u32FlexNvmPartSize == 0xF)
    {
        //         /* if error flags are set the cmd is not executed */
        //         REG_WRITE8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_ACCERR_U8 | TEST_EEP_EEPROM_FSTAT_FPVIOL_U8);
        //
        //         /*erase DF 0 sector*/
        //         u32Addr=(TEST_EEP_DEEPROM_SECTOR_0_ADDR32 - D_EEPROM_BASE_ADDR) + 0x800000UL;
        //
        //         REG_WRITE8(TEST_EEP_EEPROM_FCCOB0_ADDR32, TEST_EEP_EEPROM_CMD_ERASE_SECTOR);
        //         REG_WRITE8(TEST_EEP_EEPROM_FCCOB1_ADDR32, (uint8)(u32Addr >> 16UL));
        //         REG_WRITE8(TEST_EEP_EEPROM_FCCOB2_ADDR32, (uint8)(u32Addr >> 8UL));
        //         REG_WRITE8(TEST_EEP_EEPROM_FCCOB3_ADDR32, (uint8)(u32Addr >> 0UL));
        //         REG_WRITE8(TEST_EEP_EEPROM_FSTAT_ADDR32 , TEST_EEP_EEPROM_FSTAT_CCIF_U8);
        //         while((0U == REG_BIT_GET8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_CCIF_U8)))
        //         {
        //         }
        //
        if (0U == REG_BIT_GET8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_ACCERR_U8 | TEST_EEP_EEPROM_FSTAT_FPVIOL_U8))
        {
            /* run program partition command */
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB0_ADDR32, EEPROM_CMD_PROGRAM_PARTITION);
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB1_ADDR32, (uint8)eepKeysize);
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB2_ADDR32, (uint8)eepSecurityFlagExtension);
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB3_ADDR32, (uint8)eepLoadFlexRamAtReset);
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB4_ADDR32, (uint8)eepFlexRamPartition);
            REG_WRITE8(TEST_EEP_EEPROM_FCCOB5_ADDR32, (uint8)eepFlexNvmPartition);
            REG_WRITE8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_CCIF_U8);
            while ((0U == REG_BIT_GET8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_CCIF_U8)))
            {
                /* wait for operation to finish */
            }
            /* check if errors occured  */
            if (REG_BIT_GET8(TEST_EEP_EEPROM_FSTAT_ADDR32, TEST_EEP_EEPROM_FSTAT_ACCERR_U8 | TEST_EEP_EEPROM_FSTAT_FPVIOL_U8))
            {
                /* NOK, error flags are set */
                u8RetVal = (Std_ReturnType)E_NOT_OK;
            }
        }
        else
        {
            /* NOK, error flags are set */
            u8RetVal = (Std_ReturnType)E_NOT_OK;
        }
    }
    else
    {
        /* NOK, partitioned already */
        u8RetVal = (Std_ReturnType)E_NOT_OK;
    }
    return u8RetVal;
}

void Eep_DepartParitition(TestEep_Eeprom_FlexNvmPartitionType T_EEP_SIZE)
{
    uint32 u32FlexNvmPartSize = 0;

    uint32 u32RegSimFcfg1 = 0UL;

    u32RegSimFcfg1 = IP_SIM->FCFG1;

    /*get DEPART value */
    u32FlexNvmPartSize = (uint32)((u32RegSimFcfg1 & SIM_FCFG1_DEPART_MASK) >> SIM_FCFG1_DEPART_SHIFT);
    if (u32FlexNvmPartSize == 0xF) /* We just partition again if curent size different with expected */
    {
        /* partition for EERAM 64K with NOT loading EERAM at reset in hardware */
        TestEep_FlexNvmProgramPartCmd(EEP_FTFC_KEY_SIZE_0_BYTES, EEP_FTFC_VERIFY_ONLY_DISABLED,
                                      EEP_FTFC_LOAD_AT_RESET_ENABLED, EEP_FTFC_EERAM_SIZE_4K, T_EEP_SIZE);
    }
}
/* Erase memory by writing erase value */
Std_ReturnType HAL_EEP_Erase(uint32 eepEraseStartAddr, uint32 eepEraseSize)
{
    Std_ReturnType retReturnType = E_OK;
    MemIf_JobResultType retJobResultType;
    retReturnType = Eep_Erase(eepEraseStartAddr, eepEraseSize);
    if (E_OK != retReturnType)
    {
        return E_NOT_OK;
    }
    while (MEMIF_IDLE != Eep_GetStatus())
    {
        Eep_MainFunction();
    }
    retJobResultType = Eep_GetJobResult();
    if (MEMIF_JOB_OK != retJobResultType)
    {
        return E_NOT_OK;
    }
    return E_OK;
}

/* Write one or more complete eeprom pages to the eeprom device */
Std_ReturnType HAL_EEP_Write(uint32 eepWriteStartAddr, uint8 *pDataNeedtoWrite, uint32 dataSize)
{
    Std_ReturnType retReturnType = E_OK;
    MemIf_JobResultType retJobResultType;

    /*Erase the EEP before write*/
    retReturnType = HAL_EEP_Erase(eepWriteStartAddr, dataSize);
    if (E_OK != retReturnType)
    {
        return E_NOT_OK;
    }

    retReturnType = Eep_Write(eepWriteStartAddr, pDataNeedtoWrite, dataSize);
    if (E_OK != retReturnType)
    {
        return E_NOT_OK;
    }
    while (MEMIF_IDLE != Eep_GetStatus())
    {
        Eep_MainFunction();
    }
    retJobResultType = Eep_GetJobResult();
    if (MEMIF_JOB_OK != retJobResultType)
    {
        return E_NOT_OK;
    }
    return E_OK;
}

/* Reads from eeprom memory */
Std_ReturnType HAL_EEP_Read(uint32 eepReadStartAddr, uint8 *pDataBuffer, uint32 dataSize)
{
    Std_ReturnType retReturnType = E_OK;
    MemIf_JobResultType retJobResultType;
    retReturnType = Eep_Read(eepReadStartAddr, pDataBuffer, dataSize);
    if (E_OK != retReturnType)
    {
        return E_NOT_OK;
    }
    while (MEMIF_IDLE != Eep_GetStatus())
    {
        Eep_MainFunction();
    }
    retJobResultType = Eep_GetJobResult();
    if (MEMIF_JOB_OK != retJobResultType)
    {
        return E_NOT_OK;
    }
    return E_OK;
}

/* Compares a eeprom memory area with an application data buffer */
Std_ReturnType HAL_EEP_Compare(uint32 eepCompareStartAddr, uint8 *pDataNeedtoCompare, uint32 dataSize)
{
    Std_ReturnType retReturnType = E_OK;
    MemIf_JobResultType retJobResultType;
    retReturnType = Eep_Compare(eepCompareStartAddr, pDataNeedtoCompare, dataSize);
    if (E_OK != retReturnType)
    {
        return E_NOT_OK;
    }
    while (MEMIF_IDLE != Eep_GetStatus())
    {
        Eep_MainFunction();
    }
    retJobResultType = Eep_GetJobResult();
    if (MEMIF_JOB_OK != retJobResultType)
    {
        return E_NOT_OK;
    }
    return E_OK;
}
/* @brief VECTKEY value so that AIRCR register write is not ignored. */
#define FEATURE_SCB_VECTKEY               (0x05FAU)
void SystemSoftwareReset(void)
{
    uint32_t regValue;

    /* Read Application Interrupt and Reset Control Register */
    regValue = S32_SCB->AIRCR;

    /* Clear register key */
    regValue &= ~( S32_SCB_AIRCR_VECTKEY_MASK);

    /* Configure System reset request bit and Register Key */
    regValue |= S32_SCB_AIRCR_VECTKEY(FEATURE_SCB_VECTKEY);
    regValue |= S32_SCB_AIRCR_SYSRESETREQ(0x1u);

    /* Write computed register value */
    S32_SCB->AIRCR = regValue;
}

void MCUSleep(void)
{

#if (ICU_PRECOMPILE_SUPPORT == STD_ON)
					Icu_Init(NULL_PTR);
#elif (ICU_PRECOMPILE_SUPPORT == STD_OFF)
	Icu_Init(&Icu_Config_VS_0);
#endif

	Mcu_SetMode(McuModeSettingConf_VLPS);


//	typedef void (*AppAddr)(void);
//	AppAddr resetHandle = (AppAddr)(0x14601);
//	OsIf_SuspendAllInterrupts();
//	(resetHandle)();
	SystemSoftwareReset();
//	coreInit();
}


void SystemDeinit(void)
{

	Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF);
	vTaskDelay(pdMS_TO_TICKS(3000));
	Dio_WriteChannel(DioConf_DioChannel_PTA6_GPIO_OUT_MCU_4G_POW_EN, STD_OFF);

	Dio_WriteChannel(DioConf_DioChannel_PTD1_GPIO_OUT_MCU_GPS_POW_EN, STD_OFF);//GPS ShutDown

	Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_ON);
	Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_ON);
	Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_ON);
	Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_ON);
	Dio_WriteChannel(DioConf_DioChannel_PTE9_GPIO_OUT_MCU_LED5, STD_ON);

	Uart_Deinit();

	Can_SetControllerMode(CanController_0, CAN_CS_STOPPED);
	Can_SetControllerMode(CanController_1, CAN_CS_STOPPED);
//	Can_SetControllerMode(CanController_2, CAN_CS_STOPPED);

	Can_DeInit();

	Adc_DeInit();

	Gpt_DisableNotification(GptConf_GptChannelConfiguration_GptChannelConfiguration_0);

	Gpt_DeInit();

	Spi_DeInit();

	Mcl_DeInit();

	//port DeInit
	for(int pinIndex = 0; pinIndex <PortConfigSet_PortContainer_GPIO_PTB4_GPIO_OUT_MCU_RS485_EN; pinIndex++)
	{
		if(pinIndex == PortConfigSet_PortContainer_CAN_PTA12_CAN1_RX_MCU_CAN1_RX /*|| pinIndex == PortConfigSet_PortContainer_INT_PTB0_LPTMR0_ATL3_MCU_CC1_INT || pinIndex == PortConfigSet_PortContainer_INT_PTE11_LPTMR0_ALT1_MCU_3D_INT1 || pinIndex == PortConfigSet_PortContainer_INT_PTD5_LPTMR0_ATL2_MCU_3D_INT2*/)
		{
			continue;
		}
		else
		{
			Port_SetAsUnusedPin(pinIndex);
		}
	}

	Port_SetPinMode(PortConfigSet_PortContainer_CAN_PTA12_CAN1_RX_MCU_CAN1_RX,PORT_GPIO_MODE);

//	systemInitFlag = false;
}

void MCUEnterSleep(void)
{
	if(pdTRUE == xSemaphoreTake(sleep_mutex,1) && Fota_Process_Going == false)
	{
		extern boolean Uart_4G_Task_Sleep_FLag;
		WdgDeInit();
		Std_ReturnType Ret = E_NOT_OK;
		uint8 appConfigWriteTimes = 0;
		do
		{
			waitForSleepFlag = true;

			//save the app configure before power off
			if(Ret == E_NOT_OK)
			{
				AppConfigInfo.appSaveFlg = false;
				Ret = HAL_EEP_Write(0,(uint8 *)&AppConfigInfo,sizeof(AppConfigInfo));
				appConfigWriteTimes++;
			}

			vTaskDelay(pdMS_TO_TICKS(10));
		}while(Uart_4G_Task_Sleep_FLag == false || (Ret == E_NOT_OK && appConfigWriteTimes<5) );

		vTaskDelete(Uart_Hal_RecvTask_Handle);
		vTaskDelete(Uart_Hal_SendTask_Handle);
		vTaskDelete(CanTask_Handle);
		vTaskDelete(GpsTask_Handle);
		vTaskDelete(Uart_4G_Task_Handle);

		SystemDeinit();
		MCUSleep();
//		WdgInit();
//		DoResetECUWithWdg();
	}
}

void coreInit(void)
{
	/* Initialize the Mcu driver */
#if (MCU_PRECOMPILE_SUPPORT == STD_ON)
	Mcu_Init(NULL_PTR);
#elif (MCU_PRECOMPILE_SUPPORT == STD_OFF)
	Mcu_Init(&Mcu_Config_VS_0);
#endif /* (MCU_PRECOMPILE_SUPPORT == STD_ON) */

	Mcu_InitClock(McuClockSettingConfig_0);

	/* Wait until PLL is locked */
	while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
	{
		/* Busy wait until the System PLL is locked */
	}
	Mcu_DistributePllClock();

	OsIf_Init(NULL_PTR);

	Platform_Init(NULL_PTR);

	/* Initialize all pins*/
#if (PORT_PRECOMPILE_SUPPORT == STD_ON)
	Port_Init(NULL_PTR);
#elif (PORT_PRECOMPILE_SUPPORT == STD_OFF)
	Port_Init(&Port_Config_VS_0);
#endif

}

void SystemModulesInit(void)
{
//	Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
	/* Initialize Mcl module */
	Mcl_Init(NULL_PTR);

	SEGGER_RTT_Init();


	/* Initializes an UART driver*/
#if (UART_PRECOMPILE_SUPPORT == STD_ON)
	Uart_Init(NULL_PTR);
#elif (UART_PRECOMPILE_SUPPORT == STD_OFF)
	Uart_Init(&Uart_xConfig_VS_0);
#endif
	IP_LPUART0->CTRL |= LPUART_CTRL_ILT(1);
	IP_LPUART1->CTRL |= LPUART_CTRL_ILT(1);
	IP_LPUART2->CTRL |= LPUART_CTRL_ILT(1);
	IP_LPUART0->CTRL |= LPUART_CTRL_IDLECFG(3);
	IP_LPUART1->CTRL |= LPUART_CTRL_IDLECFG(3);
	IP_LPUART2->CTRL |= LPUART_CTRL_IDLECFG(3);

#if 1 /* Initialize Platform driver */
#if (CAN_PRECOMPILE_SUPPORT == STD_ON)
	Can_Init(NULL_PTR);
#elif (CAN_PRECOMPILE_SUPPORT == STD_OFF)
	Can_Init(&Can_Config_VS_0);
#endif
	Can_SetControllerMode(CanController_0, CAN_CS_STARTED);
	Can_SetControllerMode(CanController_1, CAN_CS_STARTED);
//	Can_SetControllerMode(CanController_2, CAN_CS_STARTED);
#endif

#if (ADC_PRECOMPILE_SUPPORT == STD_ON)
	Adc_Init(NULL_PTR);
#else
	Adc_Init(&Adc_Config_VS_0);
#endif /* ADC_PRECOMPILE_SUPPORT == STD_ON */

	/* Partition only if it was not partitioned before for EERAM with code 0x4 */
//    Eep_DepartParitition(T_EEEPROM_SIZE);
	/* Initialize Eep driver */
#if defined (EEP_PRECOMPILE_SUPPORT)
	Eep_Init(NULL_PTR);
#else
	Eep_Init(&Eep_Config_VS_0);
#endif
	//Init Flash Driver
#if defined (FLS_PRECOMPILE_SUPPORT)
	Fls_Init(NULL_PTR);
#else
	Fls_Init(&Fls_Config_VS_0);
	while(MEMIF_IDLE == Fls_GetStatus())
	{
		;
	}
#endif


	Spi_Init(NULL_PTR);
			/* Initialize the Gpt driver */
	Gpt_Init(&Gpt_Config_VS_0);

	/* Enable the Gpt notification to periodically service the Wdg */
	Gpt_EnableNotification(GptConf_GptChannelConfiguration_GptChannelConfiguration_0);

	Icu_DeInit();

	WdgInit();

	IsFeedWdg = true;
}

void displayResetReasonWithLED(void)
{
	Mcu_ResetType bootreason;
	bootreason = Mcu_GetResetReason();
	if(bootreason == MCU_STOP_ACKNOWLEDGE_ERROR_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_MDM_AP_SYSTEM_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);

	}
	else if(bootreason == MCU_SW_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_CORE_LOCKUP_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_JTAG_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_POWER_ON_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_EXTERNAL_PIN_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_WATCHDOG_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}

	else if(bootreason == MCU_CMU_LOSS_OF_CLOCK_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_LOSS_OF_LOCK_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_LOSS_OF_CLOCK_RESET)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_LOW_OR_HIGH_VOLTAGE_DETECT_RESET)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_NO_RESET_REASON)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
//		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_MULTIPLE_RESET_REASON)
	{
//		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
	else if(bootreason == MCU_RESET_UNDEFINED)
	{
		Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE7_GPIO_OUT_MCU_LED3, STD_OFF);
		Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
	}
}