/*
 * LPUART_TJA1124_LIN_Comm.c
 *
 *  Created on: Sep 24, 2019
 *      Author: nxa07657
 */

#include "bsp.h"
#include "Lpuart_Lin_Ip.h"
#include "LIN_TJA1124_test.h"

#define TAG "LPUART_TJA1124"     /* the KDF log print tag for debug */

#define LIN_FRAME_PRINT_ENABLE			0
#define LIN_TJA1124_CONNECTION_PRINT	0

/* declear the RTD LPUART LIN ISR used */
extern ISR(LPUART6_LIN_IP_RxTx_IRQHandler);
extern ISR(LPUART7_LIN_IP_RxTx_IRQHandler);
extern ISR(LPUART9_LIN_IP_RxTx_IRQHandler);
extern ISR(LPUART12_LIN_IP_RxTx_IRQHandler);


uint32_t wakeupSignalFlag = false;


static uint8 tx_linSdu[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
static uint8 rx_linSdu_Addr = 0;
static uint8_t **rx_bufer = (uint8_t **)(&rx_linSdu_Addr);


bool transfer_complete_flag = false;

static uint8_t lin1_timeout = 0;
static uint8_t lin2_timeout = 0;
static uint8_t lin3_timeout = 0;
static uint8_t lin4_timeout = 0;


void PIT1_CH0_Timer_Notification(uint8 channel)
{
	(void)channel;

	/* call the LIN timeout service */
	Lpuart_Lin_Ip_TimerExpiredService(TJA1124_CH1_LIN_INST);
}

void PIT1_CH1_Timer_Notification(uint8 channel)
{
	(void)channel;

	/* call the LIN timeout service */
	Lpuart_Lin_Ip_TimerExpiredService(TJA1124_CH2_LIN_INST);
}

void PIT1_CH2_Timer_Notification(uint8 channel)
{
	(void)channel;

	/* call the LIN timeout service */
	Lpuart_Lin_Ip_TimerExpiredService(TJA1124_CH3_LIN_INST);
}

void PIT1_CH3_Timer_Notification(uint8 channel)
{
	(void)channel;

	/* call the LIN timeout service */
	Lpuart_Lin_Ip_TimerExpiredService(TJA1124_CH4_LIN_INST);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : LIN1_CallBack
 * Description   : The LIN message frame handle ISR callback of LIN1 for user process
 *
 *END**************************************************************************/
void LIN1_CallBack(uint8 Instance, Lpuart_Lin_Ip_StateStructType *LpuartStateStruct)
{
	(void) Instance;
	if(LPUART_LIN_IP_TIMEOUT_ERROR == LpuartStateStruct->CurrentEventId)
	{
		lin1_timeout = 1;/* set the flag */
	}
	if(LPUART_LIN_IP_RX_COMPLETED == LpuartStateStruct->CurrentEventId)
	{

	}
}

/*FUNCTION**********************************************************************
 *
 * Function Name : LIN2_CallBack
 * Description   : The LIN message frame handle ISR callback of LIN2 for user process
 *
 *END**************************************************************************/
void LIN2_CallBack(uint8 Instance, Lpuart_Lin_Ip_StateStructType *LpuartStateStruct)
{
	(void) Instance;
	if(LPUART_LIN_IP_TIMEOUT_ERROR == LpuartStateStruct->CurrentEventId)
	{
		lin2_timeout = 1;/* set the flag */
	}
}

/*FUNCTION**********************************************************************
 *
 * Function Name : LIN3_CallBack
 * Description   : The LIN message frame handle ISR callback of LIN3 for user process
 *
 *END**************************************************************************/
void LIN3_CallBack(uint8 Instance, Lpuart_Lin_Ip_StateStructType *LpuartStateStruct)
{
	(void) Instance;
	if(LPUART_LIN_IP_TIMEOUT_ERROR == LpuartStateStruct->CurrentEventId)
	{
		lin3_timeout = 1;/* set the flag */
	}
}

/*FUNCTION**********************************************************************
 *
 * Function Name : LIN4_CallBack
 * Description   : The LIN message frame handle ISR callback of LIN4 for user process
 *
 *END**************************************************************************/
void LIN4_CallBack(uint8 Instance, Lpuart_Lin_Ip_StateStructType *LpuartStateStruct)
{
	(void) Instance;
	if(LPUART_LIN_IP_TIMEOUT_ERROR == LpuartStateStruct->CurrentEventId)
	{
		lin4_timeout = 1;/* set the flag */
	}
}

void LIN_StartTimer_Notification(uint8 Instance, uint32 MicroSeconds)
{
	/* start the timer, LIN instance is translated to STM timer channel */
	switch(Instance)
	{
		case TJA1124_CH1_LIN_INST: Pit_Ip_StartChannel(LIN_PIT1_INST,CH_0,PIT1_MS2CNT(MicroSeconds)); break;

		case TJA1124_CH2_LIN_INST: Pit_Ip_StartChannel(LIN_PIT1_INST,CH_1,PIT1_MS2CNT(MicroSeconds)); break;

		case TJA1124_CH3_LIN_INST: Pit_Ip_StartChannel(LIN_PIT1_INST,CH_2,PIT1_MS2CNT(MicroSeconds)); break;

		case TJA1124_CH4_LIN_INST: Pit_Ip_StartChannel(LIN_PIT1_INST,CH_3,PIT1_MS2CNT(MicroSeconds)); break;

		default: break;
	}
}


void LIN_StopTimer_Notification(uint8 Instance)
{
	/* stop the timer, LIN instance is translated to STM timer channel */
	switch(Instance)
	{
		case TJA1124_CH1_LIN_INST: Pit_Ip_StopChannel(LIN_PIT1_INST,CH_0); break;

		case TJA1124_CH2_LIN_INST: Pit_Ip_StopChannel(LIN_PIT1_INST,CH_1); break;

		case TJA1124_CH3_LIN_INST: Pit_Ip_StopChannel(LIN_PIT1_INST,CH_2); break;

		case TJA1124_CH4_LIN_INST: Pit_Ip_StopChannel(LIN_PIT1_INST,CH_3); break;

		default: break;
	}
}


/*************************************************************************
 * Function API to send a LIN message frame with master response ID
 *
 * instance : The LPUART instance for LIN frame transfer
 * Message  : LIN message to be send
 *
 *************************************************************************/
Std_ReturnType LIN_Frame_Transmit(uint32_t instance, Lpuart_Lin_Ip_PduType *Message)
{
	Std_ReturnType retCode = E_OK;
	/* send out the frame header at first */
	retCode = Lpuart_Lin_Ip_SendFrame(instance, Message);
	if(retCode != E_OK)
		return retCode;

	/* wait for transfer complete */
	while(LPUART_LIN_IP_STATUS_TX_OK != Lpuart_Lin_Ip_GetStatus(instance, NULL_PTR))
	{
		if(lin1_timeout)
		{
			lin1_timeout = 0;/* clear the flag */

			return E_NOT_OK; /* return error */
		}
	}
	return E_OK;
}

/*************************************************************************
 * Function API to recive a LIN message frame with slave response ID
 *
 * instance : The LPUART instance for LIN frame transfer
 * Message  : LIN message to be receive
 *
 *************************************************************************/
Std_ReturnType LIN_Frame_Receive(uint32_t instance, Lpuart_Lin_Ip_PduType *Message)
{
	Std_ReturnType retCode = E_OK;
	/* send out the frame header at first */
	retCode = Lpuart_Lin_Ip_SendFrame(instance, Message);
	if(retCode != E_OK)
		return retCode;

	/* wait for transfer complete */
	while(LPUART_LIN_IP_STATUS_RX_OK != Lpuart_Lin_Ip_GetStatus(instance, rx_bufer))
	{
		if(lin1_timeout)
		{
			lin1_timeout = 0;/* clear the flag */

			return E_NOT_OK; /* return error */
		}
	}
	return E_OK;
}

#if LIN_FRAME_PRINT_ENABLE
static void LIN_Frame_Print(uint8_t **Message)
{
	uint32_t i = 0;

	LOGI(TAG,"LIN message frame received as below:\r\n");

	for(i=0; i < 8; i++)
	{
		LOGI(TAG,"data[%d] = 0x%x\r\n", (int)i, (unsigned int)((*Message)[i]));
	}
}
#endif



/*************************************************************************
 * Function API to initialize used LPUART instance and TJA1124 sleep control pin
 * for LPUART LIN and TJA1124 PHY test:
 *
 *  1. drive SLP pin of TJA1124 as low to make TJA1124 enter normal mode
 *
 *  2. initialize S32K344 LPUART6/7/9/12 as LIN master with 9600 baud rate to test
 *     TJA1124 LIN transceiver channel 1/2/3/4 according to S32K344-WB HW design
 *
 *  3. enable and install LPUART LPUART6/7/9/12 interrupt ISR
 *
 ************************************************************************/
void LPUART_LIN_TJA1124_Test_Init(void)
{
	/*set TJA1124 to enter normal mode*/
	TJA1124_EnterNormalMode();

#ifdef TJA1124_LIN_CH1_TEST

	/*initialize as LPUART6 as LIN master with baudrate = 9600*/
	Lpuart_Lin_Ip_Init(TJA1124_CH1_LIN_INST, &Lpuart_Lin_Ip_Sa_pHwConfigPB_0_BOARD_INITPERIPHERALS);
	IntCtrl_Ip_InstallHandler(LPUART6_IRQn, LPUART6_LIN_IP_RxTx_IRQHandler, NULL_PTR);
	IntCtrl_Ip_EnableIrq(LPUART6_IRQn);

#if LIN_TJA1124_CONNECTION_PRINT
	LOGI(TAG,"TJA1124 LIN1 test is enabled, User should connect a slave node to S32K344-WB J31-7 \
and configure ID = 0x%x as master response ID and ID = 0x%x as slave response ID with data length = %d, \
or it will stuck when test slave response ID frame!\r\n",FRAME_SLAVE_RECEIVE_DATA_ID1,              \
			FRAME_MASTER_RECEIVE_DATA_ID1, LIN_FRAME_DATA_LEN );
#endif

#endif /* end of TJA1124_LIN_CH1_TEST */

#ifdef TJA1124_LIN_CH2_TEST

	/*initialize as LPUART7 as LIN master with baudrate = 9600*/
	Lpuart_Lin_Ip_Init(TJA1124_CH2_LIN_INST, &Lpuart_Lin_Ip_Sa_pHwConfigPB_1_BOARD_INITPERIPHERALS);
	IntCtrl_Ip_InstallHandler(LPUART7_IRQn, LPUART7_LIN_IP_RxTx_IRQHandler, NULL_PTR);
	IntCtrl_Ip_EnableIrq(LPUART7_IRQn);

#if LIN_TJA1124_CONNECTION_PRINT
	LOGI(TAG,"TJA1124 LIN2 test is enabled, User should connect a slave node to S32K344-WB J31-8 \
and configure ID = 0x%x as master response ID and ID = 0x%x as slave response ID with data length = %d, \
or it will stuck when test slave response ID frame!\r\n",FRAME_SLAVE_RECEIVE_DATA_ID2,              \
			FRAME_MASTER_RECEIVE_DATA_ID2, LIN_FRAME_DATA_LEN );
#endif

#endif /* end of TJA1124_LIN_CH2_TEST */

#ifdef TJA1124_LIN_CH3_TEST

	/*initialize as LPUART9 as LIN master with baudrate = 9600*/
	Lpuart_Lin_Ip_Init(TJA1124_CH3_LIN_INST, &Lpuart_Lin_Ip_Sa_pHwConfigPB_2_BOARD_INITPERIPHERALS);
	IntCtrl_Ip_InstallHandler(LPUART9_IRQn, LPUART9_LIN_IP_RxTx_IRQHandler, NULL_PTR);
	IntCtrl_Ip_EnableIrq(LPUART9_IRQn);

#if LIN_TJA1124_CONNECTION_PRINT
	LOGI(TAG,"TJA1124 LIN3 test is enabled, User should connect a slave node to S32K344-WB J31-9 \
and configure ID = 0x%x as master response ID and ID = 0x%x as slave response ID with data length = %d, \
or it will stuck when test slave response ID frame!\r\n",FRAME_SLAVE_RECEIVE_DATA_ID3,              \
			FRAME_MASTER_RECEIVE_DATA_ID3, LIN_FRAME_DATA_LEN );
#endif


#endif /* end of TJA1124_LIN_CH3_TEST */

#ifdef TJA1124_LIN_CH4_TEST

	/*initialize as LPUART12 as LIN master with baudrate = 9600*/
	Lpuart_Lin_Ip_Init(TJA1124_CH4_LIN_INST, &Lpuart_Lin_Ip_Sa_pHwConfigPB_3_BOARD_INITPERIPHERALS);
	IntCtrl_Ip_InstallHandler(LPUART12_IRQn, LPUART12_LIN_IP_RxTx_IRQHandler, NULL_PTR);
	IntCtrl_Ip_EnableIrq(LPUART12_IRQn);

#if LIN_TJA1124_CONNECTION_PRINT
	LOGI(TAG,"TJA1124 LIN4 test is enabled, User should connect a slave node to S32K344-WB J31-10 \
and configure ID = 0x%x as master response ID and ID = 0x%x as slave response ID with data length = %d, \
or it will stuck when test slave response ID frame!\r\n",FRAME_SLAVE_RECEIVE_DATA_ID4,              \
			FRAME_MASTER_RECEIVE_DATA_ID4, LIN_FRAME_DATA_LEN );
#endif


#endif /* end of TJA1124_LIN_CH4_TEST */

}

void LPUART_LIN_TJA1124_Test()
{
#ifdef TJA1124_LIN_CH1_TEST
    LPUART_LIN1_TJA1124_Test();
#endif
#ifdef TJA1124_LIN_CH2_TEST
    LPUART_LIN2_TJA1124_Test();
#endif
#ifdef TJA1124_LIN_CH3_TEST
	LPUART_LIN3_TJA1124_Test();
#endif
#ifdef TJA1124_LIN_CH4_TEST
	LPUART_LIN4_TJA1124_Test();
#endif
}

/*************************************************************************
 * Function API to test TJA1124 PHY:
 *
 *  1. generate LIN frames(both master response ID and slave response ID) for the test
 *  2. call BSP APIs to transfer the LIN message frame
 *
 ************************************************************************/
void LPUART_LIN1_TJA1124_Test(void)
{
	Lpuart_Lin_Ip_StatusType status = LPUART_LIN_IP_STATUS_SUCCESS;
	(void)status;

	Lpuart_Lin_Ip_PduType tx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_TX,
			.Dl = 8,
			.SduPtr = tx_linSdu
	};

	Lpuart_Lin_Ip_PduType rx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_RX,
			.Dl = 8
	};
	(void)rx_lin_pdu;

	/* make PID with frame ID */
	tx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_SLAVE_RECEIVE_DATA_ID1, LIN_IP_MAKE_PARITY);
	rx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_MASTER_RECEIVE_DATA_ID1, LIN_IP_MAKE_PARITY);

	/* Send a master response frame*/
	status = LIN_Frame_Transmit(TJA1124_CH1_LIN_INST,&tx_lin_pdu);

#ifdef TJA1124_LIN_CH1_RECV_ENABLE
	/* send slave response LIN message frame via TJA1124 LIN1 and wait for slave response */
	LIN_Frame_Receive(TJA1124_CH1_LIN_INST, &rx_lin_pdu);
	/* print the received LIN frame */
	LIN_Frame_Print(rx_bufer);
#endif

}

void LPUART_LIN2_TJA1124_Test(void)
{
	Lpuart_Lin_Ip_StatusType status = LPUART_LIN_IP_STATUS_SUCCESS;
	(void)status;

	Lpuart_Lin_Ip_PduType tx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_TX,
			.Dl = 8,
			.SduPtr = tx_linSdu
	};

	Lpuart_Lin_Ip_PduType rx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_RX,
			.Dl = 8
	};
	(void)rx_lin_pdu;

	/* make PID with frame ID */
	tx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_SLAVE_RECEIVE_DATA_ID2, LIN_IP_MAKE_PARITY);
	rx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_MASTER_RECEIVE_DATA_ID2, LIN_IP_MAKE_PARITY);

	status = LIN_Frame_Transmit(TJA1124_CH2_LIN_INST,&tx_lin_pdu);

#ifdef TJA1124_LIN_CH2_RECV_ENABLE
	/* send slave response LIN message frame via TJA1124 LIN1 and wait for slave response */
	LIN_Frame_Receive(TJA1124_CH2_LIN_INST, &rx_lin_pdu);
	/* print the received LIN frame */
	LIN_Frame_Print(&rx_lin_pdu);
#endif

}

void LPUART_LIN3_TJA1124_Test(void)
{
	Lpuart_Lin_Ip_StatusType status = LPUART_LIN_IP_STATUS_SUCCESS;
	(void)status;

	Lpuart_Lin_Ip_PduType tx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_TX,
			.Dl = 8,
			.SduPtr = tx_linSdu
	};

	Lpuart_Lin_Ip_PduType rx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_RX,
			.Dl = 8
	};
	(void)rx_lin_pdu;

	/* make PID with frame ID */
	tx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_SLAVE_RECEIVE_DATA_ID3, LIN_IP_MAKE_PARITY);
	rx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_MASTER_RECEIVE_DATA_ID3, LIN_IP_MAKE_PARITY);

	status = LIN_Frame_Transmit(TJA1124_CH3_LIN_INST,&tx_lin_pdu);

#ifdef TJA1124_LIN_CH3_RECV_ENABLE
	/* send slave response LIN message frame via TJA1124 LIN1 and wait for slave response */
	LIN_Frame_Receive(TJA1124_CH3_LIN_INST, &rx_lin_pdu);
	/* print the received LIN frame */
	LIN_Frame_Print(&rx_lin_pdu);
#endif

}

void LPUART_LIN4_TJA1124_Test(void)
{
	Lpuart_Lin_Ip_StatusType status = LPUART_LIN_IP_STATUS_SUCCESS;
	(void)status;

	Lpuart_Lin_Ip_PduType tx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_TX,
			.Dl = 8,
			.SduPtr = tx_linSdu
	};

	Lpuart_Lin_Ip_PduType rx_lin_pdu = {
			.Cs = LPUART_LIN_IP_ENHANCED_CS,
			.Drc = LPUART_LIN_IP_FRAMERESPONSE_RX,
			.Dl = 8
	};
	(void)rx_lin_pdu;

	/* make PID with frame ID */
	tx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_SLAVE_RECEIVE_DATA_ID4, LIN_IP_MAKE_PARITY);
	rx_lin_pdu.Pid = Lin_Ip_ProcessParity(FRAME_MASTER_RECEIVE_DATA_ID4, LIN_IP_MAKE_PARITY);

	status = LIN_Frame_Transmit(TJA1124_CH4_LIN_INST,&tx_lin_pdu);

#ifdef TJA1124_LIN_CH4_RECV_ENABLE
	/* send slave response LIN message frame via TJA1124 LIN1 and wait for slave response */
	LIN_Frame_Receive(TJA1124_CH4_LIN_INST, &rx_lin_pdu);
	/* print the received LIN frame */
	LIN_Frame_Print(&rx_lin_pdu);
#endif

}
