/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* (c) 2014 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/

/******************************************************************************
* File Name     : rscan.c
* Version       : 1.0
* Device(s)     : R7F701403AFP RH850/D1L
* Tool-Chain    : GHS
* Description   : This file is a sample of RS-CAN.
* Operation     : -
*******************************************************************************
*******************************************************************************
* History       : DD.MM.YYYY Version Description
*               : 27.10.2016 1.00    First Release
******************************************************************************/

/******************************************************************************
Includes <System Includes> , �gProject Includes�h
******************************************************************************/
#include "r_typedefs.h"
#include "dr7f701441.dvf.h"
#include "GPIO.h"
#include "Rscan.h"
#include "CAN_Lib.h"
//#include "CAN_Signal_Tx.h"
#include "DoCAN_ISO15765.h"

#include <stdio.h>

/******************************************************************************
Imported global variables and functions (from other files)
******************************************************************************/
#define RSCAN0_CH0
//#define RSCAN0_CH1
//#define RSCAN0_CH2

#define RSCAN0_CH0_EXT
//#define RSCAN0_CH0_STD
//#define RSCAN0_CH1_EXT
//#define RSCAN0_CH1_STD
//#define RSCAN0_CH2_EXT
//#define RSCAN0_CH2_STD

#if defined RSCAN0_CH0_EXT
#define RSCAN0_CH0_IDE (1U)
#else
#define RSCAN0_CH0_IDE (0U)
#endif

#if defined RSCAN0_CH1_EXT
#define RSCAN0_CH1_IDE (1U)
#else
#define RSCAN0_CH1_IDE (0U)
#endif

#if defined RSCAN0_CH2_EXT
#define RSCAN0_CH2_IDE (1U)
#else
#define RSCAN0_CH2_IDE (0U)
#endif

/******************************************************************************
Macro definitions
******************************************************************************/
#define protected_write(preg, pstatus, reg, value) \
    do                                             \
    {                                              \
        (preg) = 0xa5u;                            \
        (reg) = (value);                           \
        (reg) = ~(value);                          \
        (reg) = (value);                           \
    } while ((pstatus) == 1u)

CAN0_Data_Ind_Func pfCAN0DataIndCb;
CAN1_Data_Ind_Func pfCAN1DataIndCb;
CAN2_Data_Ind_Func pfCAN2DataIndCb;

void RSCAN0_CH_Init(CANFD_Filter_Init_st_t *pFilterInit, uint32_t IDFilterNum)
{
    uint8_t i, j;

    uint8_t FilterNum;
    uint8_t FilterPageNum;

    uint8_t Ext_FilterNum;
    uint8_t MsgFilterNum;
    uint8_t MsgFilterCycle;
    uint8_t MsgFilterPageNum;

    uint8_t CH0_IDFilterNum = 0U;
    uint8_t CH1_IDFilterNum = 0U;
    uint8_t CH2_IDFilterNum = 0U;

    CANFD_Filter_Cfg_st_t *pFilterCfg;
    CANFD_ID_Filter_st_t *pIDFilter;

    pfCAN0DataIndCb = pFilterInit->pfCAN0DataIndCb;
    pfCAN1DataIndCb = pFilterInit->pfCAN1DataIndCb;
    pfCAN2DataIndCb = pFilterInit->pfCAN2DataIndCb;

    /* Waiting for C_ISO_CAN to set. */
    protected_write(SYSPROTCMDD1, SYSPROTSD1, SYSCKSC_IRSCAND_CTL, 0x00000003); //PLLFIXCLK /60  PLLFIXCLK = PLL1CLK  PLL1CLK=480 MHz     480/6=8M   为什么设置 目前不知道  徐瑞
    while (SYSCKSC_IRSCAND_ACT != 0x3UL)
    {
    }
    /* Waiting for C_ISO_IRSCANXIN to set. */
    protected_write(SYSPROTCMDD1, SYSPROTSD1, SYSCKSC_IRSCANXINS_CTL, 0x00000001); //MainOsc  8M
    while (SYSCKSC_IRSCANXINS_ACT != 0x1UL)
    {
    }
    /* Waiting for CAN RAM initialization is completed */
    while ((RSCAN0GSTS & CAN_GRAMINIT_ON) != 0UL)
    {
    } //复位之后  由mcu自动设置成0
    /* Waiting for CAN entry global reset mdoe */
    RSCAN0GCTR &= ~CAN_GSLPR_MASK; /* GSLPR=0 , CAN_GSLPR_MASK = 0x4UL */
    while ((RSCAN0GSTS & CAN_GSLPSTS_ON) != 0UL)
    {
    }

#ifdef RSCAN0_CH0
    CH0_IDFilterNum = (uint8_t)(IDFilterNum & 0xFFU);
    /* Waiting for CAN0 entry channel reset mdoe */
    RSCAN0C0CTR &= ~CAN_CSLPR_MASK; /* CSLPR=0 , CAN_CSLPR_MASK = 0x4UL */
    while ((RSCAN0C0STS & CAN_CSLPSTS_ON) != 0UL)
    {
    }
    /* Set Channel Control register */
    RSCAN0C0CTR |= 0x00400000UL; // BUSOFF end occur recover by user
    /* Set Channel Configuration register */
    RSCAN0C0CFG = 0x023A0000UL; /* 500K 75%*/
    //RSCAN0C0CFG = 0x023A0001UL; /* 250K 75%*/ 
#endif

    /* Set Global Configuration register */
    RSCAN0GCFG = 0x00000018UL; /* CAN Clock Source Select */

    /* Set receive rule */
    RSCAN0GAFLCFG0 |= (uint32_t)(CH0_IDFilterNum << 24U); /* Channel0 Filter num */
    RSCAN0GAFLCFG0 |= (uint32_t)(CH1_IDFilterNum << 16U); /* Channel1 Filter num */
    RSCAN0GAFLCFG0 |= (uint32_t)(CH2_IDFilterNum << 8U);  /* Channel2 Filter num */

    RSCAN0GAFLECTR &= 0U;            /* Configuration Page0 */
    RSCAN0GAFLECTR |= CAN_AFLDAE_ON; /* Enable receive rule */
                                     /*12个 page  每个page 16个rule*/

    FilterNum = 0U;
    FilterPageNum = 0U;

#ifdef RSCAN0_CH0
    /* Step 1 : Configure standard ID filters(Nsg) */
    pFilterCfg = &(pFilterInit->Msg0StdFilter);

    MsgFilterNum = pFilterCfg->IDNum;
    if ((MsgFilterNum % 16U) > 0U)
    {
        MsgFilterPageNum = (MsgFilterNum / 16U) + 1U;
    }
    else if ((MsgFilterNum % 16U) == 0U)
    {
        MsgFilterPageNum = MsgFilterNum / 16U;
    }
    MsgFilterCycle = 16U;

    for (j = 0U; j < MsgFilterPageNum; j++)
    {
        if (FilterNum == 0U)
        {
            RSCAN0GAFLECTR &= 0x100UL;
            RSCAN0GAFLECTR |= FilterPageNum; /* Configuration Page N */
        }
        if ((pFilterCfg->CfgType == CANFD_FILTER_ID_LIST) && (pFilterCfg->pIDs != NULL))
        {
            for (i = 0U; i < MsgFilterCycle; i++)
            {
                pIDFilter = (CANFD_ID_Filter_st_t *)((uint32_t *)(CANFD_CH0_MSG_RAM_ADDR + (0x0010U * FilterNum)));
                pIDFilter->F0_f.GAFLID = pFilterCfg->pIDs[i + j * 16U];
                pIDFilter->F0_f.GAFLLB = 0U;
                pIDFilter->F0_f.GAFLRTR = 0U;
                pIDFilter->F0_f.GAFLIDE = RSCAN0_CH0_IDE;

                pIDFilter->F1_f.GAFLIDM = 0x1FFFFFFFUL; //所有位都比较
                pIDFilter->F1_f.GAFLRTRM = 1U;
                pIDFilter->F1_f.GAFLIDEM = 1U;

                pIDFilter->F2_f.GAFLRMDP = 0U;
                pIDFilter->F2_f.GAFLRMV = 0U;
                pIDFilter->F2_f.GAFLPTR = 0U;
                pIDFilter->F2_f.GAFLDLC = 0U;

                pIDFilter->F3_f.GAFLFDP1 = 0U;
                pIDFilter->F3_f.GAFLFDP2 = 0x02U;

                FilterNum++;
                if (FilterNum >= 16U)
                {
                    FilterNum = 0U;
                    FilterPageNum++;
                }

                MsgFilterNum--;
                if (MsgFilterNum == 0U)
                {
                    break;
                }
            }
        }
    }
    /* Step 2 : Configure own standard ID filters(Diag) */
    Ext_FilterNum = 0U;

    pFilterCfg = &(pFilterInit->Diag0StdFilter);

    MsgFilterNum = pFilterCfg->IDNum;
    if (FilterNum == 0U)
    {
        if ((MsgFilterNum % 16U) > 0U)
        {
            MsgFilterPageNum = (MsgFilterNum / 16U) + 1U;
        }
        else if ((MsgFilterNum % 16U) == 0U)
        {
            MsgFilterPageNum = MsgFilterNum / 16U;
        }
        MsgFilterCycle = 16U;
    }
    else if (FilterNum != 0U)
    {
        Ext_FilterNum = 16U - FilterNum;
        if (MsgFilterNum > Ext_FilterNum)
        {
            MsgFilterNum = MsgFilterNum - Ext_FilterNum;
            if ((MsgFilterNum % 16U) > 0U)
            {
                MsgFilterPageNum = (MsgFilterNum / 16U) + 2U;
            }
            else if ((MsgFilterNum % 16U) == 0U)
            {
                MsgFilterPageNum = MsgFilterNum / 16U + 1U;
            }
            MsgFilterCycle = Ext_FilterNum;
        }
        else
        {
            MsgFilterNum = MsgFilterNum;
            MsgFilterPageNum = 1U;
            MsgFilterCycle = MsgFilterNum;
        }
    }

    for (j = 0U; j < MsgFilterPageNum; j++)
    {
        if (FilterNum == 0U)
        {
            RSCAN0GAFLECTR &= 0x100UL;
            RSCAN0GAFLECTR |= FilterPageNum;
        }

        if (j > 0U)
        {
            //	    Ext_FilterNum = 0U;
            MsgFilterCycle = 16U;
        }

        if ((pFilterCfg->CfgType == CANFD_FILTER_ID_LIST) && (pFilterCfg->pIDs != NULL))
        {
            for (i = 0U; i < MsgFilterCycle; i++)
            {
                pIDFilter = (CANFD_ID_Filter_st_t *)((uint32 *)(CANFD_CH0_MSG_RAM_ADDR + (0x0010U * FilterNum)));
                if ((j > 0U) && (Ext_FilterNum != 0U))
                {
                    pIDFilter->F0_f.GAFLID = pFilterCfg->pIDs[i + (j - 1U) * 16U + Ext_FilterNum];
                }
                else
                {
                    pIDFilter->F0_f.GAFLID = pFilterCfg->pIDs[i + j * 16U];
                }

                pIDFilter->F0_f.GAFLLB = 1U;
                pIDFilter->F0_f.GAFLRTR = 0U;
                pIDFilter->F0_f.GAFLIDE = RSCAN0_CH0_IDE;

                pIDFilter->F1_f.GAFLIDM = 0x1FFFFFFFUL;
                pIDFilter->F1_f.GAFLRTRM = 1U;
                pIDFilter->F1_f.GAFLIDEM = 1U;

                pIDFilter->F2_f.GAFLRMDP = 0U;
                pIDFilter->F2_f.GAFLRMV = 0U;
                pIDFilter->F2_f.GAFLPTR = 0U;
                pIDFilter->F2_f.GAFLDLC = 0U;

                pIDFilter->F3_f.GAFLFDP1 = 0U;
                pIDFilter->F3_f.GAFLFDP2 = 0x02U;

                FilterNum++;
                if (FilterNum >= 16U)
                {
                    FilterNum = 0U;
                    FilterPageNum++;
                }

                if (MsgFilterCycle == 16U)
                {
                    MsgFilterNum--;
                }
                if (MsgFilterNum == 0U)
                {
                    break;
                }
            }
        }
    }
    /* Step 3 : Configure range standard ID filters(NM) */
    if (FilterNum == 0U)
    {
        RSCAN0GAFLECTR &= 0x100UL;
        RSCAN0GAFLECTR |= FilterPageNum; /* Configuration Page N */
    }
    pFilterCfg = &(pFilterInit->NM0StdFilter);
    if ((pFilterCfg->CfgType == CANFD_FILTER_ID_RANGE) && (pFilterCfg->pIDs != NULL))
    {
        for (i = 0U; i < pFilterCfg->IDNum; i++)
        {
            pIDFilter = (CANFD_ID_Filter_st_t *)((uint32_t *)(CANFD_CH0_MSG_RAM_ADDR + (0x0010U * FilterNum)));
            pIDFilter->F0_f.GAFLID = pFilterCfg->pIDs[i * 2U + 1U];
            pIDFilter->F0_f.GAFLLB = 0U;
            pIDFilter->F0_f.GAFLRTR = 0U;
            pIDFilter->F0_f.GAFLIDE = RSCAN0_CH0_IDE;

            pIDFilter->F1_f.GAFLIDM = 0x1FFFFF80UL;
            pIDFilter->F1_f.GAFLRTRM = 1U;
            pIDFilter->F1_f.GAFLIDEM = 1U;

            pIDFilter->F2_f.GAFLRMDP = 0U;
            pIDFilter->F2_f.GAFLRMV = 0U;
            pIDFilter->F2_f.GAFLPTR = 0U;
            pIDFilter->F2_f.GAFLDLC = 0U;

            pIDFilter->F3_f.GAFLFDP1 = 0U;
            pIDFilter->F3_f.GAFLFDP2 = 0x02U;

            FilterNum++;
            if (FilterNum >= 16U)
            {
                FilterNum = 0U;
                FilterPageNum++;
            }
        }
    }

#endif

    RSCAN0GAFLECTR &= ~CAN_AFLDAE_ON; /* Disable receive rule */
//每个通道有16个 发送buffer
#ifdef RSCAN0_CH0
    /* Set transmit Buffer configuration */
    RSCAN0TMC0 |= 0x05U;          /* enable Txbuffer0 abort function */
    RSCAN0TMC1 |= 0x05U;          /* enable Txbuffer1 abort function */
    RSCAN0TMIEC0 |= 0x00000003UL; /* enable Txbuffer0.1 interrup num */
    /* Set transmint/receive buffer configuration(Tx) */
    RSCAN0CFCC0 &= ~CAN_CFE_MASK; /* clear CFE first */
    while ((RSCAN0CFCC0 & CAN_CFE_MASK) != 0UL)
    {
    } /* Waiting for CFE cleared */
    RSCAN0CFCC0 |= 0x00FD1404UL;
    /* Set transmint/receive buffer configuration(Rx) */
    RSCAN0CFCC1 &= ~CAN_CFE_MASK; /* clear CFE first */
    while ((RSCAN0CFCC1 & CAN_CFE_MASK) != 0UL)
    {
    } /* Waiting for CFE cleared */
    RSCAN0CFCC1 |= 0x000C1402UL;
    /* Set interrupt configuration */
    PBGFSGD0BPROT0 = 0x07FFFFFFUL; /* must-operate , page384 */
    INTC2EIC70 = 0x0047UL;         /* channel0-2 RX FIFO interrupt */
    //INTC2EIC71   = 0x0047UL;            /* error interrupt */
    INTC2EIC72 = 0x0047UL; /* rx interrupt */
    INTC2EIC73 = 0x0047UL; /* tx interrupt */
#endif

    /* Set Receive_Buffer Number */
    RSCAN0RMNB = 0U;

    if (RSCAN0GSTS & 0x03UL) /* If GlobalChannel in test or reset mode */
    {
        RSCAN0GCTR &= 0xFFFFFFFCUL; /* Switch to operating mode */
        while ((RSCAN0GSTS & 0x02UL) == 2UL)
        {
        } /* While test mode */
        while ((RSCAN0GSTS & 0x01UL) == 1UL)
        {
        } /* While reset mode */
    }

#ifdef RSCAN0_CH0
    if (RSCAN0C0STS & 0x03UL) /* If Channel0 in halt or reset mode */
    {
        RSCAN0C0CTR &= 0xFFFFFFFCUL; /* Switch to communication mode */
        while ((RSCAN0C0STS & 0x02) == 2UL)
        {
        } /* While halt mode */
        while ((RSCAN0C0STS & 0x01) == 1UL)
        {
        } /* While reset mode */
    }
    /* transmint/receive buffer Enable */
    RSCAN0CFCC0 |= CAN_CFE_ON; /* CFE Enable transmint/receive buffer Enable��Modify the bit only in channel halt/communication mode */
    RSCAN0CFCC1 |= CAN_CFE_ON; /* CFE Enable transmint/receive buffer Enable��Modify the bit only in channel halt/communication mode */
#endif
}

/******************************************************************************
* Function Name     : RSCAN0_SendCH0_TxBuf0
* Description       : CAN trasmit by TxBuf0
* Argument          : ID DLC IDE MSG[8]
* Return Value      : None
******************************************************************************/
uint8_t RSCAN0_SendCH0_TxBuf0(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer0 */
    if ((RSCAN0TMSTS0 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS0 = 0x00U;
        RSCAN0TMID0 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID0 |= (ide << 31U);
        RSCAN0TMPTR0 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF00 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF10 = *((uint32_t *)&msg[4]);
        RSCAN0TMC0 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
/******************************************************************************
* Function Name     : RSCAN0_SendCH0_TxBuf1
* Description       : CAN trasmit by TxBuf1
* Argument          : ID DLC IDE MSG[8]
* Return Value      : None
******************************************************************************/
uint8_t RSCAN0_SendCH0_TxBuf1(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS1 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS1 = 0x00U;
        RSCAN0TMID1 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID1 |= (ide << 31U);
        RSCAN0TMPTR1 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF01 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF11 = *((uint32_t *)&msg[4]);
        RSCAN0TMC1 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}

uint8_t RSCAN0_SendCH0_TxBuf2(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS2 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS2 = 0x00U;
        RSCAN0TMID2 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID2 |= (ide << 31U);
        RSCAN0TMPTR2 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF02 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF12 = *((uint32_t *)&msg[4]);
        RSCAN0TMC2 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf3(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS3 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS3 = 0x00U;
        RSCAN0TMID3 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID3 |= (ide << 31U);
        RSCAN0TMPTR3 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF03 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF13 = *((uint32_t *)&msg[4]);
        RSCAN0TMC3 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf4(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS4 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS4 = 0x00U;
        RSCAN0TMID4 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID4 |= (ide << 31U);
        RSCAN0TMPTR4 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF04 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF14 = *((uint32_t *)&msg[4]);
        RSCAN0TMC4 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}

uint8_t RSCAN0_SendCH0_TxBuf5(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS5 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS5 = 0x00U;
        RSCAN0TMID5 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID5 |= (ide << 31U);
        RSCAN0TMPTR5 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF05 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF15 = *((uint32_t *)&msg[4]);
        RSCAN0TMC5 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf6(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS6 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS6 = 0x00U;
        RSCAN0TMID6 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID6 |= (ide << 31U);
        RSCAN0TMPTR6 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF06 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF16 = *((uint32_t *)&msg[4]);
        RSCAN0TMC6 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf7(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS7 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS7 = 0x00U;
        RSCAN0TMID7 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID7 |= (ide << 31U);
        RSCAN0TMPTR7 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF07 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF17 = *((uint32_t *)&msg[4]);
        RSCAN0TMC7 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf8(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS8 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS8 = 0x00U;
        RSCAN0TMID8 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID8 |= (ide << 31U);
        RSCAN0TMPTR8 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF08 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF18 = *((uint32_t *)&msg[4]);
        RSCAN0TMC8 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf9(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS9 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS9 = 0x00U;
        RSCAN0TMID9 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID9 |= (ide << 31U);
        RSCAN0TMPTR9 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF09 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF19 = *((uint32_t *)&msg[4]);
        RSCAN0TMC9 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf10(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS10 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS10 = 0x00U;
        RSCAN0TMID10 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID10 |= (ide << 31U);
        RSCAN0TMPTR10 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF010 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF110 = *((uint32_t *)&msg[4]);
        RSCAN0TMC10 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf11(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS11 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS11 = 0x00U;
        RSCAN0TMID11 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID11 |= (ide << 31U);
        RSCAN0TMPTR11 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF011 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF111 = *((uint32_t *)&msg[4]);
        RSCAN0TMC11 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf12(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS12 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS12 = 0x00U;
        RSCAN0TMID12 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID12 |= (ide << 31U);
        RSCAN0TMPTR12 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF012 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF112 = *((uint32_t *)&msg[4]);
        RSCAN0TMC12 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf13(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS13 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS13 = 0x00U;
        RSCAN0TMID13 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID13 |= (ide << 31U);
        RSCAN0TMPTR13 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF013 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF113 = *((uint32_t *)&msg[4]);
        RSCAN0TMC13 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf14(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS14 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS14 = 0x00U;
        RSCAN0TMID14 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID14 |= (ide << 31U);
        RSCAN0TMPTR14 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF014 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF114 = *((uint32_t *)&msg[4]);
        RSCAN0TMC14 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
uint8_t RSCAN0_SendCH0_TxBuf15(uint32_t can_id, uint8_t dlc, uint8_t ide, uint8_t msg[8])
{
    uint8_t ret;

    /* ʹ��transmint buffer1 */
    if ((RSCAN0TMSTS15 & CAN_TMTRM_ON) == 0x0U) /* CAN_TMTRM_ON = 0x8U */
    {
        RSCAN0TMSTS15 = 0x00U;
        RSCAN0TMID15 = (can_id & 0x1FFFFFFFUL);
        RSCAN0TMID15 |= (ide << 31U);
        RSCAN0TMPTR15 = (dlc & 0xFU) << 28U;
        RSCAN0TMDF015 = *((uint32_t *)&msg[0]);
        RSCAN0TMDF115 = *((uint32_t *)&msg[4]);
        RSCAN0TMC15 = CAN_TMTR_ON;
        ret = 1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}
/******************************************************************************
* Function Name     : CAN0_Receive_FIFO0
* Description       : CAN Receive by Rx/Tx FIFO0
* Argument          : None
* Return Value      : None
******************************************************************************/
uint8_t CAN0_Receive_FIFO1(void)
{
    uint8_t ret = 0U;
    uint8_t DLC;
    uint32_t Identifier;
    uint8_t Data[8];

    while ((RSCAN0CFSTS1 & 0x01UL) == 0U)
    {
        ret = 1U;
        Identifier = (uint32_t)(RSCAN0CFID1 & 0x1FFFFFFFUL);
        DLC = (uint8_t)(RSCAN0CFPTR1 >> 28U);
        *((uint32_t *)&Data[0]) = RSCAN0CFDF01;
        *((uint32_t *)&Data[4]) = RSCAN0CFDF11;
        RSCAN0CFPCTR1 |= 0xFFFFFFFFUL;

        if (DLC > 8U)
        {
            DLC = 8U;
        }

        if (pfCAN0DataIndCb != NULL)
        {
            pfCAN0DataIndCb(Identifier, DLC, Data);
        }
    }

    return ret;
}

/******************************************************************************
* Function Name     : CAN_CH0_Data_Request
* Description       : Set CAN_CH0_L_Data_Request
* Argument          : None
* Return Value      : CAN_Set_Complete=0,
                          CAN_Set_ERROR_BUSOFF,
                          CAN_Set_ERROR_OverMaxLen,
                          CAN_Set_ERROR_MsgFull,
******************************************************************************/
CAN_SetState CAN_CH0_Data_Request(uint32_t Identifier, uint8_t MsgStd, uint8_t MsgRTR, uint8_t DLC, uint8_t *Data)
{
    uint8_t i;
    uint32_t Word;

    if ((DLC == 0U) || (DLC > 8U) || (Data == NULL))
    {
        return CAN_Set_ERROR_OverMaxLen;
    }

    if ((RSCAN0CFSTS0 & 0x00000002UL) == 0x0U)
    {
        RSCAN0CFID0 |= ((MsgStd & 0x1U) << 31U);
        RSCAN0CFID0 |= ((MsgRTR & 0x1U) << 30U);
        if (MsgStd == Standard_ID)
        {
            RSCAN0CFID0 &= 0xE0000000UL;
            RSCAN0CFID0 |= (Identifier & 0x7FFUL);
        }
        else
        {
            RSCAN0CFID0 &= 0xE0000000UL;
            RSCAN0CFID0 |= (Identifier & 0x1FFFFFFFUL);
        }
        RSCAN0CFPTR0 = ((DLC & 0xFU) << 28U);

        if (DLC < 5U)
        {
            RSCAN0CFDF10 = 0x00000000UL;
        }
        else
        {
            Word = 0U;
            i = 8U;
            while (i > 4U)
            {
                i--;
                Word <<= 8U;
                if (i < DLC)
                {
                    Word |= (uint32_t)Data[i];
                }
            }
            RSCAN0CFDF10 = Word;
        }

        Word = 0U;
        i = 4U;
        while (i > 0U)
        {
            i--;
            Word <<= 8U;
            if (i < DLC)
            {
                Word |= (uint32_t)Data[i];
            }
        }
        RSCAN0CFDF00 = Word;
        RSCAN0CFPCTR0 |= 0x000000FFUL;
        return CAN_Set_Complete;
    }
    else
    {
        return CAN_Set_ERROR_MsgFull;
    }
}
/******************************************************************************
* Function Name     : Get_CAN0_Status
* Description       : Get_CAN0_Status_Register
* Argument          : None
* Return Value      : None
******************************************************************************/
uint32_t Get_CAN0_Status(void)
{
    uint32_t ret;
    ret = RSCAN0C0STS;
    return ret;
}
/******************************************************************************
* Function Name     : Get_CAN0_TxBuf1_Status
* Description       : Get_CAN0_Transmit_Buffer1_Status_Register
* Argument          : None
* Return Value      : None
******************************************************************************/
uint8_t Get_CAN0_TxBuf1_Status(void)
{
    uint8_t ret;
    ret = RSCAN0TMSTS1;
    return ret;
}
/******************************************************************************
* Function Name     : CAN0_Channel0_To_StopMode
* Description       : Set CAN0_Channel0 goto StopMode
* Argument          : None
* Return Value      : None
******************************************************************************/
void CAN0_Channel0_To_StopMode(void)
{
    RSCAN0C0CTR &= 0xFFFFFFF8UL;
    RSCAN0C0CTR |= 0x00000001UL; /* first goto ResetMode */
    RSCAN0C0CTR |= 0x00000004UL; /* next goto StopMode */
}
/******************************************************************************
* Function Name     : CAN0_Channel0_To_CommunicationMode
* Description       : Set CAN0_Channel0 goto CommunicationMode
* Argument          : None
* Return Value      : None
******************************************************************************/
void CAN0_Channel0_To_CommunicationMode(void)
{
    RSCAN0C0CTR &= 0xFFFFFFFBUL; /* first goto ResetMode */
    RSCAN0C0CTR &= 0xFFFFFFF8UL; /* next goto CommunicationMode */
}
/******************************************************************************
* Function Name     : CAN0_Global_To_StopMode
* Description       : Set CAN0_Global goto StopMode
* Argument          : None
* Return Value      : None
******************************************************************************/
void CAN0_Global_To_StopMode(void)
{
    RSCAN0GCTR &= 0xFFFFFFF8UL;
    RSCAN0GCTR |= 0x00000001UL; /* first goto ResetMode */
    RSCAN0GCTR |= 0x00000004UL; /* next goto StopMode */
}
/******************************************************************************
* Function Name     : CANFD_SetTX_Abort
* Description       : Set CANFD_SetTX_Abort
* Argument          : None
* Return Value      : None
******************************************************************************/
void CANFD_SetTX_Abort(void)
{
    RSCAN0TMC0 |= 0X02U; /* transmit Buffer0 abort */
    RSCAN0TMC1 |= 0X02U; /* transmit Buffer1 abort */
}

uint8_t Get_CH0_BusOffStatus(void)
{
    uint32_t ret;
    ret = RSCAN0C0ERFL;
    if (ret & 0x00000008UL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
uint8_t Get_CH0_RecStatus(void)
{
    uint32_t ret;
    ret = RSCAN0C0STS;
    if (ret & 0x40UL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
void CH0_BusOff_Recovery(void)
{
    uint8_t ret;
    ret = Get_CH0_BusOffStatus();
    if (ret == 1U)
    {
        RSCAN0C0ERFL &= 0xFFFFFFF7UL;
        CAN0_Channel0_To_CommunicationMode();
    }
}
uint8_t Get_CH0_ErrPassiveStatus(void)
{
    uint32_t ret;
    ret = RSCAN0C0STS;
    if (ret & 0x00000008UL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
void RSCan0_CH0_Write(CAN_Msg_t *Msg)
{
    CAN_CH0_Data_Request(Msg->MsgID, Msg->MsgStd, Msg->MsgRTR, Msg->MsgDLC, Msg->Msg);
}

void RSCAN0_CH0_Tx_ISR(void) //CAN发送中断
{
    /*Clear the transmit status flag*/
    if ((RSCAN0TMSTS0 & 0x06U) != 0)
    {
        DoCAN_L_Data_Confirm(DIAG_ID_Tx, 1u);
        RSCAN0TMSTS0 &= 0xF9U;
    }
    if ((RSCAN0TMSTS1 & 0x06U) != 0)
    {
        RSCAN0TMSTS1 &= 0xF9;
    }
    if ((RSCAN0TMSTS2 & 0x06U) != 0)
    {
        RSCAN0TMSTS2 &= 0xF9;
    }
    if ((RSCAN0TMSTS3 & 0x06U) != 0)
    {
        RSCAN0TMSTS3 &= 0xF9;
    }
    if ((RSCAN0TMSTS4 & 0x06U) != 0)
    {
        RSCAN0TMSTS4 &= 0xF9;
    }
    if ((RSCAN0TMSTS5 & 0x06U) != 0)
    {
        RSCAN0TMSTS5 &= 0xF9;
    }
    if ((RSCAN0TMSTS6 & 0x06U) != 0)
    {
        RSCAN0TMSTS6 &= 0xF9;
    }
    if ((RSCAN0TMSTS7 & 0x06U) != 0)
    {
        RSCAN0TMSTS7 &= 0xF9;
    }
    if ((RSCAN0TMSTS8 & 0x06U) != 0)
    {
        RSCAN0TMSTS8 &= 0xF9;
    }
    if ((RSCAN0TMSTS9 & 0x06U) != 0)
    {
        RSCAN0TMSTS9 &= 0xF9;
    }
    if ((RSCAN0TMSTS10 & 0x06U) != 0)
    {
        RSCAN0TMSTS10 &= 0xF9;
    }
    if ((RSCAN0TMSTS11 & 0x06U) != 0)
    {
        RSCAN0TMSTS11 &= 0xF9;
    }
    if ((RSCAN0TMSTS12 & 0x06U) != 0)
    {
        RSCAN0TMSTS12 &= 0xF9;
    }
    if ((RSCAN0TMSTS13 & 0x06U) != 0)
    {
        RSCAN0TMSTS13 &= 0xF9;
    }
    if ((RSCAN0TMSTS14 & 0x06U) != 0)
    {
        RSCAN0TMSTS14 &= 0xF9;
    }
    if ((RSCAN0TMSTS15 & 0x06U) != 0)
    {
        RSCAN0TMSTS15 &= 0xF9;
    }
    if (RSCAN0CFTISTS & 0x1UL)
    {
        RSCAN0CFSTS0 &= 0xFFFFFFEF;
    }
    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC71 &= 0xEFFF;
}

void RSCAN0_CH0_Rx_ISR(void)
{
    if ((RSCAN0CFRISTS & 0x02UL) != 0U)
    {
        RSCAN0CFSTS1 &= 0xFFFFFFF7UL;
        CAN0_Receive_FIFO1();
    }

    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC72 &= 0xEFFF;
}

void RSCAN0_CH0_Err_ISR(void)
{
    uint32 temp1;
    temp1 = RSCAN0C0ERFL;

    if (temp1 & 0x00000008UL) //BOEF:bus off entry
    {
        RSCAN0C0ERFL &= 0xFFFFFFF7;
        CANFD_SetTX_Abort();
    }

    RSCAN0C0ERFL &= 0xFFFF8000UL;  /* clear all interrupt */
    PBGFSGD0BPROT0 = 0x07FFFFFFUL; /* 配置INTC2寄存器时必须进行此操作，见手册384页 */
    INTC2EIC71 &= 0xEFFF;
}

// void RSCAN0_CH0_Wakeup_ISR(void)
// {
// //    if(SYSWUF0 & 0x00000080UL)
//     {
//         SYSWUFC0   |= 0x00000080UL; //clear Wake-up event
//         SYSWUFMSK0 |= 0x00000080UL; //disable Wake-up event
//         GPIO_OUT_PORT00_PIN06 = 0U; // RSCAN0_CH0_STB set CAN goto normal mode
//     }
//     INTC1EIC12 &= 0xEFFF;       //clear iterrupt source
// }
void RSCAN0_CH1_Err_ISR(void)
{

}
void RSCAN0_CH2_Err_ISR(void)
{

}


void RSCAN0_CH2_Rx_ISR(void)
{

}
void RSCAN0_CH1_Rx_ISR(void)
{

}

void RSCAN0_CH1_Tx_ISR(void)
{

}
void RSCAN0_CH2_Tx_ISR(void)
{
    
}