#include "r_typedefs.h"
#include "dr7f701684.dvf.h"
#include "UART.h"
#include "rh850_macros.h"
#include <string.h>
#define UART_TX_MAX_DEPTH 1024UL          //(2 * 1024UL)    // 4K
#define UART_RX_MAX_DEPTH (2 * 1024UL)    // 4K
/*-----------------use for RH850_F1KM_S1 --------------------*/
/*******************************************************************/

#define UART_BASE_ADDRESS 0xFFCE2000UL
#define UART_CKSCLK_ILIN 40000000UL

#define UART_TIME_OUT_MAX 0X0000FFFFUL

/*******************************************************************/

uint32_t UART_Init(UART_Channel_en_t enUARTCh, UART_Channel_Config_st_t *penUARTCfg);
void UART_Sleep_Init(UART_Channel_en_t enUARTCh);
/*******************************************************************/
/*******************************************************************/
/*******************************************************************/
#define UART_LSB_FIRST (0U << 1U)
#define UART_MSB_FIRST (1U << 1U)

#define UART_INT_AT_START (0U << 3U)
#define UART_INT_AT_FINISH (1U << 3U)

#define LIN_CHECKSUM_CLASSIC (0U)
#define LIN_CHECKSUM_ENHANCED (0X20U)
/*******************************************************/
typedef struct
{
	uint32_t u32UARTCount;	  /*发送计数*/
	uint32_t u32UARTLEN;	  /*UART发送数据总长,LIN接收数据总长*/
	uint8_t u8UARTTXBusyFlag; /*发送是否忙标志  0:idle  1:busy */
	uint8_t u8LINBusyFlag;	  /*总线是否忙标志  0:idle  1:TX  2:RX */
	uint8_t u8UARTReserved1;
	uint8_t u8UARTReserved2;
	uint8_t *pu8UARTDataBuf; /*要发送数据的指针*/
} UART_Ctr_st_t;
/*******************************************************/

static UART_Ctr_st_t stUARTCtr0;
static UART_Ctr_st_t stUARTCtr1;
static UART_Ctr_st_t stUARTCtr2;
static UART_Ctr_st_t stUARTCtr3;

static UART_Channel_Config_st_t stUARTCh0Cfg;
static UART_Channel_Config_st_t stUARTCh1Cfg;
static UART_Channel_Config_st_t stUARTCh2Cfg;
static UART_Channel_Config_st_t stUARTCh3Cfg;

static uint8_t u8UART30SendBuf[UART_30_SEND_MAX];
static uint8_t u8UART31SendBuf[UART_31_SEND_MAX];
static uint8_t u8UART32SendBuf[UART_32_SEND_MAX];
static uint8_t u8UART33SendBuf[UART_33_SEND_MAX];

/*******************************************************/
// void UART_Put(uint16_t Data)
// {
//     uint32_t nextPos = 0u;

//     nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

//     if ( nextPos == UARTRxBuf.read_pos )
//     {
//         //队列已满，无法插入队列
//     }
//     else
//     {
//         UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Data;
//         UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
//     }

//     return;
// }

static void UART_CH0_Variate_Init(void)
{
	uint32_t i = 0UL;

	memset(&stUARTCtr0, 0, sizeof(stUARTCtr0));
	memset(&stUARTCh0Cfg, 0, sizeof(stUARTCh0Cfg));

	for (i = 0; i < UART_30_SEND_MAX; i++)
	{
		u8UART30SendBuf[i] = 0U;
	}
}
static void UART_CH1_Variate_Init(void)
{
	uint32_t i = 0UL;

	memset(&stUARTCtr1, 0, sizeof(stUARTCtr1));
	memset(&stUARTCh1Cfg, 0, sizeof(stUARTCh1Cfg));

	for (i = 0; i < UART_31_SEND_MAX; i++)
	{
		u8UART31SendBuf[i] = 0U;
	}
}
static void UART_CH2_Variate_Init(void)
{
	uint32_t i = 0UL;
	memset(&stUARTCtr2, 0, sizeof(stUARTCtr2));
	memset(&stUARTCh2Cfg, 0, sizeof(stUARTCh2Cfg));

	for (i = 0; i < UART_32_SEND_MAX; i++)
	{
		u8UART32SendBuf[i] = 0U;
	}
}
static void UART_CH3_Variate_Init(void)
{
	uint32_t i = 0UL;
	memset(&stUARTCtr3, 0, sizeof(stUARTCtr3));
	memset(&stUARTCh3Cfg, 0, sizeof(stUARTCh3Cfg));

	for (i = 0; i < UART_33_SEND_MAX; i++)
	{
		u8UART33SendBuf[i] = 0U;
	}
}


uint32_t UART_Init(UART_Channel_en_t enUARTCh, UART_Channel_Config_st_t *penUARTCfg)
{

	uint32_t u32UARTAddressBase = 0UL;
	uint32_t u32UARTAddress = 0UL;
	uint32_t u32UARTCalBuf = 0UL;
	uint32_t u32UARTTimeCount = 0UL;
	uint32_t i = 0UL;
	uint32_t j = 0UL;
	uint32_t u32UARTRealbps[11UL];
	uint32_t u32UARTbpsDif[11UL];
	uint32_t u32UARTbpsBRP[11UL];

	if ((enUARTCh < UART_RLIN_MAX) && (penUARTCfg->enUARTLINMode == MODE_UART) && (penUARTCfg->u32UARTbps))
	{
		u32UARTAddressBase = UART_BASE_ADDRESS + 0x40UL * enUARTCh;

		u32UARTAddress = u32UARTAddressBase + 0x20U;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LUOER = 0X00U;

		u32UARTAddress = u32UARTAddressBase + 0x08U;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		// RLN31LMD = 0X0U;
		/*****LIN reset mode*/
		u32UARTAddress = u32UARTAddressBase + 0x0EU;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LCUC = 0X0U;
		u32UARTAddress = u32UARTAddressBase + 0x11U;
		u32UARTTimeCount = 0UL;
		while (((*((uint8_t *)(u32UARTAddress))) != 0U) && (u32UARTTimeCount < UART_TIME_OUT_MAX))
		//  while (RLN31LMST != 0U)
		{
			u32UARTTimeCount++;
		}

		/** baud rate**/
		for (i = 0UL; i < 11UL; i++)
		{
			u32UARTbpsBRP[i] = UART_CKSCLK_ILIN / (i + 6UL) / penUARTCfg->u32UARTbps;

			if ((u32UARTbpsBRP[i] >= 1UL) && (u32UARTbpsBRP[i] <= 65536UL))
			{
				u32UARTRealbps[i] = UART_CKSCLK_ILIN / (i + 6UL) / u32UARTbpsBRP[i];
			}
			else
			{
				u32UARTRealbps[i] = 0xFFFFFFFFUL;
			}
			if (u32UARTRealbps[i] < penUARTCfg->u32UARTbps)
			{
				u32UARTbpsDif[i] = penUARTCfg->u32UARTbps - u32UARTRealbps[i];
			}
			else
			{
				u32UARTbpsDif[i] = u32UARTRealbps[i] - penUARTCfg->u32UARTbps;
			}
		}

		j = 10UL;
		for (i = 15; i >= 6UL; i--)
		{
			if (u32UARTbpsDif[i - 6] < u32UARTbpsDif[j])
			{
				j = i - 6;
			}
		}

		u32UARTAddress = u32UARTAddressBase + 0x01U;
		(*((uint8_t *)(u32UARTAddress))) = ((j + 5U) << 4U);
		//(*((uint8_t *)(u32UARTAddress))) = 0X50U;
		/*6 samplings  Prescaler Clock Select1/1*/
		// RLN31LWBR = 0X50U;

		u32UARTAddress = u32UARTAddressBase + 0x02U;
		(*((uint16_t *)(u32UARTAddress))) = u32UARTbpsBRP[j] - 1U;
		// 	(*((uint16_t *)(u32UARTAddress))) = u32UARTCalBuf - 1U;
		// 	// RLN31LBRP01 = u32UARTCalBuf - 1U;

		penUARTCfg->u32UARTbps = u32UARTRealbps[j];

		/**The noise filter is enabled**/
		u32UARTAddress = u32UARTAddressBase + 0x08U;
		(*((uint8_t *)(u32UARTAddress))) = 0X01U;
		//RLN31LMD = 0X01U;

		/**disable error detection.**/
		u32UARTAddress = u32UARTAddressBase + 0x0DU;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LEDE = 0U;
		/*** data format   */
		u32UARTCalBuf = (penUARTCfg->enUARTOrder << 1U);
		u32UARTCalBuf |= (penUARTCfg->en2UARTParity << 3U);
		u32UARTCalBuf |= (penUARTCfg->en2UARTPolarity << 5U);

		u32UARTAddress = u32UARTAddressBase + 0x09U;
		(*((uint8_t *)(u32UARTAddress))) = u32UARTCalBuf;
		// RLN31LBFC = UART_MSB_FIRST;
		/*Transmission interrupt is generated at.*/
		u32UARTAddress = u32UARTAddressBase + 0x21U;
		(*((uint8_t *)(u32UARTAddress))) = UART_INT_AT_FINISH;
		// RLN31LUOR1 = UART_INT_AT_FINISH;
		/******Exits from LIN reset mode***/
		u32UARTAddress = u32UARTAddressBase + 0x0EU;
		(*((uint8_t *)(u32UARTAddress))) = 0X01U;
		// RLN31LCUC = 0X01U;

		u32UARTAddress = u32UARTAddressBase + 0x11U;
		u32UARTTimeCount = 0UL;
		while (((*((uint8_t *)(u32UARTAddress))) != 0X01U) && (u32UARTTimeCount < UART_TIME_OUT_MAX))
		//  while (RLN31LMST != 0X01U)
		{
			u32UARTTimeCount++;
		}

		u32UARTAddress = u32UARTAddressBase + 0x13U;
		(*((uint8_t *)(u32UARTAddress))) = 0X0U;
		// RLN31LEST = 0X0U; /*clear Error Flag , it doesn't matter*/

		u32UARTAddress = u32UARTAddressBase + 0x20U;
		(*((uint8_t *)(u32UARTAddress))) = 0X03U;
		//  RLN31LUOER = 0X03U; /*TX RX EN*/

		/***************************/
		/**********NO USE*****************/

		/***************************/

		if (enUARTCh == UART_RLIN30)
		{
			UART_CH0_Variate_Init();
			stUARTCh0Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN30UR0);
			peripheral_IRQ_enable(INTRLIN30UR1);
		}
		else if (enUARTCh == UART_RLIN31)
		{
			UART_CH1_Variate_Init();
			stUARTCh1Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN31UR0);
			peripheral_IRQ_enable(INTRLIN31UR1);
		}
		else if (enUARTCh == UART_RLIN32)
		{
			UART_CH2_Variate_Init();
			stUARTCh2Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN32UR0);
			peripheral_IRQ_enable(INTRLIN32UR1);
		}
		else if (enUARTCh == UART_RLIN33)
		{
			UART_CH3_Variate_Init();
			stUARTCh3Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN33UR0);
			peripheral_IRQ_enable(INTRLIN33UR1);
		}

		/***************************/
	}
	return penUARTCfg->u32UARTbps;
}

void UART_Sleep_Init(UART_Channel_en_t enUARTCh)
{

	uint32_t u32UARTAddressBase = 0UL;
	uint32_t u32UARTAddress = 0UL;
	uint32_t u32UARTTimeCount = 0UL;

	if ((enUARTCh < UART_RLIN_MAX))
	{
		u32UARTAddressBase = UART_BASE_ADDRESS + 0x40UL * enUARTCh;

		u32UARTAddress = u32UARTAddressBase + 0x20U;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LUOER = 0X00U;

		u32UARTAddress = u32UARTAddressBase + 0x08U;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		// RLN31LMD = 0X0U;
		/*****LIN reset mode*/
		u32UARTAddress = u32UARTAddressBase + 0x0EU;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LCUC = 0X0U;
		u32UARTAddress = u32UARTAddressBase + 0x11U;
		u32UARTTimeCount = 0UL;
		while (((*((uint8_t *)(u32UARTAddress))) != 0U) && (u32UARTTimeCount < UART_TIME_OUT_MAX))
		//  while (RLN31LMST != 0U)
		{
			u32UARTTimeCount++;
		}
		if (enUARTCh == UART_RLIN30)
		{
			UART_CH0_Variate_Init();
		}
		else if (enUARTCh == UART_RLIN31)
		{
			UART_CH1_Variate_Init();
		}
		else if (enUARTCh == UART_RLIN32)
		{
			UART_CH2_Variate_Init();
		}
		else if (enUARTCh == UART_RLIN33)
		{
			UART_CH3_Variate_Init();
		}
	}
}

uint8_t UART_Ch0_Get_TX_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN30LST & 0x10U) || (stUARTCtr0.u8UARTTXBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t UART_Ch1_Get_TX_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN31LST & 0x10U) || (stUARTCtr1.u8UARTTXBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t UART_Ch2_Get_TX_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN32LST & 0x10U) || (stUARTCtr2.u8UARTTXBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t UART_Ch3_Get_TX_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN33LST & 0x10U) || (stUARTCtr3.u8UARTTXBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}

uint32_t UART_Ch0_Send_Multiple_Byte(uint8_t *Data, uint32_t Len)
{
	uint32_t u32UARTResult = 1UL;
	if ((UART_Ch1_Get_TX_Busy_Flag() == 0U) && (Len <= UART_30_SEND_MAX))
	{
		uint32_t i = 0UL;
		stUARTCtr0.u32UARTCount = 1U;
		stUARTCtr0.u32UARTLEN = Len;
		stUARTCtr0.u8UARTTXBusyFlag = 1U;
		stUARTCtr0.pu8UARTDataBuf = Data;
		for (i = 0; i < Len; i++)
		{
			u8UART30SendBuf[i] = Data[i];
		}

		RLN30LUTDR = stUARTCtr0.pu8UARTDataBuf[0U];
		u32UARTResult = 0UL;
	}
	else
	{
		UART_Ch0_Send_Multiple_Byte(Data,Len);
	}
	return u32UARTResult;
}

uint32_t UART_Ch1_Send_Multiple_Byte(uint8_t *Data, uint32_t Len)
{
	uint32_t u32UARTResult = 1UL;
	if ((UART_Ch1_Get_TX_Busy_Flag() == 0U) && (Len <= UART_31_SEND_MAX))
	{
		uint32_t i = 0UL;
		stUARTCtr1.u32UARTCount = 1U;
		stUARTCtr1.u32UARTLEN = Len;
		stUARTCtr1.u8UARTTXBusyFlag = 1U;
		stUARTCtr1.pu8UARTDataBuf = Data;
		for (i = 0; i < Len; i++)
		{
			u8UART31SendBuf[i] = Data[i];
		}
		RLN31LUTDR = stUARTCtr1.pu8UARTDataBuf[0U];
		u32UARTResult = 0UL;
	}
	return u32UARTResult;
}

uint32_t UART_Ch2_Send_Multiple_Byte(uint8_t *Data, uint32_t Len)
{
	uint32_t u32UARTResult = 1UL;
	if ((UART_Ch2_Get_TX_Busy_Flag() == 0U) && (Len <= UART_32_SEND_MAX))
	{
		uint32_t i = 0UL;
		stUARTCtr2.u32UARTCount = 1U;
		stUARTCtr2.u32UARTLEN = Len;
		stUARTCtr2.u8UARTTXBusyFlag = 1U;
		stUARTCtr2.pu8UARTDataBuf = Data;
		for (i = 0; i < Len; i++)
		{
			u8UART32SendBuf[i] = Data[i];
		}
		RLN32LUTDR = stUARTCtr2.pu8UARTDataBuf[0U];
		u32UARTResult = 0UL;
	}
	return u32UARTResult;
}
uint32_t UART_Ch3_Send_Multiple_Byte(uint8_t *Data, uint32_t Len)
{
	uint32_t u32UARTResult = 1UL;
	if ((UART_Ch3_Get_TX_Busy_Flag() == 0U) && (Len <= UART_33_SEND_MAX))
	{
		uint32_t i = 0UL;
		stUARTCtr3.u32UARTCount = 1U;
		stUARTCtr3.u32UARTLEN = Len;
		stUARTCtr3.u8UARTTXBusyFlag = 1U;
		stUARTCtr3.pu8UARTDataBuf = Data;
		for (i = 0; i < Len; i++)
		{
			u8UART33SendBuf[i] = Data[i];
		}
		RLN33LUTDR = stUARTCtr3.pu8UARTDataBuf[0U];
		u32UARTResult = 0UL;
	}
	return u32UARTResult;
}

void UART_CH0_RX_ISR(void)
{
	if (stUARTCh0Cfg.enUARTLINMode == MODE_UART)
	{
		/*If no error is detected*/
		if (stUARTCh0Cfg.pfnUARTReadMsgCallBack)
		{
			stUARTCh0Cfg.pfnUARTReadMsgCallBack(RLN30LURDR);
		}
	}
	else if (stUARTCh0Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN30LST & 0x02U)
		{

			uint8_t i = 0U;
			volatile uint8_t *pRLINDataBuf = &RLN30LDBR1;

			if (stUARTCh0Cfg.pfnUARTReadMsgCallBack)
			{
				stUARTCh0Cfg.pfnUARTReadMsgCallBack(RLN30LIDB);
				for (i = 0U; i < stUARTCtr0.u32UARTLEN; i++)
				{
					stUARTCh0Cfg.pfnUARTReadMsgCallBack(pRLINDataBuf[i]);
				}
			}

			stUARTCtr0.u8LINBusyFlag = 0U;
		}
		RLN30LST = 0U;
	}
}
void UART_CH1_RX_ISR(void)
{
	if (stUARTCh1Cfg.enUARTLINMode == MODE_UART)
	{
		/*If no error is detected*/
		if (stUARTCh1Cfg.pfnUARTReadMsgCallBack)
		{
			stUARTCh1Cfg.pfnUARTReadMsgCallBack(RLN31LURDR);
		}
	}
	else if (stUARTCh1Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN31LST & 0x02U)
		{

			uint8_t i = 0U;
			volatile uint8_t *pRLINDataBuf = &RLN31LDBR1;
			if (stUARTCh1Cfg.pfnUARTReadMsgCallBack)
			{
				stUARTCh1Cfg.pfnUARTReadMsgCallBack(RLN31LIDB);
				for (i = 0U; i < stUARTCtr1.u32UARTLEN; i++)
				{
					stUARTCh1Cfg.pfnUARTReadMsgCallBack(pRLINDataBuf[i]);
				}
			}
			stUARTCtr1.u8LINBusyFlag = 0U;
		}
		RLN31LST = 0U;
	}
}
void UART_CH2_RX_ISR(void)
{
	if (stUARTCh2Cfg.enUARTLINMode == MODE_UART)
	{
		/*If no error is detected*/
		if (stUARTCh2Cfg.pfnUARTReadMsgCallBack)
		{
			stUARTCh2Cfg.pfnUARTReadMsgCallBack(RLN32LURDR);
		}
	}
	else if (stUARTCh2Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{

		if (RLN32LST & 0x02U)
		{

			uint8_t i = 0U;
			volatile uint8_t *pRLINDataBuf = &RLN32LDBR1;
			if (stUARTCh2Cfg.pfnUARTReadMsgCallBack)
			{
				stUARTCh2Cfg.pfnUARTReadMsgCallBack(RLN32LIDB);

				for (i = 0U; i < stUARTCtr2.u32UARTLEN; i++)
				{
					stUARTCh2Cfg.pfnUARTReadMsgCallBack(pRLINDataBuf[i]);
				}
			}
			stUARTCtr2.u8LINBusyFlag = 0U;
		}
		RLN32LST = 0U;
	}
}
void UART_CH3_RX_ISR(void)
{
	if (stUARTCh3Cfg.enUARTLINMode == MODE_UART)
	{
		/*If no error is detected*/
		if (stUARTCh3Cfg.pfnUARTReadMsgCallBack)
		{
			stUARTCh3Cfg.pfnUARTReadMsgCallBack(RLN33LURDR);
		}
	}
	else if (stUARTCh3Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN33LST & 0x02U)
		{

			uint8_t i = 0U;
			volatile uint8_t *pRLINDataBuf = &RLN33LDBR1;

			if (stUARTCh3Cfg.pfnUARTReadMsgCallBack)
			{
				stUARTCh3Cfg.pfnUARTReadMsgCallBack(RLN33LIDB);

				for (i = 0U; i < stUARTCtr3.u32UARTLEN; i++)
				{
					stUARTCh3Cfg.pfnUARTReadMsgCallBack(pRLINDataBuf[i]);
				}
			}
			stUARTCtr3.u8LINBusyFlag = 0U;
		}
		RLN33LST = 0U;
	}
}

void UART_CH0_TX_ISR(void)
{
	if (stUARTCh0Cfg.enUARTLINMode == MODE_UART)
	{
		if (stUARTCtr0.u32UARTCount < stUARTCtr0.u32UARTLEN)
		{
			RLN30LUTDR = u8UART30SendBuf[stUARTCtr0.u32UARTCount++];
		}
		else
		{
			stUARTCtr0.u8UARTTXBusyFlag = 0U;
			if (stUARTCh0Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh0Cfg.pfnUARTConfirmCallBack();
			}
		}
	}
	else if (stUARTCh0Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN30LST & 0x01U)
		{
			stUARTCtr0.u8LINBusyFlag = 0U;
			if (stUARTCh0Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh0Cfg.pfnUARTConfirmCallBack();
			}
		}
		RLN30LST = 0U;
	}
}
void UART_CH1_TX_ISR(void)
{
	if (stUARTCh1Cfg.enUARTLINMode == MODE_UART)
	{

		if (stUARTCtr1.u32UARTCount < stUARTCtr1.u32UARTLEN)
		{
			RLN31LUTDR = u8UART31SendBuf[stUARTCtr1.u32UARTCount++];
		}
		else
		{
			stUARTCtr1.u8UARTTXBusyFlag = 0U;
			if (stUARTCh1Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh1Cfg.pfnUARTConfirmCallBack();
			}
		}
	}
	else if (stUARTCh1Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN31LST & 0x01U)
		{

			stUARTCtr1.u8LINBusyFlag = 0U;
			if (stUARTCh1Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh1Cfg.pfnUARTConfirmCallBack();
			}
		}
		RLN31LST = 0U;
	}
}
void UART_CH2_TX_ISR(void)
{
	if (stUARTCh2Cfg.enUARTLINMode == MODE_UART)
	{

		if (stUARTCtr2.u32UARTCount < stUARTCtr2.u32UARTLEN)
		{
			RLN32LUTDR = u8UART32SendBuf[stUARTCtr2.u32UARTCount++];
		}
		else
		{
			stUARTCtr2.u8UARTTXBusyFlag = 0U;
			if (stUARTCh2Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh2Cfg.pfnUARTConfirmCallBack();
			}
		}
	}
	else if (stUARTCh2Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN32LST & 0x01U)
		{

			stUARTCtr2.u8LINBusyFlag = 0U;
			if (stUARTCh2Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh2Cfg.pfnUARTConfirmCallBack();
			}
		}
		RLN32LST = 0U;
	}
}
void UART_CH3_TX_ISR(void)
{
	if (stUARTCh3Cfg.enUARTLINMode == MODE_UART)
	{

		if (stUARTCtr3.u32UARTCount < stUARTCtr3.u32UARTLEN)
		{
			RLN33LUTDR = u8UART33SendBuf[stUARTCtr3.u32UARTCount++];
		}
		else
		{
			stUARTCtr3.u8UARTTXBusyFlag = 0U;
			if (stUARTCh3Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh3Cfg.pfnUARTConfirmCallBack();
			}
		}
	}
	else if (stUARTCh3Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		if (RLN33LST & 0x01U)
		{
			stUARTCtr3.u8LINBusyFlag = 0U;
			if (stUARTCh3Cfg.pfnUARTConfirmCallBack)
			{
				stUARTCh3Cfg.pfnUARTConfirmCallBack();
			}
		}
		RLN33LST = 0U;
	}
}

void UART_CH0_Err_ISR(void)
{
	if (stUARTCh0Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{

		stUARTCtr0.u32UARTCount = 0U;
		stUARTCtr0.u32UARTLEN = 0U;
		stUARTCtr0.u8UARTTXBusyFlag = 0U;
		stUARTCtr0.u8LINBusyFlag = 0U;
		stUARTCtr0.pu8UARTDataBuf = 0U;

		if (stUARTCh0Cfg.pfnUARTErrHandleCallBack != 0U)
		{
			stUARTCh0Cfg.pfnUARTErrHandleCallBack(RLN30LEST);
		}
		RLN30LEST = 0U;
		RLN30LST = 0U;
	}
}
void UART_CH1_Err_ISR(void)
{
	if (stUARTCh1Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{

		stUARTCtr1.u32UARTCount = 0U;
		stUARTCtr1.u32UARTLEN = 0U;
		stUARTCtr1.u8UARTTXBusyFlag = 0U;
		stUARTCtr1.u8LINBusyFlag = 0U;
		stUARTCtr1.pu8UARTDataBuf = 0U;

		if (stUARTCh1Cfg.pfnUARTErrHandleCallBack != 0U)
		{
			stUARTCh1Cfg.pfnUARTErrHandleCallBack(RLN31LEST);
		}
		RLN31LEST = 0U;
		RLN31LST = 0U;
	}
}
void UART_CH2_Err_ISR(void)
{
	if (stUARTCh2Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{

		stUARTCtr2.u32UARTCount = 0U;
		stUARTCtr2.u32UARTLEN = 0U;
		stUARTCtr2.u8UARTTXBusyFlag = 0U;
		stUARTCtr2.u8LINBusyFlag = 0U;
		stUARTCtr2.pu8UARTDataBuf = 0U;

		if (stUARTCh2Cfg.pfnUARTErrHandleCallBack != 0U)
		{
			stUARTCh2Cfg.pfnUARTErrHandleCallBack(RLN32LEST);
		}
		RLN32LEST = 0U;
		RLN32LST = 0U;
	}
}
void UART_CH3_Err_ISR(void)
{
	if (stUARTCh3Cfg.enUARTLINMode == MODE_LIN_MASTER)
	{
		stUARTCtr3.u32UARTCount = 0U;
		stUARTCtr3.u32UARTLEN = 0U;
		stUARTCtr3.u8UARTTXBusyFlag = 0U;
		stUARTCtr3.u8LINBusyFlag = 0U;
		stUARTCtr3.pu8UARTDataBuf = 0U;

		if (stUARTCh3Cfg.pfnUARTErrHandleCallBack != 0U)
		{
			stUARTCh3Cfg.pfnUARTErrHandleCallBack(RLN33LEST);
		}
		RLN33LEST = 0U;
		RLN33LST = 0U;
	}
}
/*****************************LIN*****************************************************/
/*****************************LIN*****************************************************/
/*****************************LIN*****************************************************/


uint32_t UART_LIN_Init(UART_Channel_en_t enUARTCh, UART_Channel_Config_st_t *penUARTCfg)
{

	uint32_t u32UARTAddressBase = 0UL;
	uint32_t u32UARTAddress = 0UL;
	uint32_t u32UARTCalBuf = 0UL;
	uint32_t u32UARTFre = UART_CKSCLK_ILIN;
	uint32_t u32UARTTimeCount = 0UL;

	if ((enUARTCh < UART_RLIN_MAX) && (penUARTCfg->enUARTLINMode == MODE_LIN_MASTER) && (penUARTCfg->u32UARTbps))
	{
		u32UARTAddressBase = UART_BASE_ADDRESS + 0x40UL * enUARTCh;

		u32UARTAddress = u32UARTAddressBase + 0x08U;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		// RLN31LMD = 0X0U;
		/*****LIN reset mode*/
		u32UARTAddress = u32UARTAddressBase + 0x0EU;
		(*((uint8_t *)(u32UARTAddress))) = 0X00U;
		//  RLN31LCUC = 0X0U;
		u32UARTAddress = u32UARTAddressBase + 0x11U;
		u32UARTTimeCount = 0UL;
		while (((*((uint8_t *)(u32UARTAddress))) != 0U) && (u32UARTTimeCount < UART_TIME_OUT_MAX))
		//  while (RLN31LMST != 0U)
		{
			u32UARTTimeCount++;
		}

		/** baud rate**/

		u32UARTAddress = u32UARTAddressBase + 0x01U;

		if (penUARTCfg->u32UARTbps >= 19200)
		{
			(*((uint8_t *)(u32UARTAddress))) = 0X0U;
			/*16 samplings  Prescaler Clock Select1/1*/
			// RLN31LWBR = 0X0U;
			u32UARTFre = UART_CKSCLK_ILIN;
		}
		else if (penUARTCfg->u32UARTbps >= 9600)
		{
			(*((uint8_t *)(u32UARTAddress))) = 0X02U;
			u32UARTFre = UART_CKSCLK_ILIN / 2U;
		}
		else //if (penUARTCfg->u32UARTbps>=2400)
		{
			(*((uint8_t *)(u32UARTAddress))) = 0X06U;
			u32UARTFre = UART_CKSCLK_ILIN / 8U;
		}

		u32UARTCalBuf = u32UARTFre / 16UL / penUARTCfg->u32UARTbps;
		if ((u32UARTCalBuf) && (u32UARTCalBuf <= 256))
		{
			u32UARTAddress = u32UARTAddressBase + 0x02U;
			(*((uint8_t *)(u32UARTAddress))) = u32UARTCalBuf - 1U;
			// RLN31LBRP01 = u32UARTCalBuf - 1U;
			penUARTCfg->u32UARTbps = u32UARTFre / 16UL / u32UARTCalBuf;
		}
		else
		{
			penUARTCfg->u32UARTbps = 0xFFFFFFFFUL;
		}

		/**The noise filter is enabled**/
		u32UARTAddress = u32UARTAddressBase + 0x08U;
		(*((uint8_t *)(u32UARTAddress))) = 0X10U;
		//RLN31LMD = 0X01U;

		/**error detection.**/
		u32UARTAddress = u32UARTAddressBase + 0x0DU;
		(*((uint8_t *)(u32UARTAddress))) = 0X8FU;
		//  RLN31LEDE = 0U;

		/*** data format   13+1*/
		u32UARTAddress = u32UARTAddressBase + 0x09U;
		(*((uint8_t *)(u32UARTAddress))) = 0x0U;
		// RLN31LBFC = UART_MSB_FIRST;
		/*0+0*/
		u32UARTAddress = u32UARTAddressBase + 0x0AU;
		(*((uint8_t *)(u32UARTAddress))) = 0x00U;
		// RLN3nLSC = 0 ;

		u32UARTAddress = u32UARTAddressBase + 0x0CU;
		(*((uint8_t *)(u32UARTAddress))) = 0X07U;
		//  RLN3nLIE = /**/
		u32UARTAddress = u32UARTAddressBase + 0x0DU;
		(*((uint8_t *)(u32UARTAddress))) = 0X8FU;
		//  RLN3nLEDE =  /**/

		/******Exits from LIN reset mode***/
		u32UARTAddress = u32UARTAddressBase + 0x0EU;
		(*((uint8_t *)(u32UARTAddress))) = 0X03U;
		// RLN31LCUC = 0X01U;

		u32UARTAddress = u32UARTAddressBase + 0x11U;
		u32UARTTimeCount = 0UL;
		while (((*((uint8_t *)(u32UARTAddress))) != 0X03U) && (u32UARTTimeCount < UART_TIME_OUT_MAX))
		//  while (RLN31LMST != 0X01U)
		{
			u32UARTTimeCount++;
		}

		/***************************/
		/**********NO USE*****************/

		/***************************/

		if (enUARTCh == UART_RLIN30)
		{
			UART_CH0_Variate_Init();
			stUARTCh0Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN30UR0);
			peripheral_IRQ_enable(INTRLIN30UR1);
			peripheral_IRQ_enable(INTRLIN30UR2);
		}
		else if (enUARTCh == UART_RLIN31)
		{
			UART_CH1_Variate_Init();
			stUARTCh1Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN31UR0);
			peripheral_IRQ_enable(INTRLIN31UR1);
			peripheral_IRQ_enable(INTRLIN31UR2);
		}
		else if (enUARTCh == UART_RLIN32)
		{
			UART_CH2_Variate_Init();
			stUARTCh2Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN32UR0);
			peripheral_IRQ_enable(INTRLIN32UR1);
			peripheral_IRQ_enable(INTRLIN32UR2);
		}
		else if (enUARTCh == UART_RLIN33)
		{
			UART_CH3_Variate_Init();
			stUARTCh3Cfg = *penUARTCfg;
			peripheral_IRQ_enable(INTRLIN33UR0);
			peripheral_IRQ_enable(INTRLIN33UR1);
			peripheral_IRQ_enable(INTRLIN33UR2);
		}

		/***************************/
	}
	return penUARTCfg->u32UARTbps;
}

uint8_t LIN_CAL_PID(uint8_t u8LINID)
{
	uint8_t u8LINPID = u8LINID;
	uint8_t u8LINP0 = 0U;
	uint8_t u8LINP1 = 0U;

	u8LINP0 = (((u8LINID >> 0) & 0x01) ^ ((u8LINID >> 1) & 0x01) ^ ((u8LINID >> 2) & 0x01) ^ ((u8LINID >> 4) & 0x01)) << 6U;
	u8LINP1 = (!(((u8LINID >> 1) & 0x01) ^ ((u8LINID >> 3) & 0x01) ^ ((u8LINID >> 4) & 0x01) ^ ((u8LINID >> 5) & 0x01))) << 7U;

	u8LINPID |= u8LINP0;
	u8LINPID |= u8LINP1;

	return u8LINPID;
}

uint8_t LIN_Ch0_Get_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN30LTRC & 0x01U) || (stUARTCtr0.u8LINBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t LIN_Ch1_Get_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN31LTRC & 0x01U) || (stUARTCtr1.u8LINBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t LIN_Ch2_Get_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN32LTRC & 0x01U) || (stUARTCtr2.u8LINBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint8_t LIN_Ch3_Get_Busy_Flag(void)
{
	uint8_t u8Status = 0U;
	if ((RLN33LTRC & 0x01U) || (stUARTCtr3.u8LINBusyFlag))
	{
		u8Status = 1U;
	}
	return u8Status;
}
uint32_t LIN_Ch0_Send_Header_Send_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch0_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			volatile uint8_t *pRLINDataBuf = &RLN30LDBR1;
			uint8_t i = 0U;
			stUARTCtr0.u8LINBusyFlag = 1U;

			RLN30LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN30LDFC = LIN_CHECKSUM_ENHANCED | 0X10U | (pstLINData->u8LINLen);

			for (i = 0U; i < pstLINData->u8LINLen; i++)
			{
				pRLINDataBuf[i] = pstLINData->pu8LINData[i];
			}
			RLN30LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch1_Send_Header_Send_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch1_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			volatile uint8_t *pRLINDataBuf = &RLN31LDBR1;
			uint8_t i = 0U;
			stUARTCtr1.u8LINBusyFlag = 1U;

			RLN31LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN31LDFC = LIN_CHECKSUM_ENHANCED | 0X10U | (pstLINData->u8LINLen);

			for (i = 0U; i < pstLINData->u8LINLen; i++)
			{
				pRLINDataBuf[i] = pstLINData->pu8LINData[i];
			}
			RLN31LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch2_Send_Header_Send_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch2_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			volatile uint8_t *pRLINDataBuf = &RLN32LDBR1;
			uint8_t i = 0U;
			stUARTCtr2.u8LINBusyFlag = 1U;

			RLN32LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN32LDFC = LIN_CHECKSUM_ENHANCED | 0X10U | (pstLINData->u8LINLen);

			for (i = 0U; i < pstLINData->u8LINLen; i++)
			{
				pRLINDataBuf[i] = pstLINData->pu8LINData[i];
			}
			RLN32LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch3_Send_Header_Send_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch3_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			volatile uint8_t *pRLINDataBuf = &RLN33LDBR1;
			uint8_t i = 0U;
			stUARTCtr3.u8LINBusyFlag = 1U;

			RLN33LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN33LDFC = LIN_CHECKSUM_ENHANCED | 0X10U | (pstLINData->u8LINLen);

			for (i = 0U; i < pstLINData->u8LINLen; i++)
			{
				pRLINDataBuf[i] = pstLINData->pu8LINData[i];
			}
			RLN33LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}

uint32_t LIN_Ch0_Send_Header_Recieve_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch0_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			stUARTCtr0.u8LINBusyFlag = 2U;
			stUARTCtr0.u32UARTLEN = pstLINData->u8LINLen;

			RLN30LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN30LDFC = LIN_CHECKSUM_ENHANCED | (pstLINData->u8LINLen);

			RLN30LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch1_Send_Header_Recieve_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch1_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			stUARTCtr1.u8LINBusyFlag = 2U;
			stUARTCtr1.u32UARTLEN = pstLINData->u8LINLen;

			RLN31LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN31LDFC = LIN_CHECKSUM_ENHANCED | (pstLINData->u8LINLen);

			RLN31LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch2_Send_Header_Recieve_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch2_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			stUARTCtr2.u8LINBusyFlag = 2U;
			stUARTCtr2.u32UARTLEN = pstLINData->u8LINLen;

			RLN32LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN32LDFC = LIN_CHECKSUM_ENHANCED | (pstLINData->u8LINLen);

			RLN32LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
uint32_t LIN_Ch3_Send_Header_Recieve_Response(LIN_Data_st_t *pstLINData)
{
	uint32_t u32UARTResult = 1UL;
	if (LIN_Ch3_Get_Busy_Flag() == 0U)
	{
		if (pstLINData->u8LINLen < 8)
		{
			stUARTCtr3.u8LINBusyFlag = 2U;
			stUARTCtr3.u32UARTLEN = pstLINData->u8LINLen;

			RLN33LIDB = LIN_CAL_PID(pstLINData->u8LINID);
			RLN33LDFC = LIN_CHECKSUM_ENHANCED | (pstLINData->u8LINLen);

			RLN33LTRC = 0X01U;
			u32UARTResult = 0UL;
		}
	}
	return u32UARTResult;
}
