#include "common_include.h"


void          Copy_RamToRxBuf(stc_canfd_msg_t* stc_msg,uint8_t* msg,uint8_t dlc);
en_result_t    Can_PrescalerInit( volatile stc_canp_t* pstcCanp,uint8_t u8CanPrescaler,boolean_t bSelectMainClock);
en_result_t    CanFD_UpdateAndTransmitMsgBuffer(pstc_canfd_type_t pstcCanFD,uint8_t u8MsgBuf,stc_canfd_msg_t* pstcMsgData);
en_result_t    CanFD_Config( pstc_canfd_type_t pstcCanFD, stc_canfd_config_t* pstcConfig ,stc_canfd_standardFilter_t* standFilter_config);
uint32_t*      calcTxBufAdrs(pstc_canfd_type_t pstcCanFD,uint8_t u8MsgBuf);
uint32_t*      calcRxBufAdrs(pstc_canfd_type_t pstcCanFD,uint8_t u8MsgBuf);
stc_canfd_intern_data_t*  CanFDGetInternDataPtr(pstc_canfd_type_t pstcCanFD);
void CAN0_NACK_handle(void);
void CAN1_NACK_handle(void);

void bsp_HDOG_Feed(void);

volatile    uint8_t   Can0_busoffTime = 0;

enum CanAckInfo
{
    Can_ACK = 0,
    Can_NACK
};

volatile    enum     CanAckInfo   Can0_AckState = Can_ACK;  /* qitiancun 2018-9-14 */
volatile    enum     CanAckInfo   Can1_AckState = Can_ACK;  /* qitiancun 2018-9-14 */

/*-------------------------------------------------------------------------
* Function Name  : CAN0_Rx_CallBack
* Description    : CANFD??????????????CAN?��?????????,??????????
* Input          : BufferNumber ?????stc_msg:?��???????????????????
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN0_Rx_CallBack(uint8_t BufferNumber,stc_canfd_msg_t* stc_msg)
{
  
    CheckRecvCan0Frame(stc_msg);
  
}

void CAN0_NACK_handle(void)
{
//    SendCanMessage20msTimer = Timer1msCnts;
//    SendCanMessage100msTimer = Timer1msCnts;
//    SendCanMessage200msTimer = Timer1msCnts;
//    SendCanMessage1000msTimer = Timer1msCnts;
}



/*-------------------------------------------------------------------------
*Function:       : CAN0_Tx_CallBack
*Description:    : CANFD???????????CAN?��?????????,??????????
Input:          //
*Output:         : ??
*Return:         : ??
*Others:         :
--------------------------------------------------------------------------*/
void CAN0_Tx_CallBack(void)
{
    if(Can0_AckState == Can_NACK)  /* qitiancun 2018-9-14 */
    {
        Can0_AckState = Can_ACK;
        
        CAN0_NACK_handle();
        
        bsp_tx_msgbuf_abort( 0 );
    }
}

/*-------------------------------------------------------------------------
* Function Name  : CAN0_Wakup_CallBack
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
static void CAN0_Wakup_CallBack(uint8_t channel)
{
    Eic_Disable((stc_eic00_t *) &EIC00, 4);
}

/*-------------------------------------------------------------------------
* Function Name  : CAN0_Error_CallBack
* Description    : CAN ?????��???????
* Input          : en_canfd_err ????????
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN0_Error_CallBack(en_canfd_error_t en_canfd_err)
{
    
}

/*-------------------------------------------------------------------------
* Function Name  : CAN0_FIFO_0_CallBack
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN0_FIFO_0_CallBack(uint8_t BufferNumber,stc_canfd_msg_t* stc_msg)
{
    
}

/*-------------------------------------------------------------------------
* Function Name  : CAN0_Wakup_Init
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN0_Wakup_Init(void)
{
    stc_port_pin_config_t stc_port_pin_config0_25= { .enOutputFunction      = PortOutputResourceGPIO,
        .enOutputDrive         = PortOutputDriveA,
        .enPullResistor        = PortPullResistorNone,
        .enInputLevel          = PortInputLevelCmosA,
        .bInputEnable          = TRUE,
        .bNoiseFilterEnable    = FALSE,
        .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow};
    Port_SetPinConfig( 0, 25, &stc_port_pin_config0_25 );
    
    stc_eic_config_t      stcEicConfig;
    // EIC Configuration
    stcEicConfig.enRequestEvent               = EicRisingEdge;          // Detect rising edge
    stcEicConfig.bInputNoiseFilterEnable      = TRUE;                   // Enable the noise filter
    stcEicConfig.bDmaRequestEnable            = FALSE;                  // Disable the DMA request
    stcEicConfig.pfnCallback                  = &CAN0_Wakup_CallBack;   // using interrupts
    
    Port_SelectInputPort( &RIC.unRESIN255, PortInputPortA );
    
    Eic_Init((stc_eic00_t *) &EIC00, 4, &stcEicConfig);
    
    Eic_Enable((stc_eic00_t *) &EIC00, 4);
    
    Port_EnableInput();
}


/*-------------------------------------------------------------------------
* Function Name  : CAN1_Rx_CallBack
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN1_Rx_CallBack(uint8_t BufferNumber,stc_canfd_msg_t* stc_msg)
{
   CheckRecvCan1Frame(stc_msg);
 //  Flag_BCanWakeup = 1;
}

/*-------------------------------------------------------------------------
*Function:       : CAN1_NACK_handle
*Description:    : 
Input:          //
*Output:         : ??
*Return:         : ??
*Others:         :
--------------------------------------------------------------------------*/
void CAN1_NACK_handle(void)
{
    //AppMsgTime.App1DFTime = 0;
}

/*-------------------------------------------------------------------------
*Function:       : CAN1_Tx_CallBack
*Description:    : CANFD???????????CAN?��?????????,??????????
*Input:          :
*Output:         : ??
*Return:         : ??
*Others:         : ???????
--------------------------------------------------------------------------*/
void CAN1_Tx_CallBack(void)
{
    NM_TranMsgSuccessDetect();
    if(Can1_AckState == Can_NACK)  /* qitiancun 2018-9-14 */
    {
        Can1_AckState = Can_ACK;
        
        CAN1_NACK_handle();
        
        bsp_tx_msgbuf_abort( 1 ); 
    }
}

/*-------------------------------------------------------------------------
* Function Name  : CAN1_Wakup_CallBack
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
static void CAN1_Wakup_CallBack(uint8_t channel)
{
    Eic_Disable((stc_eic00_t *) &EIC00, 6);
    TalkNM( );
    NM_RemoteWakeup_Fun( );
  //  Flag_BCanWakeup = 1;
}

/*-------------------------------------------------------------------------
*Function:       : CAN1_Error_CallBack
*Description:    : CAN ?????��???????
*Input:          : en_canfd_err ????????
*Output:         : ??
*Return:         : ??
*Others:         : ???????
--------------------------------------------------------------------------*/
void CAN1_Error_CallBack(en_canfd_error_t en_canfd_err)
{
    NM_TranMsgErrorDetect();
}

/*-------------------------------------------------------------------------
* Function Name  : CAN1_FIFO_0_CallBack
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN1_FIFO_0_CallBack(uint8_t BufferNumber,stc_canfd_msg_t* stc_msg)
{
    uint8_t w_RevMsg[ 8 ];
    
    if((NetWorkStatus.NMactive == NM_Passive) )//|| (UdsParameter.CommNMMessageDisableRx == 1))
    {
        return;
    }
    
    Copy_RxBufToRam((uint8_t*)(&w_RevMsg[ 0 ]),(stc_canfd_msg_t*)stc_msg);
    NM_Receive_isr_Fun(stc_msg->stcIdentifier.u32Identifier,&w_RevMsg[ 0 ]);
}


/*-------------------------------------------------------------------------
* Function Name  : CAN1_Wakup_Init
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CAN1_Wakup_Init(void)
{
    //ERR
    stc_port_pin_config_t stc_port_pin_config2_09 = { .enOutputFunction      = PortOutputResourceGPIO,
        .enOutputDrive         = PortOutputDriveA,
        .enPullResistor        = PortPullResistorNone,
        .enInputLevel          = PortInputLevelCmosA,
        .bInputEnable          = TRUE,
        .bNoiseFilterEnable    = FALSE,
        .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow};
    Port_SetPinConfig( 2, 9, &stc_port_pin_config2_09 );
    
    //RXQ
    stc_port_pin_config_t stc_port_pin_config0_27= { .enOutputFunction      = PortOutputResourceGPIO,
        .enOutputDrive         = PortOutputDriveA,
        .enPullResistor        = PortPullResistorNone,
        .enInputLevel          = PortInputLevelCmosA,
        .bInputEnable          = TRUE,
        .bNoiseFilterEnable    = FALSE,
        .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow};
    Port_SetPinConfig( 0, 27, &stc_port_pin_config0_27 );
    
    Port_EnableInput();
    
 //  Flag_BCanWakeup = 0;

    stc_eic_config_t      stcEicConfig;
    // EIC Configuration
    stcEicConfig.enRequestEvent               = EicFallingEdge;          // Detect rising edge
    stcEicConfig.bInputNoiseFilterEnable      = TRUE;                   // Enable the noise filter
    stcEicConfig.bDmaRequestEnable            = FALSE;                  // Disable the DMA request
    stcEicConfig.pfnCallback                  = &CAN1_Wakup_CallBack;   // using interrupts
    
    Port_SelectInputPort( &RIC.unRESIN257, PortInputPortA );
    
    Eic_Init((stc_eic00_t *) &EIC00, 6, &stcEicConfig);
    
    Eic_Enable((stc_eic00_t *) &EIC00, 6);
}

/*-------------------------------------------------------------------------
* Function Name  : bsp_CAN_Sleep
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void bsp_CAN_Sleep(uint8_t channel)
{
    if(channel == 0)
    {
        CANFD0_Type->unCCCR.stcField.u1INIT = 1;
        if(CPG_CANFD0_CCCR_CSR == 0)
        {
            CPG_CANFD0_CCCR_CSR = 1;
            SetCan0Mode(0);
            CAN0_Wakup_Init();
        }
    }
    
    if(channel == 1)
    {
        CANFD1_Type->unCCCR.stcField.u1INIT = 1;
        if(CPG_CANFD1_CCCR_CSR == 0)
        {
            CPG_CANFD1_CCCR_CSR = 1;
            SetCan1Mode(0);
            CAN1_Wakup_Init();
        }
    }
}

/*-------------------------------------------------------------------------
*Function:       : CanFD_Drive_Init
*Description:    : ????? CAN ???
*Input:          : stc_canfd_standardFilter_t ???????��??????????????????
*                : ?? canfd_320.h ?��??��???????????????�A????20
*Output:         : ??
*Return:         : ??
*Others:         : ???????
--------------------------------------------------------------------------*/
void CanFD_Drive_Init(pstc_canfd_type_t pstcCanFD,stc_canfd_standardFilter_t* filterConfig)
{
    stc_canfd_config_t  m_stc_canfd_config;
    
    m_stc_canfd_config.bCanFDMode = FALSE;
    
    m_stc_canfd_config.stcBitrate.u8SyncJumpWidth = 3;
    if(pstcCanFD == CANFD0_Type) //500K
    {
        m_stc_canfd_config.stcBitrate.u16Prescaler    = 1;
        m_stc_canfd_config.stcBitrate.u8TimeSegment1  = 11;
        m_stc_canfd_config.stcBitrate.u8TimeSegment2  = 2;
        m_stc_canfd_config.pfnRxCallback = &CAN0_Rx_CallBack;
        m_stc_canfd_config.pfnTxCallback = &CAN0_Tx_CallBack;
        m_stc_canfd_config.pfnErrorCallback = &CAN0_Error_CallBack;
        m_stc_canfd_config.pfnRxFIFO_0_Callback = &CAN0_FIFO_0_CallBack;
    }
    else if(pstcCanFD == CANFD1_Type) //100K
    {
        m_stc_canfd_config.stcBitrate.u16Prescaler    = 4;
        m_stc_canfd_config.stcBitrate.u8TimeSegment1  = 11;
        m_stc_canfd_config.stcBitrate.u8TimeSegment2  = 2;
        m_stc_canfd_config.pfnRxCallback = &CAN1_Rx_CallBack;
        m_stc_canfd_config.pfnTxCallback = &CAN1_Tx_CallBack;
        m_stc_canfd_config.pfnErrorCallback = &CAN1_Error_CallBack;
        m_stc_canfd_config.pfnRxFIFO_0_Callback = &CAN1_FIFO_0_CallBack;
    }
    else
    {
        
    }
    CanFD_Config(pstcCanFD, &m_stc_canfd_config, filterConfig);
}

/*-------------------------------------------------------------------------
** \brief Message buffer address calculation for transmission.
**
** \param [in] pstcCanFD           Pointer to register area of a CAN-FD unit.
** \param [in] u8MsgBuf            Message buffer index for transmission.(0-31)

** \retval pulAdrs                 Message buffer address corresponding to the index.
**                                 Can be 0 if the index is invalid.
--------------------------------------------------------------------------*/
uint32_t* calcTxBufAdrs(pstc_canfd_type_t pstcCanFD,uint8_t u8MsgBuf)
{
    uint32_t* pulAdrs;
	
	if(pstcCanFD->unTXFQS.stcField.u6TFFL == 0)
	{
		pulAdrs = NULL;
	}
   	else
	{
    	pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unTXBC.stcField.u14TBSA + (2 + iDlcInWord[pstcCanFD->unTXESC.stcField.u3TBDS]) * pstcCanFD->unTXFQS.stcField.u5TFQPI;
	}
    return pulAdrs;
}


/*---------------------------------------------------------------------------
** \brief Message buffer address calculation for reception.
**
** \param [in] pstcCanFD           Pointer to register area of a CAN-FD unit.
** \param [in] u8MsgBuf            Message buffer index for reception.(0-63)

** \retval pulAdrs                 Message buffer address corresponding to the index.
**                                 Can be 0 if the index is invalid.
---------------------------------------------------------------------------*/
uint32_t* calcRxBufAdrs(pstc_canfd_type_t pstcCanFD,uint8_t u8MsgBuf)
{
    uint32_t* pulAdrs;
    
    if (u8MsgBuf > 63)
    {
        // Set 0 to the return value if the index is invalid
        pulAdrs = 0;
    }
    else
    {
        // Set the message buffer address to the return value if the index is available
        pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unRXBC.stcField.u14RBSA + (2 + iDlcInWord[pstcCanFD->unRXESC.stcField.u3RBDS]) * u8MsgBuf;
    }
    return pulAdrs;
}
/*-------------------------------------------------------------------------
*Function:       : CanFD_chl0_isr
*Description:    : CAN0 ?��????
*Input:          :
*Output:         : ??
*Return:         : ??
*Others:         : ???????
--------------------------------------------------------------------------*/
__irq __arm  void CanFD_chl0_isr(void)
{
    uint32_t*    pulAdrs = 0;
    uint32_t     rxBufIndex = 0x00000001;
    uint16_t     u16count = 0;
    uint16_t     ramCount = 0;
    uint16_t     u16dlcTmp = 0;
    uint16_t     u16MessageBufferNumber;
      
    stc_canfd_intern_data_t*  pstcCanFDInternData;
    pstc_canfd_type_t         pstcCanFD;
    
    stc_canfd_msg_t           stcCanFDmsg;
    stc_canfd_tx_event_t      stcCanFDTxEvent;
    
    pstcCanFD = CANFD0_Type;
    pstcCanFDInternData = &m_astcCanFDInstanceDataLut[CanFDInstanceIndexCanFD0].stcInternData;
    
    // Received a data frame
    if ( pstcCanFD->unIR.stcField.u1DRX == 1 ) // At least one received message stored into an Rx Buffer.
    {
        // Clear the Message stored to Dedicated Rx Buffer flag
        pstcCanFD->unIR.stcField.u1DRX = 1;
        
        // New data is exist
        for(u16count = 0; u16count < 32; u16count ++)
        {
            // Check the message buffer n
            if (pstcCanFD->unNDAT1.u32Register & rxBufIndex)
            {
                u16MessageBufferNumber = u16count;
                // Rx Buffer address
                pulAdrs = calcRxBufAdrs( pstcCanFD, u16MessageBufferNumber );
                // Clear NDAT1 register
                pstcCanFD->unNDAT1.u32Register = rxBufIndex;

                if (pulAdrs)
                {
                    // Save received data
                    // XTD : Extended Identifier
                    stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                        
                    // ID : RxID
                    if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                    }
                    else
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                    }
                    
                    // FDF : Extended Data Length
                    stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                    
                    // DLC : Data Length Code
                    stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                    
                    // Copy 0-64 byte of data area
                    if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                    {
                        u16dlcTmp = 0;
                    }
                    else
                    {
                        u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                    }
                    
                    for ( ramCount = 0; ramCount < iDlcInWord[ u16dlcTmp ]; ramCount++ )
                    {
                        stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                    }
                    
                    // CAN-FD message received, check if there is a callback function
                    // Call callback function if it was set previously.
                    if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction != NULL)
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                    }
                }
            }
            
            if (pstcCanFD->unNDAT2.u32Register & rxBufIndex)
            {
                u16MessageBufferNumber = 32 + u16count;
                // Rx Buffer address
                pulAdrs = calcRxBufAdrs( pstcCanFD, u16MessageBufferNumber );
                // Clear NDAT1 register
                pstcCanFD->unNDAT2.u32Register = rxBufIndex;
                
                if (pulAdrs)
                {
                    // Save received data
                    // XTD : Extended Identifier
                    stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                    
                    // ID : RxID
                    if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                    }
                    else
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                    }
                    
                    // FDF : Extended Data Length
                    stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                    
                    // DLC : Data Length Code
                    stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                    
                    // Copy 0-64 byte of data area
                    if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                    {
                        u16dlcTmp = 0;
                    }
                    else
                    {
                        u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                    }
                    
                    for ( ramCount = 0; ramCount < iDlcInWord[u16dlcTmp]; ramCount++ )
                    {
                        stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                    }
                    
                    // CAN-FD message received, check if there is a callback function
                    // Call callback function if it was set previously.
                    if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction != NULL)
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                    }
                }
            }
            rxBufIndex = rxBufIndex << 1;
        }
    }
    
    if ( pstcCanFD->unIR.stcField.u1RF0N == 1 ) // FIFO 0
    {
        pstcCanFD->unIR.stcField.u1RF0N = 1;
        
        while(pstcCanFD->unRXF0S.stcField.u7F0FL)
        {
            pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unRXF0C.stcField.u14F0SA + (2 + iDlcInWord[pstcCanFD->unRXESC.stcField.u3F0DS]) * pstcCanFD->unRXF0S.stcField.u6F0GI;
            if (pulAdrs)
            {
                stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                
                if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                {
                    stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                }
                else
                {
                    stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                }
                
                stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                
                stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                
                // Copy 0-64 byte of data area
                if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                {
                    u16dlcTmp = 0;
                }
                else
                {
                    u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                }
                
                for ( ramCount = 0; ramCount < iDlcInWord[u16dlcTmp]; ramCount++ )
                {
                    stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                }
                
                // CAN-FD message received, check if there is a callback function
                // Call callback function if it was set previously.
                if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction != NULL)
                {
                    pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                }
                pstcCanFD->unRXF0A.stcField.u6F0AI = pstcCanFD->unRXF0S.stcField.u6F0GI; //1693 page
            }
        }
    }
    
    if ( pstcCanFD->unIR.stcField.u1TEFN == 1 || pstcCanFD->unIR.stcField.u1TEFW == 1|| pstcCanFD->unIR.stcField.u1TC == 1) // Transmission completed.
    {
        pstcCanFD->unIR.stcField.u1TEFN = 1;
        pstcCanFD->unIR.stcField.u1TEFW = 1;
        pstcCanFD->unIR.stcField.u1TC = 1;
        // CAN-FD message succesfully transmitted.
        // Call callback function if it was set previously.
        while(pstcCanFD->unTXEFS.stcField.u6EFFL)
        {
            pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unTXEFC.stcField.u14EFSA + 2 * pstcCanFD->unTXEFS.stcField.u5EFGI;
            if (pulAdrs)
            {
                stcCanFDTxEvent = *((stc_canfd_tx_event_t *) pulAdrs);
                memcpy(&stcCanFDTxEvent, (void *)pulAdrs, sizeof(stc_canfd_tx_event_t));
                if ( stcCanFDTxEvent.E0_f.XTD == FALSE )
                {
                    stcCanFDTxEvent.E0_f.ID = ((stc_canfd_tx_event_t *) pulAdrs)->E0_f.ID >> 18;
                }
                else
                {
                    stcCanFDTxEvent.E0_f.ID = ((stc_canfd_tx_event_t *) pulAdrs)->E0_f.ID;
                }
				
		        if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDTxInterruptFunction != NULL)
		        {
		            pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDTxInterruptFunction();
		        }
                
                pstcCanFD->unTXEFA.stcField.u5EFAI = pstcCanFD->unTXEFS.stcField.u5EFGI; //1693 page
            }
        }
    }
    else if ( pstcCanFD->unIR.stcField.u1PEA ) //Protocol Error in Arbitration Phase
    {
        pstcCanFD->unIR.stcField.u1PEA = 1;
        
        if(pstcCanFD->unPSR.stcField.u3LEC == 3)  /* qitiancun 2018-9-14 */
        {
            Can0_AckState = Can_NACK;
        }
        
        if (pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction != NULL)
        {
            pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction(CanFDWarning);
        }
    }
    else if ( pstcCanFD->unIR.stcField.u1PED ) //Protocol Error in Data Phase
    {
        pstcCanFD->unIR.stcField.u1PED = 1;
        if (pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction != NULL)
        {
            pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction(CanFDWarning);
        }
    }
    IRC0_IRQHC = INTERRUPTS_IRQ_NUMBER_40;
}

/*-------------------------------------------------------------------------
*Function:       : CanFD_chl1_isr
*Description:    : CAN1 ?��????
*Input:          :
*Output:         : ??
*Return:         : ??
*Others:         : ???????
--------------------------------------------------------------------------*/
__irq __arm void CanFD_chl1_isr(void)
{
    uint32_t*    pulAdrs = 0;
    uint32_t     rxBufIndex = 0x00000001;
    uint16_t     u16count = 0;
    uint16_t     ramCount = 0;
    uint16_t     u16dlcTmp = 0;
    uint16_t     u16MessageBufferNumber;
    
    stc_canfd_intern_data_t*  pstcCanFDInternData;
    pstc_canfd_type_t         pstcCanFD;
    
    stc_canfd_msg_t           stcCanFDmsg;
    stc_canfd_tx_event_t      stcCanFDTxEvent;
    
    pstcCanFD = CANFD1_Type;
    pstcCanFDInternData = &m_astcCanFDInstanceDataLut[CanFDInstanceIndexCanFD1].stcInternData;
    // Received a data frame
    if ( pstcCanFD->unIR.stcField.u1DRX == 1 ) // At least one received message stored into an Rx Buffer.
    {
        // Clear the Message stored to Dedicated Rx Buffer flag
        pstcCanFD->unIR.stcField.u1DRX = 1;
        
        // New data is exist
        for(u16count = 0; u16count < 32; u16count ++)
        {
            // Check the message buffer n
            if (pstcCanFD->unNDAT1.u32Register & rxBufIndex)
            {
                u16MessageBufferNumber = u16count;
                // Rx Buffer address
                pulAdrs = calcRxBufAdrs( pstcCanFD, u16MessageBufferNumber );
                // Clear NDAT1 register
                pstcCanFD->unNDAT1.u32Register = rxBufIndex;
                
                if (pulAdrs)
                {
                    // Save received data
                    // XTD : Extended Identifier
                    stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                    
                    // ID : RxID
                    if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                    }
                    else
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                    }
                    
                    // FDF : Extended Data Length
                    stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                    
                    // DLC : Data Length Code
                    stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                    
                    // Copy 0-64 byte of data area
                    if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                    {
                        u16dlcTmp = 0;
                    }
                    else
                    {
                        u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                    }
                    
                    for ( ramCount = 0; ramCount < iDlcInWord[u16dlcTmp]; ramCount++ )
                    {
                        stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                    }
                    
                    // CAN-FD message received, check if there is a callback function
                    // Call callback function if it was set previously.
                    if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction != NULL)
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                    }
                }
            }
            else if (pstcCanFD->unNDAT2.u32Register & rxBufIndex)
            {
                u16MessageBufferNumber = 32 + u16count;
                // Rx Buffer address
                pulAdrs = calcRxBufAdrs( pstcCanFD, u16MessageBufferNumber );
                // Clear NDAT2 register
                pstcCanFD->unNDAT2.u32Register = rxBufIndex;

                if (pulAdrs)
                {
                    // Save received data
                    // XTD : Extended Identifier
                    stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                        
                    // ID : RxID
                    if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                    }
                    else
                    {
                        stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                    }
                    
                    // FDF : Extended Data Length
                    stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                    
                    // DLC : Data Length Code
                    stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                    
                    // Copy 0-64 byte of data area
                    if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                    {
                        u16dlcTmp = 0;
                    }
                    else
                    {
                        u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                    }
                    
                    for ( ramCount = 0; ramCount < iDlcInWord[u16dlcTmp]; ramCount++ )
                    {
                        stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                    }
                    
                    // CAN-FD message received, check if there is a callback function
                    // Call callback function if it was set previously.
                    if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction != NULL)
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                    }
                }
            }
            rxBufIndex = rxBufIndex << 1;
        }
    }
    
    if ( pstcCanFD->unIR.stcField.u1RF0N == 1 ) // FIFO 0
    {
        pstcCanFD->unIR.stcField.u1RF0N = 1;
        while(pstcCanFD->unRXF0S.stcField.u7F0FL)
        {
            pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unRXF0C.stcField.u14F0SA + (2 + iDlcInWord[pstcCanFD->unRXESC.stcField.u3F0DS]) * pstcCanFD->unRXF0S.stcField.u6F0GI;
            if (pulAdrs)
            {
                stcCanFDmsg.stcIdentifier.bExtended = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.XTD;
                
                if ( stcCanFDmsg.stcIdentifier.bExtended == FALSE )
                {
                    stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID >> 18;
                }
                else
                {
                    stcCanFDmsg.stcIdentifier.u32Identifier = ((stc_canfd_rx_buffer_t *) pulAdrs)->R0_f.ID;
                }
                
                stcCanFDmsg.bCanFDFormat = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.FDF;
                
                stcCanFDmsg.stcData.u8DataLengthCode = ((stc_canfd_rx_buffer_t *) pulAdrs)->R1_f.DLC;
                
                if ( stcCanFDmsg.stcData.u8DataLengthCode < 8 )
                {
                    u16dlcTmp = 0;
                }
                else
                {
                    u16dlcTmp = stcCanFDmsg.stcData.u8DataLengthCode - 8;
                }

                for ( ramCount = 0; ramCount < iDlcInWord[u16dlcTmp]; ramCount++ )
                {
                    stcCanFDmsg.stcData.au32Data[ ramCount ] = ((stc_canfd_rx_buffer_t *) pulAdrs)->DATA_AREA_f[ ramCount ];
                }
                if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxFIFO_0_InterruptFunction != NULL)
                {
                    if(stcCanFDmsg.stcIdentifier.u32Identifier >= 0x500 && stcCanFDmsg.stcIdentifier.u32Identifier <= 0x5FF)
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxFIFO_0_InterruptFunction((uint8_t)0, &stcCanFDmsg);
                    }
                    else
                    {
                        pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction((uint8_t)u16MessageBufferNumber, &stcCanFDmsg);
                    }
                }
                pstcCanFD->unRXF0A.stcField.u6F0AI = pstcCanFD->unRXF0S.stcField.u6F0GI; //1693 page
            }
        }
    }
    
    if ( pstcCanFD->unIR.stcField.u1TEFN == 1 || pstcCanFD->unIR.stcField.u1TEFW == 1|| pstcCanFD->unIR.stcField.u1TC == 1) // Transmission completed.
    {
        pstcCanFD->unIR.stcField.u1TEFN = 1;
        pstcCanFD->unIR.stcField.u1TEFW = 1;
        pstcCanFD->unIR.stcField.u1TC = 1;
        // CAN-FD message succesfully transmitted.
        // Call callback function if it was set previously.
        while(pstcCanFD->unTXEFS.stcField.u6EFFL)
        {
            pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unTXEFC.stcField.u14EFSA + 2 * pstcCanFD->unTXEFS.stcField.u5EFGI;
            if (pulAdrs)
            {
                stcCanFDTxEvent = *((stc_canfd_tx_event_t *) pulAdrs);
                memcpy(&stcCanFDTxEvent, (void *)pulAdrs, sizeof(stc_canfd_tx_event_t));
                if ( stcCanFDTxEvent.E0_f.XTD == FALSE )
                {
                    stcCanFDTxEvent.E0_f.ID = ((stc_canfd_tx_event_t *) pulAdrs)->E0_f.ID >> 18;
                }
                else
                {
                    stcCanFDTxEvent.E0_f.ID = ((stc_canfd_tx_event_t *) pulAdrs)->E0_f.ID;
                }
				
		        if (pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDTxInterruptFunction != NULL)
		        {
		            pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDTxInterruptFunction();
		        }
                
                pstcCanFD->unTXEFA.stcField.u5EFAI = pstcCanFD->unTXEFS.stcField.u5EFGI; //1693 page
            }
        }
        if (MMCanBusOffCnts) {
            MMCanBusOffCnts = 0;
        }
    }
    else if ( pstcCanFD->unIR.stcField.u1PEA ) //Protocol Error in Arbitration Phase
    {
        pstcCanFD->unIR.stcField.u1PEA = 1;

        if(pstcCanFD->unPSR.stcField.u3LEC == 3)  /* qitiancun 2018-9-14 */
        {
            Can1_AckState = Can_NACK;
        }
        if (pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction != NULL)
        {
            pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction(CanFDWarning);
        }
    }
    else if ( pstcCanFD->unIR.stcField.u1PED ) //Protocol Error in Data Phase
    {
        pstcCanFD->unIR.stcField.u1PED = 1;
        if (pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction != NULL)
        {
            pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction(CanFDWarning);
        }
    }
    IRC0_IRQHC = INTERRUPTS_IRQ_NUMBER_41;
}

/*-------------------------------------------------------------------------
* Function Name  : CanFD_0_Busoff_Recover
* Description    : CAN CH0 BusOff???????
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void CanFD_0_Busoff_Recover(void)
{
    if(CANFD0_Type->unPSR.stcField.u1BO) //CHECK BUSOFF EVENT
    {
        if(Can0_busoffTime == 0)
        {
            Can0_busoffTime = 37;
            
            bsp_tx_msgbuf_abort(0);
            //App_C_CAN_SendInit();
            CANFD0_Type->unCCCR.stcField.u1INIT = 0;
        }
        if(Can0_busoffTime > 0)
        {
            Can0_busoffTime --;
        }
    }
    else
    {
        Can0_busoffTime = 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : bsp_tx_msgbuf_abort
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : qitiancun 2018-9-14
--------------------------------------------------------------------------*/
void bsp_tx_msgbuf_abort(uint8_t channel)
{
    if(channel == 0)
    {
        CPG_CANFD0_TXBCR = 0xFFFFFFFF;
    }
    if(channel == 1)
    {
        CPG_CANFD1_TXBCR = 0xFFFFFFFF;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : Copy_RxBufToRam
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void Copy_RxBufToRam(uint8_t* msg,stc_canfd_msg_t* stc_msg)
{
    uint8_t count = 0;
    for(count = 0; count < stc_msg->stcData.u8DataLengthCode;count++)
    {
        if(count < 4)
        {
            msg[ count ] = (stc_msg->stcData.au32Data[0] >> (count * 8));
        }
        else
        {
            msg[ count ] = (stc_msg->stcData.au32Data[1] >> ((count - 4) * 8));
        }
    }
}


static uint8_t GetCanFDLen(uint8_t len)
{
    if (len <= 8) {
        return len;
    } else if (len == 12) {
        return 9;
    } else if (len == 16) {
        return 10;
    } else if (len == 20) {
        return 11;
    } else if (len == 24) {
        return 12;
    } else if (len == 32) {
        return 13;
    } else if (len == 48) {
        return 14;
    } else if (len == 64) {
        return 15;
    } else {
        return 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : Copy_RamToRxBuf
* Description    : ?? RAM ?????? COPY ?? stc_canfd_msg_t ?? word ????????
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void Copy_RamToRxBuf(stc_canfd_msg_t* stc_msg,uint8_t* msg,uint8_t dlc)
{
    uint8_t count = 0;
    stc_msg->stcData.u8DataLengthCode = dlc;
    stc_msg->stcData.au32Data[ 0 ] = 0;
    stc_msg->stcData.au32Data[ 1 ] = 0;
    for(count = dlc; count > 0; count--)
    {
        if(count >= 5)
        {
            stc_msg->stcData.au32Data[ 1 ] <<=  8;
            stc_msg->stcData.au32Data[ 1 ] |= msg[ count - 1 ];
        }
        else
        {
            stc_msg->stcData.au32Data[ 0 ] <<=  8;
            stc_msg->stcData.au32Data[ 0 ] |= msg[ count - 1 ];
        }
    }
}


/*****************************************************************************
** \brief Updates the message data of a message buffer and start transmission.
** Transmits the message immediately.
** Function CanFD_Init() must be called before setup the identifier and enable
** this message buffer.
**
** \param [in] pstcCanFD             Pointer to register area of a CAN-FD unit.
** \param [in] bufIndex              Message buffer index (0-31)
** \param [in] pstcMsg               CAN-FD message data
**
** \retval Ok                        Message buffer has been succesfully updated.
** \retval ErrorInvalidParameter     If one of the following conditions are met:
**   - pstcCanFD == NULL
**   - pstcMsg == NULL
**   - pstcCanFDTxBuffer == NULL
*****************************************************************************/
en_result_t CanFD_UpdateAndTransmitMsgBuffer( pstc_canfd_type_t pstcCanFD,uint8_t bufIndex,stc_canfd_msg_t* pstcMsg)
{
    stc_canfd_intern_data_t* pstcCanFDInternData; // Pointer to internal data
    stc_canfd_tx_buffer_t*   pstcCanFDTxBuffer;
    uint8_t    u8DataLengthWord;
    uint16_t   u16count;
    uint16_t   u16dlcTmp;
    
    uint32_t   Index;
    
    // Check for NULL pointers
    if ( pstcCanFD     == NULL ||  pstcMsg == NULL )
    {
        return ErrorInvalidParameter;
    }
    
    // Get pointer to internal data structure
    pstcCanFDInternData = CanFDGetInternDataPtr( pstcCanFD );
    
    // Check for NULL */
    if ( pstcCanFDInternData == NULL )
    {
        return ErrorInvalidParameter;
    }
    
    // Get Tx Buffer address
    pstcCanFDTxBuffer = (stc_canfd_tx_buffer_t *)(calcTxBufAdrs( pstcCanFD, bufIndex ));
    if ( pstcCanFDTxBuffer == NULL )
    {
        return ErrorInvalidParameter;
    }
    
    //Set data to Tx buffer
    pstcCanFDTxBuffer->T0_f.ESI = 0;
    pstcCanFDTxBuffer->T0_f.RTR = 0; //Transmit data frame.
    pstcCanFDTxBuffer->T0_f.XTD = (pstcMsg->stcIdentifier.bExtended == TRUE) ? 1 : 0;
    pstcCanFDTxBuffer->T0_f.ID  = (pstcCanFDTxBuffer->T0_f.XTD == 0) ? (pstcMsg->stcIdentifier.u32Identifier << 18) : pstcMsg->stcIdentifier.u32Identifier;
    pstcCanFDTxBuffer->T1_f.EFC = 1; // Store Tx event FIFO
    pstcCanFDTxBuffer->T1_f.MM  = 1; // Not used
    pstcCanFDTxBuffer->T1_f.DLC = pstcMsg->stcData.u8DataLengthCode;
    pstcCanFDTxBuffer->T1_f.FDF = (pstcMsg->bCanFDFormat == TRUE) ? 1 : 0;
    pstcCanFDTxBuffer->T1_f.BRS = (pstcMsg->bCanFDFormat == TRUE) ? 1 : 0;
    
    //Convert the DLC to data byte word
    if ( pstcMsg->stcData.u8DataLengthCode < 8 )
    {
        u16dlcTmp = 0;
    }
    else
    {
        u16dlcTmp = pstcMsg->stcData.u8DataLengthCode - 8;
    }
    u8DataLengthWord = iDlcInWord[u16dlcTmp];
    
    // Data set
    for ( u16count = 0;  u16count < u8DataLengthWord; u16count++ )
    {
        pstcCanFDTxBuffer->DATA_AREA_f[u16count] = pstcMsg->stcData.au32Data[u16count];
    }
    
    // Request to transmit
    Index = (0x00000001 << (pstcCanFD->unTXFQS.stcField.u5TFQPI));
    pstcCanFD->unTXBAR.u32Register = Index; // request for buffer 0
    
    if(pstcCanFD == CANFD1_Type)
    {
        NM_LAST_ID = pstcMsg->stcIdentifier.u32Identifier;
        
        if(NM_LAST_ID == NM_CAN_CHL_ID)
        {
            NM_Time.NM_CheckTime = 0;
            NM_D_Offline(  );
        }
    }
    
    return Ok;
}


/*-------------------------------------------------------------------------
* Function Name  : CanFD_Send_StandMsg
* Description    : ???????????
* Input          : pstcCanFD: CANFDn_Type (n= 0~5)
*                : id :11bit?????
*                : bufIndex: ???? BUF ???
*                : msg:????????
*                : dlc: ?????????
*                : tx_isr_en ??????BUF?????��?
* Output         : None
* Return         : None
* onther         : ????:CanFD_Send_StandMsg(CANFD0_Type,0x120,BUF_0,TX_ISR_EN,msg,8);
--------------------------------------------------------------------------*/
uint8_t SendBufferIndex = 0;
void CanFD_Send_StandMsg(pstc_canfd_type_t pstcCanFD,uint32_t id,uint8_t bufIndex,uint8_t tx_isr_en,uint8_t* msg,uint8_t dlc)
{
    //if(UdsControl.Service28_Valid)
    //{
    //    return;
    //}
    stc_canfd_msg_t  m_stc_sendMsg;
  
    SendBufferIndex ++;
    if (SendBufferIndex >= 43) {
        SendBufferIndex = 0;
    }
    bufIndex = SendBufferIndex;
 
    //TXBTIE
    if(tx_isr_en)
    {
        pstcCanFD->unTXBTIE.u32Register  = 0x00000001 << bufIndex;
    }
    else
    {
        pstcCanFD->unTXBTIE.u32Register  &= ~(0x00000001 << bufIndex);
    }
    if(pstcCanFD == CANFD1_Type)
    {
        m_stc_sendMsg.bCanFDFormat = FALSE; /*????FD??*/
    }
    else if(pstcCanFD == CANFD0_Type)
    {
 
        //m_stc_sendMsg.bCanFDFormat = FALSE; /*????FD??*/
 
 
        m_stc_sendMsg.bCanFDFormat = TRUE; /*????FD??*/
 
    }
    // //else if(pstcCanFD == CANFD2_Type)
    // {
    //     m_stc_sendMsg.bCanFDFormat = FALSE; /*????FD??*/
    // }
    if(id > 0xFFFF)
    {
        m_stc_sendMsg.stcIdentifier.bExtended = TRUE;       //??????????
    }
    else
    {
         m_stc_sendMsg.stcIdentifier.bExtended = FALSE;  
    }
    m_stc_sendMsg.stcIdentifier.u32Identifier = id;
    
    m_stc_sendMsg.stcData.u8DataLengthCode = GetCanFDLen(dlc);
    memset((uint8_t*)m_stc_sendMsg.stcData.au32Data, 0, CanTxBufferDataFieldSize[pstcCanFD->unTXESC.stcField.u3TBDS]); 
    memcpy((uint8_t*)&m_stc_sendMsg.stcData.au32Data, msg, dlc);  
    CanFD_UpdateAndTransmitMsgBuffer( pstcCanFD,bufIndex,&m_stc_sendMsg);
}

/*-------------------------------------------------------------------------
* Function Name  : CanFDGetInternDataPtr
* Description    : ??? stcInternData
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/


stc_canfd_intern_data_t* CanFDGetInternDataPtr(pstc_canfd_type_t pstcCanFD)
{
    uint32_t u32Instance;
    
    for (u32Instance = 0; u32Instance < CANFD_INSTANCE_COUNT; u32Instance++)
    {
        if (pstcCanFD == m_astcCanFDInstanceDataLut[u32Instance].pstcInstance)
        {
            return &m_astcCanFDInstanceDataLut[u32Instance].stcInternData;
        }
    }
    
    return NULL;
}

/**
*****************************************************************************
** \brief Initializes the CAN Prescaler.
**
** This function initialises CAN Prescaler with the parameters
** porvided in the given confdig sturcture.
**
** Initialize the CAN Prescaler before calling CanFD_Init().
** Call the Can_PrescalerInit() in a state in which the CAN-FD is stopped.(CCCR.Init=1)
**
** \param [in] pstcCanp          Pointer to register area of a CAN Prescaler.
** \param [in] u8CanPrescaler    CAN Prescaler parameters.
** \param [in] bSelectMainClock  Source clock selection. (TRUE:Main clock, FALSE:PLL clock)
**
** \retval Ok                    CAN Prescaler has been successfully initialized.
** \retval ErrorInvalidParameter If one of the following conditions are met:
**   - pstcCanp == NULL
-----------------------------------------------------------------*/
en_result_t Can_PrescalerInit( volatile stc_canp_t* pstcCanp,uint8_t u8CanPrescaler,boolean_t bSelectMainClock)
{
    // Check for NULL pointers
    if ( pstcCanp    == NULL )
    {
        return ErrorInvalidParameter;
    }
    
    // Set CAN prescaler
    pstcCanp->unCTR.stcField.u6CANPRE = u8CanPrescaler;
    while( pstcCanp->unSTR.stcField.u1BUSY == 1 )
    {
    }
    
    // Select the source clock of CAN Prescaler
    pstcCanp->unCTR.stcField.u1CPCKS  = (bSelectMainClock == TRUE) ? 1 : 0 ;
    
    return Ok;
}

/*-------------------------------------------------------------------------
* Function Name  : CanFD_Config
* Description    : ???? CanFD_Init???? ???? stc_canfd_standardFilter_t ????????
* Input          : stc_canfd_standardFilter_t ???????��??????????????????
*                : ?? canfd_320_driver.h ?��??��???????????????�A????20
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
en_result_t CanFD_Config( pstc_canfd_type_t pstcCanFD, stc_canfd_config_t* pstcConfig ,stc_canfd_standardFilter_t* standFilter_config)
{
    stc_canfd_intern_data_t* pstcCanFDInternData;
    stc_id_filter_t*         pstcIdFilter;
    stc_extid_filter_t*      pstcExtIdFilter;
    uint32_t*                pulAdrs;
    uint16_t                 u16count;
    
    // Shadow data to avoid RMW and speed up HW access
    un_cpg_canfdn_sidfc_t unSIDFC = { 0 };
    un_cpg_canfdn_xidfc_t unXIDFC = { 0 };
    un_cpg_canfdn_xidam_t unXIDAM = { 0 };
    un_cpg_canfdn_rxf0c_t unRXF0C = { 0 };
    un_cpg_canfdn_rxf1c_t unRXF1C = { 0 };
    un_cpg_canfdn_rxbc_t  unRXBC  = { 0 };
    un_cpg_canfdn_txefc_t unTXEFC = { 0 };
    un_cpg_canfdn_txbc_t  unTXBC  = { 0 };
    un_cpg_canfdn_cccr_t  unCCCR  = { 0 };
    un_cpg_canfdn_nbtp_t  unNBTP  = { 0 };
    un_cpg_canfdn_dbtp_t  unDBTP  = { 0 };
    un_cpg_canfdn_tdcr_t  unTDCR  = { 0 };
    un_cpg_canfdn_gfc_t   unGFC   = { 0 };
    un_cpg_canfdn_rxesc_t unRXESC = { 0 };
    un_cpg_canfdn_txesc_t unTXESC = { 0 };
    un_cpg_canfdn_ie_t    unIE    = { 0 };
    un_cpg_canfdn_ils_t   unILS   = { 0 };
    un_cpg_canfdn_ile_t   unILE   = { 0 };
    un_cpg_canfdn_tscc_t  unTSCC  = { 0 };	
    
    
    // Check for NULL pointers
    if ( pstcCanFD    == NULL || pstcConfig == NULL)
    {
        return ErrorInvalidParameter;
    }
    
    // Get pointer to internal data structure
    pstcCanFDInternData = CanFDGetInternDataPtr( pstcCanFD );
    
    // Check for NULL
    if (pstcCanFDInternData == NULL)
    {
        return ErrorInvalidParameter;
    }
    
    // Set notification callback functions
    pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDTxInterruptFunction = pstcConfig->pfnTxCallback;
    pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxInterruptFunction  = pstcConfig->pfnRxCallback;
    pstcCanFDInternData->stcCanFDInterruptHandling.pfnCanFDRxFIFO_0_InterruptFunction  = pstcConfig->pfnRxFIFO_0_Callback;
    pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDStatusInterruptFunction = pstcConfig->pfnStatusCallback;
    pstcCanFDInternData->stcCanFDNotificationCb.pfnCanFDErrorInterruptFunction  = pstcConfig->pfnErrorCallback;
    
    //Set CCCR.INIT to 1 and wait until it will be updated.
    unCCCR.stcField.u1INIT = 1;
    pstcCanFD->unCCCR.u32Register = unCCCR.u32Register;
    while ( pstcCanFD->unCCCR.stcField.u1INIT != 1 )
    {
    }
    
    // Cancel protection
    unCCCR.stcField.u1CCE = 1;
      
   // Can_PrescalerInit( (stc_canp_t*)&CANP, 3, FALSE ); /*PPL0-80M ???2??-40M??????????????2??????????4????*/
    Can_PrescalerInit( (stc_canp_t*)&CANP, 0, TRUE );   
    pstcCanFD->unCCCR.u32Register = unCCCR.u32Register;
    
    // Set message RAM area
    // Standard ID filter
    unSIDFC.stcField.u8LSS = 128;           // Number of standard Message ID filter elements
    unSIDFC.stcField.u14FLSSA = 0x00000000; // Filter List Standard Start Address
    pstcCanFD->unSIDFC.u32Register = unSIDFC.u32Register;
    
    // Extended ID filter
    unXIDFC.stcField.u7LSE = 0;             // Number of extended Message ID filter elements
    unXIDFC.stcField.u14FLESA = 0x00000080; // Filter List Extended Start Address
    pstcCanFD->unXIDFC.u32Register = unXIDFC.u32Register;
    
    unXIDAM.stcField.u29EIDM = 0x1fffffff;  // not filtering(inituial value)
    pstcCanFD->unXIDAM.u32Register = unXIDAM.u32Register;
    
    // Rx FIFO 0 
    unRXF0C.stcField.u1F0OM = 1;    // Rx FIFO 0 overwrite mode
    unRXF0C.stcField.u7F0WM = 0;    // Watermark interrupt disabled
    unRXF0C.stcField.u7F0S = 64;     // FIFO Element Number = 0
    unRXF0C.stcField.u14F0SA = 0x00000100; // offset(word)
    pstcCanFD->unRXF0C.u32Register = unRXF0C.u32Register;
    
    // Rx FIFO 1 (not use)
    unRXF1C.stcField.u1F1OM = 0;    // Rx FIFO 1 overwrite mode
    unRXF1C.stcField.u7F1WM = 0;    // Watermark interrupt disabled
    unRXF1C.stcField.u7F1S = 0;     // No Rx FIFO 1.
    unRXF1C.stcField.u14F1SA = 0x00000580; // offset(word)
    pstcCanFD->unRXF1C.u32Register = unRXF1C.u32Register;
    
    // Rx buffer
    unRXBC.stcField.u14RBSA = 0x00000A00; // offset(word)
    pstcCanFD->unRXBC.u32Register = unRXBC.u32Register;
    
    // Tx FIFO/QUEUE 
    unTXEFC.stcField.u6EFWM = 0; // Watermark interrupt enable.
    unTXEFC.stcField.u6EFS = 32;  // Tx Event FIFO disabled.
    unTXEFC.stcField.u14EFSA = 0x00000E80; // offset(word)
    pstcCanFD->unTXEFC.u32Register = unTXEFC.u32Register;
    
    // Tx buffer
    unTXBC.stcField.u1TFQM = 0;  // Tx FIFO operation
    unTXBC.stcField.u6TFQS = 32; // Transmit FIFO/Queue Size
    unTXBC.stcField.u6NDTB = 0;  // size of Dedicated Tx Buffers
    unTXBC.stcField.u14TBSA = 0x00000580; // offset(word)
    pstcCanFD->unTXBC.u32Register = unTXBC.u32Register;
    
    // Initialize message RAM area(Entire region zeroing)
    pulAdrs = (uint32_t *)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET);
    for (u16count = 0; u16count < CANFD0MRWORDS; u16count++)
    {
        *pulAdrs++ = 0ul;
    }
        
    // Configuration of Global Filter
    unGFC.stcField.u2ANFS = 2; // Reject when unmatch id
    unGFC.stcField.u2ANFE = 2; // Reject when unmatch id
    unGFC.stcField.u1RRFS = 1; // Reject all remote frame
    unGFC.stcField.u1RRFE = 1; // Reject all remote frame
    pstcCanFD->unGFC.u32Register = unGFC.u32Register;
    
    // Standard Message ID Filter
    for(u16count = 0; u16count < (unSIDFC.stcField.u8LSS - 1); u16count++)
    {
        if(u16count < 64)
        {
            pstcIdFilter = (stc_id_filter_t*)((uint32_t*)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unSIDFC.stcField.u14FLSSA + u16count);
            pstcIdFilter->SFT   = 2;        // Standard Filter Type : Classic filter
            pstcIdFilter->SFEC  = 7;        // Store into dedicated Rx Buffer, configuration of SFT[1:0] ignored.
            pstcIdFilter->SFID1 = standFilter_config->standardFilter[u16count];    // Filter ID :
            pstcIdFilter->SFID2 = (0 << 9) | u16count;  // Store message into a dedicated Rx Buffer  u16count:Buffer index
        }
        else
        {
            pstcIdFilter = (stc_id_filter_t*)((uint32_t*)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unSIDFC.stcField.u14FLSSA + u16count);
            pstcIdFilter->SFT   = 1;        // Standard Filter Type : Dual ID filter
            pstcIdFilter->SFEC  = 1;        // Store in Rx FIFO 0 if filter matches.
            pstcIdFilter->SFID1 = standFilter_config->standardFilter[u16count];    // Filter ID :
            pstcIdFilter->SFID2 = standFilter_config->standardFilter[u16count];    // Filter ID :
        }
    }
    
    pstcIdFilter = (stc_id_filter_t*)((uint32_t*)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unSIDFC.stcField.u14FLSSA + u16count);
    pstcIdFilter->SFT   = 0;        // Range filter from SFID1[10:0] to SFID2[10:0]
    pstcIdFilter->SFEC  = 1;
    pstcIdFilter->SFID1 = 0x000;
    pstcIdFilter->SFID2 = 0x7FF;
    
    // Extended Message ID Filter
    pstcExtIdFilter = (stc_extid_filter_t*)((uint32_t*)((uint32_t)pstcCanFD + (uint32_t)MSGRAMOFFSET) + pstcCanFD->unXIDFC.stcField.u14FLESA);
    pstcExtIdFilter->F1_f.EFT   = 2;        // Extended Filter Type : Classic filter
    pstcExtIdFilter->F0_f.EFEC  = 7;        // Store into dedicated Rx Buffer, configuration of EFT[1:0] ignored.
    pstcExtIdFilter->F0_f.EFID1 = 0x10001;  // Filter ID : 0x10001(65537)
    pstcExtIdFilter->F1_f.EFID2 = (0 << 9) | 1;  // Store message into a dedicated Rx Buffer *//* Buffer index : 1
    
    // Select Normal CAN mode or CAN-FD mode
    if( pstcConfig->bCanFDMode == FALSE )
    {
        // Classic CAN mode
        
        // Configuration of CAN bus
        // CCCR register
        unCCCR.stcField.u1TXP  = 0; // Transmit pause disabled.
        unCCCR.stcField.u1BRSE = 0; // Bit rate switching for transmissions disabled.
        unCCCR.stcField.u1FDOE = 0; // FD operation disabled.
        unCCCR.stcField.u1TEST = 0; // Normal operation
        unCCCR.stcField.u1DAR  = 0; // Automatic retransmission enabled.
        unCCCR.stcField.u1MON  = 0; // Bus Monitoring Mode is disabled.
        unCCCR.stcField.u1CSR  = 0; // No clock stop is requested.
        unCCCR.stcField.u1ASM  = 0; // Normal CAN operation.
        pstcCanFD->unCCCR.u32Register  = unCCCR.u32Register;
        
        // Bit Timing & Prescaler Register
        unNBTP.stcField.u9NBRP   = pstcConfig->stcBitrate.u16Prescaler;
        unNBTP.stcField.u8NTSEG1 = pstcConfig->stcBitrate.u8TimeSegment1;
        unNBTP.stcField.u7NTSEG2 = pstcConfig->stcBitrate.u8TimeSegment2;
        unNBTP.stcField.u7NSJW   = pstcConfig->stcBitrate.u8SyncJumpWidth;
        pstcCanFD->unNBTP.u32Register  = unNBTP.u32Register;
        
        // Configuration of Rx Buffer and Rx FIFO
        unRXESC.stcField.u3RBDS = 0; // 8 byte data field.
        unRXESC.stcField.u3F1DS = 0; // FIFO1 8 byte data field.
        unRXESC.stcField.u3F0DS = 0; // FIFO0 8 byte data field.
        pstcCanFD->unRXESC.u32Register = unRXESC.u32Register;
        
        // Configuration of Tx Buffer and Tx FIFO/Queue
        unTXESC.stcField.u3TBDS = 0; // 8 byte data field.
        pstcCanFD->unTXESC.u32Register = unTXESC.u32Register;
    }
    else   // FAN-FD mode
    {
        // Configuration of CAN bus
        // CCCR register
        unCCCR.stcField.u1TXP  = 0; // Transmit pause disabled.
        unCCCR.stcField.u1BRSE = 1; // Bit rate switching for transmissions enabled.
        unCCCR.stcField.u1FDOE = 1; // FD operation enabled.
        unCCCR.stcField.u1TEST = 0; // Normal operation
        unCCCR.stcField.u1DAR  = 0; // Automatic retransmission enabled.
        unCCCR.stcField.u1MON  = 0; // Bus Monitoring Mode is disabled.
        unCCCR.stcField.u1CSR  = 0; // No clock stop is requested.
        unCCCR.stcField.u1ASM  = 0; // Normal CAN operation.
        pstcCanFD->unCCCR.u32Register  = unCCCR.u32Register;
        
        // Bit Timing & Prescaler Register
        unNBTP.stcField.u9NBRP   = pstcConfig->stcBitrate.u16Prescaler;
        unNBTP.stcField.u8NTSEG1 = pstcConfig->stcBitrate.u8TimeSegment1;
        unNBTP.stcField.u7NTSEG2 = pstcConfig->stcBitrate.u8TimeSegment2;
        unNBTP.stcField.u7NSJW   = pstcConfig->stcBitrate.u8SyncJumpWidth;
        pstcCanFD->unNBTP.u32Register  = unNBTP.u32Register;
        
        // Fast Bit Timing & Prescaler
        unDBTP.stcField.u1TDC    = 1; // Transceiver Delay Compensation enabled.
        unDBTP.stcField.u5DBRP   = pstcConfig->stcFastBitrate.u16Prescaler;
        unDBTP.stcField.u5DTSEG1 = pstcConfig->stcFastBitrate.u8TimeSegment1;
        unDBTP.stcField.u4DTSEG2 = pstcConfig->stcFastBitrate.u8TimeSegment2;
        unDBTP.stcField.u4DSJW   = pstcConfig->stcFastBitrate.u8SyncJumpWidth;
        pstcCanFD->unDBTP.u32Register   = unDBTP.u32Register;
        
        // Transmitter Delay Compensation
        unTDCR.stcField.u7TDCO   = 25; // Transmitter Delay Compensation Offset
        unTDCR.stcField.u7TDCF   = 0; // Transmitter Delay Compensation Filter Window Length
        pstcCanFD->unTDCR.u32Register   = unTDCR.u32Register;
        // Configuration of Rx Buffer and Rx FIFO
        unRXESC.stcField.u3RBDS = 7; // 64 byte data field.
        unRXESC.stcField.u3F1DS = 7; // FIFO1 64 byte data field.
        unRXESC.stcField.u3F0DS = 7; // FIFO0 64 byte data field.
        pstcCanFD->unRXESC.u32Register = unRXESC.u32Register;
        
        // Configuration of Tx Buffer and Tx FIFO/Queue
        unTXESC.stcField.u3TBDS = 7; // 64 byte data field.
        pstcCanFD->unTXESC.u32Register = unTXESC.u32Register;
        
    } // if( pstcConfig->bCanFDMode == 0 )
    
    // Configuration of Timestamp
    unTSCC.stcField.u2TSS = 0; // Timestamp Counter Prescaler 
    unTSCC.stcField.u4TCP = 0;  // Timestamp Select 
    pstcCanFD->unTSCC.u32Register = unTSCC.u32Register;
    
    // Configuration of Interrupt
    // Interrupt Enable
    unIE.stcField.u1ARAE  = 0; // Access to Reserved Address
    unIE.stcField.u1PEDE  = 1; // Protocol Error in Data Phase
    unIE.stcField.u1PEAE  = 1; // Protocol Error in Arbitration Phase
    unIE.stcField.u1WDIE  = 0; // Watchdog
    unIE.stcField.u1BOE   = 0; // Bus_Off Status
    unIE.stcField.u1EWE   = 0; // Warning Status
    unIE.stcField.u1EPE   = 0; // Error Passive
    unIE.stcField.u1ELOE  = 0; // Error Logging Overflow
    unIE.stcField.u1BEUE  = 0; // Bit Error Uncorrected
    unIE.stcField.u1BECE  = 0; // Bit Error Corrected
    unIE.stcField.u1DRXE  = 1; // Message stored to Dedicated Rx Buffer
    unIE.stcField.u1TOOE  = 0; // Timeout Occurred
    unIE.stcField.u1MRAFE = 0; // Message RAM Access Failure
    unIE.stcField.u1TSWE  = 0; // Timestamp Wraparound
    unIE.stcField.u1TEFLE = 0; // Tx Event FIFO Event Lost
    unIE.stcField.u1TEFFE = 0; // Tx Event FIFO Full
    unIE.stcField.u1TEFWE = 0; // Tx Event FIFO Watermark Reached
    unIE.stcField.u1TEFNE = 1; // Tx Event FIFO New Entry
    unIE.stcField.u1TFEE  = 0; // Tx FIFO Empty
    unIE.stcField.u1TCFE  = 0; // Transmission Cancellation Finished
    unIE.stcField.u1TCE   = 1; // Transmission Completed
    unIE.stcField.u1HPME  = 0; // High Priority Message
    unIE.stcField.u1RF1LE = 0; // Rx FIFO 1 Message Lost
    unIE.stcField.u1RF1FE = 0; // Rx FIFO 1 Full
    unIE.stcField.u1RF1WE = 0; // Rx FIFO 1 Wotermark Reached
    unIE.stcField.u1RF1NE = 0; // Rx FIFO 1 New Message
    unIE.stcField.u1RF0LE = 0; // Rx FIFO 0 Message Lost
    unIE.stcField.u1RF0FE = 0; // Rx FIFO 0 Full
    unIE.stcField.u1RF0WE = 0; // Rx FIFO 0 Wotermark Reached
    unIE.stcField.u1RF0NE = 1; // Rx FIFO 0 New Message
    pstcCanFD->unIE.u32Register = unIE.u32Register;
    
    // Interrupt Line Select
    unILS.stcField.u1ARAL  = 0; // Access to Reserved Address
    unILS.stcField.u1PEDL  = 0; // Protocol Error in Data Phase
    unILS.stcField.u1PEAL  = 0; // Protocol Error in Arbitration Phase
    unILS.stcField.u1WDIL  = 0; // Watchdog
    unILS.stcField.u1BOL   = 0; // Bus_Off Status
    unILS.stcField.u1EWL   = 0; // Warning Status
    unILS.stcField.u1EPL   = 0; // Error Passive
    unILS.stcField.u1ELOL  = 0; // Error Logging Overflow
    unILS.stcField.u1BEUL  = 0; // Bit Error Uncorrected
    unILS.stcField.u1BECL  = 0; // Bit Error Corrected
    unILS.stcField.u1DRXL  = 0; // Message stored to Dedicated Rx Buffer
    unILS.stcField.u1TOOL  = 0; // Timeout Occurred
    unILS.stcField.u1MRAFL = 0; // Message RAM Access Failure
    unILS.stcField.u1TSWL  = 0; // Timestamp Wraparound
    unILS.stcField.u1TEFLL = 0; // Tx Event FIFO Event Lost
    unILS.stcField.u1TEFFL = 0; // Tx Event FIFO Full
    unILS.stcField.u1TEFWL = 0; // Tx Event FIFO Watermark Reached
    unILS.stcField.u1TEFNL = 0; // Tx Event FIFO New Entry
    unILS.stcField.u1TFEL  = 0; // Tx FIFO Empty
    unILS.stcField.u1TCFL  = 0; // Transmission Cancellation Finished
    unILS.stcField.u1TCL   = 0; // Transmission Completed
    unILS.stcField.u1HPML  = 0; // High Priority Message
    unILS.stcField.u1RF1LL = 0; // Rx FIFO 1 Message Lost
    unILS.stcField.u1RF1FL = 0; // Rx FIFO 1 Full
    unILS.stcField.u1RF1WL = 0; // Rx FIFO 1 Wotermark Reached
    unILS.stcField.u1RF1NL = 0; // Rx FIFO 1 New Message
    unILS.stcField.u1RF0LL = 0; // Rx FIFO 0 Message Lost
    unILS.stcField.u1RF0FL = 0; // Rx FIFO 0 Full
    unILS.stcField.u1RF0WL = 0; // Rx FIFO 0 Wotermark Reached
    unILS.stcField.u1RF0NL = 0; // Rx FIFO 0 New Message
    pstcCanFD->unILS.u32Register = unILS.u32Register;
    
    // Interrupt Line Enable
    unILE.stcField.u1EINT0 = 1; // Enable Interrupt Line 0
    unILE.stcField.u1EINT1 = 0; // Disable Interrupt Line 1
    pstcCanFD->unILE.u32Register = unILE.u32Register;
    
    // CAN-FD operation start
    // Set CCCR.INIT to 0 and wait until it will be updated.
    unCCCR.stcField.u1INIT = 0;
    pstcCanFD->unCCCR.u32Register = unCCCR.u32Register;
    while ( pstcCanFD->unCCCR.stcField.u1INIT != 0 )
    {
    }
    
    return Ok;
}

/*-------------------------------------------------------------------------
* Function Name  : BSP_CAN1_Init
* Description    : 
* Input          : 
*                : 
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void bsp_CAN1_Init(void)
{
    /*????????????????????????  ???????????can???????*/
    stc_port_pin_config_t stc_port_pin_config0_28 = { .enOutputFunction      = PortOutputResourceD,  // TX1_0
    .enOutputDrive         = PortOutputDriveA,
    .enPullResistor        = PortPullResistorNone,
    .enInputLevel          = PortInputLevelCmosA,
    .bInputEnable          = FALSE,
    .bNoiseFilterEnable    = TRUE,
    .enGpioDirection       = PortGpioOutput,
    .enGpioInitOutputLevel = PortGpioLow
    };
    Port_SetPinConfig( 0, 28, &stc_port_pin_config0_28 );
    
    stc_port_pin_config_t stc_port_pin_config0_27 = { .enOutputFunction      = PortOutputResourceGPIO, // RX1_0
    .enOutputDrive         = PortOutputDriveA,
    .enPullResistor        = PortPullResistorNone,
    .enInputLevel          = PortInputLevelCmosA,
    .bInputEnable          = TRUE,
    .bNoiseFilterEnable    = TRUE,
    .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow
    };
    Port_SetPinConfig( 0, 27, &stc_port_pin_config0_27 );
    Port_EnableInput();
    
    stc_canfd_standardFilter_t m_canfd_standFilter_config =
    {
        //??????????
        0
    };
    
    CanFD_Drive_Init(CANFD1_Type,&m_canfd_standFilter_config);
}

/*-------------------------------------------------------------------------
* Function Name  : bsp_CAN0_Init
* Description    :
* Input          :
*                :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/

void bsp_CAN0_Init(void)
{ 
    /*????????????????????????  ???????????can???????*/
    stc_port_pin_config_t stc_port_pin_config0_26 = { .enOutputFunction      = PortOutputResourceC,  // TX0_0
    .enOutputDrive         = PortOutputDriveA,
    .enPullResistor        = PortPullResistorNone,
    .enInputLevel          = PortInputLevelCmosA,
    .bInputEnable          = FALSE,
    .bNoiseFilterEnable    = TRUE,
    .enGpioDirection       = PortGpioOutput,
    .enGpioInitOutputLevel = PortGpioLow
    };
    Port_SetPinConfig( 0, 26, &stc_port_pin_config0_26 );
    
    stc_port_pin_config_t stc_port_pin_config0_25 = { .enOutputFunction      = PortOutputResourceGPIO, // RX0_0
    .enOutputDrive         = PortOutputDriveA,
    .enPullResistor        = PortPullResistorNone,
    .enInputLevel          = PortInputLevelCmosA,
    .bInputEnable          = TRUE,
    .bNoiseFilterEnable    = FALSE,
    .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow
    };
    Port_SetPinConfig( 0, 25, &stc_port_pin_config0_25 );
    Port_EnableInput();
    
    stc_canfd_standardFilter_t m_canfd_standFilter_config =
    {
        0
    };
    
    CanFD_Drive_Init(CANFD0_Type,&m_canfd_standFilter_config);
}

uint8_t Shift_Fun(uint8_t data)
{
    uint8_t i;
    uint8_t tmp=0x00;
    
    for(i=0;i<8;i++)
    {
        tmp=((data>>i)&0x01)|tmp;
        if(i<7)
        {
            tmp=tmp<<1;
        }
    }
    return tmp;
}

void Byte_Shift_Fun(uint8_t *pdata)
{
    uint8_t i;
    for(i=0;i<8;i++)
    {
        pdata[i] = Shift_Fun(pdata[i]);
    }
}


