/***********************************************************************************************************************
* Copyright (C) All rights reserved.
***********************************************************************************************************************/

/***********************************************************************************************************************
* @file    can_user.c
* @brief   This file implements device driver for CAN module.
* @version 1.0.0
* @date    2019/12/24
***********************************************************************************************************************/

/***********************************************************************************************************************
Includes
***********************************************************************************************************************/
#include <stdio.h>
#include "userdefine.h"
#include "BAT32A239.h"
#include "can.h"

/* Start user code for include. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
Pragma directive
***********************************************************************************************************************/
void IRQ23_Handler(void) __attribute__((alias("CAN0Rec_Interrupt")));
void IRQ25_Handler(void) __attribute__((alias("CAN0Trx_Interrupt")));
void IRQ24_Handler(void) __attribute__((alias("CAN0Wup_Interrupt")));
void IRQ09_Handler(void) __attribute__((alias("CAN0Err_Interrupt")));

/***********************************************************************************************************************
Global variables and functions
***********************************************************************************************************************/
CANMSG_REC_Type MsgRec[16];
uint32_t RxCount;

static void CAN0Rec_Handler(void);
static void CAN0Trx_Handler(void);
static void CAN0Wup_Handler(void);
static void CAN0Err_Handler(void);

/* Start user code for global. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
/***********************************************************************************************************************
* Function Name: MsgRec_Clr
* @brief  This function Clear the Message Data.
* @param  pMsg_Rec - the pointer of Receive Message
* @return None
***********************************************************************************************************************/
void MsgRec_Clr(CANMSG_REC_Type* pMsg_Rec)
{
	uint32_t i,j;
	uint8_t* pMsgDat;
	CANMSG_REC_Type* pTMsg;
	
	for(j=0;j<sizeof(MsgRec)/sizeof(CANMSG_REC_Type);j++)
	{
		pTMsg = pMsg_Rec+j;
		pMsgDat = (uint8_t*)pTMsg;
		for(i=0;i<sizeof(CANMSG_REC_Type);i++)
		{
			pMsgDat[i] = 0;
		}
	}
}
/***********************************************************************************************************************
* Function Name: CAN0Rec_Interrupt
* @brief  CAN0 reception interrupt service routine
* @param  None
* @return None
***********************************************************************************************************************/
void CAN0Rec_Interrupt(void)
{
    INTC_ClearPendingIRQ(CAN0REC_IRQn);
    if(CAN->C0INTS & INTS_RX_READ)
    {
        CAN->C0INTS = INTS_RX_CLR;
        CAN0Rec_Handler();
    }
}

/***********************************************************************************************************************
* Function Name: CAN0Trx_Interrupt
* @brief  CAN0 transmission interrupt service routine
* @param  None
* @return None
***********************************************************************************************************************/
void CAN0Trx_Interrupt(void)
{
    INTC_ClearPendingIRQ(CAN0TRX_IRQn);
    if(CAN->C0INTS & INTS_TX_READ)
    {
        CAN->C0INTS = INTS_TX_CLR;
        CAN0Trx_Handler();
    }
}

/***********************************************************************************************************************
* Function Name: CAN0Wup_Interrupt
* @brief  CAN0 wakeup interrupt service routine
* @param  None
* @return None
***********************************************************************************************************************/
void CAN0Wup_Interrupt(void)
{
    INTC_ClearPendingIRQ(CAN0WUP_IRQn);
    if(CAN->C0INTS & INTS_WK_READ)
    {
	    CAN->C0INTS = INTS_WK_CLR;
        CAN0Wup_Handler();
    }
}

/***********************************************************************************************************************
* Function Name: CAN0Err_Interrupt
* @brief  CAN error interrupt service routine
* @param  None
* @return None
***********************************************************************************************************************/
void CAN0Err_Interrupt(void)
{
    INTC_ClearPendingIRQ(CAN0ERR_IRQn);
    if(CAN->C0INTS & (INTS_ERR_READ|INTS_PERR_READ|INTS_AL_READ))
    {
        //printf("INTS 0x%04x\n",CAN->C0INTS);
        CAN->C0INTS = INTS_ERR_CLR|INTS_PERR_CLR|INTS_AL_CLR;
        CAN0Err_Handler();
    }
		
}


/***********************************************************************************************************************
* Function Name: CAN0Rec_Handler
* @brief  This function is CAN0 Receive handler.
* @param  None
* @return None
***********************************************************************************************************************/
static void CAN0Rec_Handler(void)
{
	CANMSG_Type* pCMsg;
	uint8_t* pMdb;
	uint32_t rgpt;
	uint8_t msgnum,i;
	
	rgpt = CAN->C0RGPT;
	
  if(rgpt&RGPT_ROVF_READ)
	{
		CAN->C0RGPT = RGPT_ROVF_CLR;
	}
	
	while(!(rgpt&RGPT_RHPM_READ))
	{
		msgnum = (rgpt>>8)&0x0f;
		pCMsg = (CANMSG_Type*)CANMSG00+msgnum;
		
		pCMsg->C0MCTRL = MCTRL_DN_CLR;//clear DN
		MsgRec[msgnum].Id = (pCMsg->C0MIDH<<16)|(pCMsg->C0MIDL);
		MsgRec[msgnum].Dlc = pCMsg->C0MDLC;
		pMdb = (uint8_t*)&(pCMsg->C0MDB0);
		for(i=0;i<MsgRec[msgnum].Dlc;i++)
		{
			MsgRec[msgnum].Msgbuff[i] = pMdb[i];
		}
		
		MsgRec[msgnum].MsgStatus = 1;
		RxCount++;
		if((MsgRec[msgnum].Id&0x07ff)==0x702)
		{
			PORT->P7 ^= 0x06U;
		}
//		printf("RxCount %d\n",++RxCount);
//		printf("Receive a message buffer%d\n",msgnum);
//		
//		printf("ID 0x%08x\n",MsgRec[msgnum].Id);
//		printf("DLC %d\n",MsgRec[msgnum].Dlc);
//		for(i=0;i<MsgRec[msgnum].Dlc;i++)
//		{
//			printf("Data%d 0x%02x\n",i,MsgRec[msgnum].Msgbuff[i]);
//		}
		
		rgpt = CAN->C0RGPT;
	}
	 
}
/***********************************************************************************************************************
* Function Name: CAN0Trx_Handler
* @brief  This function is CAN0 Transmit handler.
* @param  None
* @return None
***********************************************************************************************************************/
static void CAN0Trx_Handler(void)
{
   
}
/***********************************************************************************************************************
* Function Name: CAN0Wup_Handler
* @brief  This function is CAN0 Wake up handler.
* @param  None
* @return None
***********************************************************************************************************************/
static void CAN0Wup_Handler(void)
{
   
}
/***********************************************************************************************************************
* Function Name: CAN0Err_Handler
* @brief  This function is CAN0 Error handler.
* @param  None
* @return None
***********************************************************************************************************************/
static void CAN0Err_Handler(void)
{
   
}

/* Start user code for adding. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */