/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2024. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */
/******************************************************************************
 * @version: V3.1.0  AC7840x  Demo
 ******************************************************************************/

#include "debugout_ac7840x.h"
#include "gpio_drv.h"
#include "can_drv.h"
#include "can_hw.h"
#include "clock_config.h"
#include "gpio.h"

/* ============================================  Define  ============================================ */
#define CAN_SOURCE_CLOCK             (60UL)                   /* 时钟源选择60M */
#define CAN_MSG_HANDLE_DIRECT        (1UL)                    /* 是否处理消息， 1 是， 0 否 */
#define CAN_TIME_STAMP_ENABLE        (0UL)                    /* 使能/失能CAN时间戳， 1 使能， 0 失能 */

/* ===========================================  Typedef  ============================================ */
typedef struct
{
    uint32_t recvCount;                                       /* 接收消息计数 */
    uint32_t sendCount;                                       /* 发送消息计数*/
} Can_cur_node_t;

/* ==========================================  Variables  =========================================== */
/*
 *  波特率和采样点计算公式：
 *  tSeg1 = (S_SEG_1 + 2); tSeg2 = (S_SEG_2 + 1).
 *  BandRate = (SCR_CLK / (S_PRESC + 1) / ((S_SEG_1 + 2) + (S_SEG_2 + 1))), SCR_CLK 为CAN 模块源时钟
 *  SamplePoint = (tSeg1 / (tSeg1 + tSeg2)).
 */

#if (CAN_SOURCE_CLOCK == 80UL)                                /* 时钟源为80M */
static const can_time_segment_t s_canBitrate[CAN_BITRATE_NUM] =
{
    {0x1C, 0x09, 0x09, 0x01},                                 /*   1M, 75% */
    {0x26, 0x09, 0x09, 0x01},                                 /* 800K, 80% */
    {0x1C, 0x09, 0x09, 0x03},                                 /* 500K, 75% */
    {0x1C, 0x09, 0x09, 0x07},                                 /* 250K, 75% */
    {0x1C, 0x09, 0x09, 0x0F},                                 /* 125K, 75% */
    {0x1C, 0x09, 0x09, 0x13},                                 /* 100K, 75% */
    {0x1C, 0x09, 0x09, 0x27},                                 /*  50K, 75% */
};
static const can_time_segment_t s_canfdBitrate[CAN_FD_BITRATE_NUM] =
{
    {0x0D, 0x04, 0x04, 0x4F},                                 /*  50K, 75%, just for test */
    {0x0D, 0x04, 0x04, 0x27},                                 /* 100K, 75%, just for test */
    {0x0D, 0x04, 0x04, 0x03},                                 /*   1M, 75% */
    {0x0D, 0x04, 0x04, 0x01},                                 /*   2M, 75% */
    {0x0D, 0x04, 0x04, 0x00},                                 /*   4M, 75% */
    {0x0A, 0x03, 0x03, 0x00},                                 /*   5M, 75% */
    {0x06, 0x01, 0x01, 0x00},                                 /*   8M, 80% */
};

#elif (CAN_SOURCE_CLOCK == 60UL)                              /* 时钟源为60M */
static const can_time_segment_t s_canBitrate[CAN_BITRATE_NUM] =
{
    {0x0D, 0x04, 0x04, 0x02},                                 /*   1M, 75% */
    {0x12, 0x04, 0x04, 0x02},                                 /* 800K, 80% */
    {0x1C, 0x09, 0x09, 0x02},                                 /* 500K, 75% */
    {0x1C, 0x09, 0x09, 0x05},                                 /* 250K, 75% */
    {0x1C, 0x09, 0x09, 0x0B},                                 /* 125K, 75% */
    {0x1C, 0x09, 0x09, 0x0E},                                 /* 100K, 75% */
    {0x1C, 0x09, 0x09, 0x1D},                                 /*  50K, 75% */
};
static const can_time_segment_t s_canfdBitrate[CAN_FD_BITRATE_NUM] =
{
    {0x0D, 0x04, 0x04, 0x3B},                                 /*  50K, 75%, just for test */
    {0x0D, 0x04, 0x04, 0x1D},                                 /* 100K, 75%, just for test */
    {0x0D, 0x04, 0x04, 0x02},                                 /*   1M, 75% */
    {0x15, 0x06, 0x06, 0x00},                                 /*   2M, 77% */
    {0x09, 0x03, 0x03, 0x00},                                 /*   4M, 73% */
    {0x05, 0x02, 0x02, 0x00},                                 /*   6M, 70% */
    {0x04, 0x01, 0x01, 0x00},                                 /* 7.5M, 75% */
};

#elif (CAN_SOURCE_CLOCK == 48UL)                              /* 时钟源为48M */
static const can_time_segment_t s_canBitrate[CAN_BITRATE_NUM] =
{
    {0x22, 0x0B, 0x0B, 0x00},                                 /*   1M, 75% */
    {0x16, 0x05, 0x05, 0x01},                                 /* 800K, 80% */
    {0x22, 0x0B, 0x0B, 0x01},                                 /* 500K, 75%*/
    {0x22, 0x0B, 0x0B, 0x03},                                 /* 250K, 75% */
    {0x22, 0x0B, 0x0B, 0x07},                                 /* 125K, 75% */
    {0x22, 0x0B, 0x0B, 0x09},                                 /* 100K, 75% */
    {0x22, 0x0B, 0x0B, 0x13},                                 /*  50K, 75% */
};
static const can_time_segment_t s_canfdBitrate[CAN_FD_BITRATE_NUM] =
{
    {0x10, 0x05, 0x05, 0x27},                                 /*  50K, 75%, just for test */
    {0x10, 0x05, 0x05, 0x13},                                 /* 100K, 75%, just for test */
    {0x10, 0x05, 0x05, 0x01},                                 /*   1M, 75% */
    {0x10, 0x05, 0x05, 0x00},                                 /*   2M, 75% */
    {0x07, 0x02, 0x02, 0x00},                                 /*   4M, 75% */
    {0x04, 0x01, 0x01, 0x00},                                 /*   6M, 75% */
    {0x03, 0x00, 0x00, 0x00},                                 /*   8M, 83% */
};

#elif (CAN_SOURCE_CLOCK == 24UL)                              /* 时钟源为24M */
static const can_time_segment_t s_canBitrate[CAN_BITRATE_NUM] =
{
    {0x10, 0x05, 0x05, 0x00},                                 /*   1M, 75% */
    {0x16, 0x05, 0x05, 0x00},                                 /* 800K, 80% */
    {0x10, 0x05, 0x05, 0x01},                                 /* 500K, 75% */
    {0x10, 0x05, 0x05, 0x03},                                 /* 250K, 75% */
    {0x10, 0x05, 0x05, 0x07},                                 /* 125K, 75% */
    {0x10, 0x05, 0x05, 0x09},                                 /* 100K, 75% */
    {0x10, 0x05, 0x05, 0x13},                                 /*  50K, 75% */
};
static const can_time_segment_t s_canfdBitrate[CAN_FD_BITRATE_NUM] =
{
    {0x10, 0x05, 0x05, 0x13},                                 /*  50K, 75%, just for test */
    {0x10, 0x05, 0x05, 0x09},                                 /* 100K, 75%, just for test */
    {0x10, 0x05, 0x05, 0x00},                                 /*   1M, 75% */
    {0x07, 0x02, 0x02, 0x00},                                 /*   2M, 75% */
    {0x03, 0x00, 0x00, 0x00},                                 /*   4M, 83% */
    {0x01, 0x00, 0x00, 0x00},                                 /*   6M, 75% */
    {0x00, 0x00, 0x00, 0x00},                                 /*   8M, 67% */
};

#elif (CAN_SOURCE_CLOCK == 8UL)                               /* 时钟源为8M */
static const can_time_segment_t s_canBitrate[CAN_BITRATE_NUM] =
{
    {0x04, 0x01, 0x01, 0x00},                                 /*   1M，75% */
    {0x06, 0x01, 0x01, 0x00},                                 /* 800K, 80% */
    {0x0A, 0x03, 0x03, 0x00},                                 /* 500K，75% */
    {0x0A, 0x03, 0x03, 0x01},                                 /* 250K，75% */
    {0x0A, 0x03, 0x03, 0x03},                                 /* 125K，75% */
    {0x0D, 0x04, 0x03, 0x03},                                 /* 100K，75% */
    {0x0D, 0x04, 0x03, 0x07},                                 /*  50K，75% */
};
static const can_time_segment_t s_canfdBitrate[CAN_FD_BITRATE_NUM] =
{
    {0x0D, 0x04, 0x03, 0x07},                                 /*  50K, 75%, just for test */
    {0x0D, 0x04, 0x03, 0x03},                                 /* 100K, 75%, just for test */
    {0x04, 0x01, 0x01, 0x00},                                 /*   1M, 75% */
    {0x01, 0x00, 0x00, 0x00},                                 /*   2M, 75% */
    {0x01, 0x00, 0x00, 0x00},                                 /*   2M, 75% */
    {0x01, 0x00, 0x00, 0x00},                                 /*   2M, 75% */
    {0x01, 0x00, 0x00, 0x00},                                 /*   2M, 75% */
};
#endif

static const can_filter_config_t s_canFilterList[16] =        /* 过滤器配置*/
{
    {0x00000001, 0x00000000, CAN_MSG_ID_BOTH},                /* 只接收ID 0x0000_0001和0x001的数据 */
    {0x00000002, 0x00000000, CAN_MSG_ID_STD},                 /* 只接收ID 0x002的标准帧数据 */
    {0x00000013, 0x00000000, CAN_MSG_ID_EXT},                 /* 只接收ID 0x0000_0013的扩展帧数据 */
    {0x00000124, 0x00000000, CAN_MSG_ID_BOTH},                /* 只接收ID 0x0000_0124和0x124的数据 */
    {0x00000050, 0x1FFFFF0F, CAN_MSG_ID_BOTH},                /* 可接收ID 0xXXXX_XX5X 或 0xX5X的数据，X为任意值 */
    {0x00000060, 0x1FFFFF0F, CAN_MSG_ID_BOTH},                /* 可接收ID 0xXXXX_XX6X 或 0xX6X的数据，X为任意值 */
    {0x00000007, 0x1FFFFFF0, CAN_MSG_ID_BOTH},                /* 可接收ID 0xXXXX_XXX7 或 0xXX7的数据，X为任意值 */
    {0x00000008, 0x1FFFFFF0, CAN_MSG_ID_BOTH},                /* 可接收ID 0xXXXX_XXX8 或 0xXX8的数据，X为任意值 */

    {0x00000009, 0x1FFFFFF0, CAN_MSG_ID_STD},                 /* 可接收ID 0xXX9的标准帧数据，X为任意值 */
    {0x0000000a, 0x1FFFFFF0, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXXX_XXXa的扩展帧数据，X为任意值 */
    {0x00000700, 0x1FFFF0FF, CAN_MSG_ID_BOTH},                /* 可接收ID 0xXXXX_X7XX 或 0x7XX的数据，X为任意值 */
    {0x0000c000, 0x1FFF0FFF, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXXX_CXXX 的扩展帧数据，X为任意值 */
    {0x000d0000, 0x1FF0FFFF, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXXX_DXXX 的扩展帧数据，X为任意值 */
    {0x00e00000, 0x1F0FFFFF, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXEX_XXXX 的扩展帧数据，X为任意值 */
    {0x0f000000, 0x10FFFFFF, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXXX_XXXX 的扩展帧数据，X为任意值 */
    {0x10000000, 0x0FFFFFFF, CAN_MSG_ID_EXT},                 /* 可接收ID 0xXXXX_XXXX 的扩展帧数据，X为任意值 */
};


static Can_cur_node_t s_canCurNode[CAN_INSTANCE_MAX] = {0}; /* 接收信息*/



/*!
 * @brief CAN_GetNormalBitrate 获取波特率
 *
 * @param[in] index: 波特率索引
 * @return 波特率配置
 */
static can_time_segment_t CAN_GetNormalBitrate(can_bitrate_t index)
{
    can_time_segment_t bitrate = {0};

    if (index < CAN_BITRATE_NUM)
    {
        bitrate = s_canBitrate[index];
    }

    return bitrate;
}


/*!
 * @brief CAN_GetDataBitrate 获取CANFD data波特率
 *
 * @param[in] index: 波特率索引
 * @return 波特率配置
 */
static can_time_segment_t CAN_GetDataBitrate(can_fd_bitrate_t index)
{
    can_time_segment_t bitrate = {0};

    if (index < CAN_FD_BITRATE_NUM)
    {
        bitrate = s_canfdBitrate[index];
    }

    return bitrate;
}


/*!
 * @brief CAN_HandleMsg 接收数据处理
 *
 * @param[in] instance: CAN 模块通道
 * @param[in] msgInfo: 接收数据
 * @return none
 */
static void CAN_HandleMsg(uint8_t instance, const can_msg_info_t *msgInfo)
{
    uint8_t i = 0;

    s_canCurNode[instance].recvCount++;     /* 节点信息更新 */
#if CAN_MSG_HANDLE_DIRECT                   /* 处理数据 */

   if (msgInfo->IDE)                                        /* 是否扩展帧 */
    {
        printf("CAN[%d] RecvCount:%06d ID:%08x DLC:%d FDF:%02d BRS:%02d", instance, s_canCurNode[instance].recvCount, msgInfo->ID, CAN_ComputePayloadSize(msgInfo->DLC), msgInfo->FDF, msgInfo->BRS);
    }
    else
    {
        printf("CAN[%d] RecvCount:%06d  ID:%03x DLC:%d FDF:%02d BRS:%02d", instance, s_canCurNode[instance].recvCount, msgInfo->ID, CAN_ComputePayloadSize(msgInfo->DLC), msgInfo->FDF, msgInfo->BRS);
    }

    if ((0U == msgInfo->RTR) && msgInfo->DLC)                /* 打印接收数据 */
    {
        printf("\r\tData: ");
        for (i = 0U; i<CAN_ComputePayloadSize(msgInfo->DLC); i++)
        {
            printf(" %02x", msgInfo->DATA[i]);
        }
    }
    printf("\r\n");
#endif
}

/*!
 * @brief CAN_EventCallback 中断回调函数， 可通过CAN_IRQHandler 了解参数具体含义
 *
 * @param[in] instance: CAN 模块通道
 * @param[in] event: 中断事件
 * @param[in] koer: 错误类型
 * @return 0: none
 */
void CAN_EventCallback(uint8_t instance, uint32_t event, uint32_t koer)
{
    can_msg_info_t recvMsg = {0};
    uint8_t recvData[64] = {0};

    if (event & (uint32_t)CAN_EVENT_BUS_ERROR)
    {
        printf("CAN[%d]e: EVEN: %x  KOER: %x\r\n", instance, event, koer);                /* 发生错误后，打印错误消息，仅用于调试 */
    }

    if (event & (uint32_t)CAN_EVENT_RECEIVE_DONE)                                         /* 接收数据 */
    {
        while (CAN_DRV_GetRbufStatus(instance))
        {
            recvMsg.DATA = recvData;                                                      /* 为接收数据索引中的数据域分配空间， 如果未给接收数据索引的数据域分配空间，直操作会触发Haltfault */
            if (STATUS_SUCCESS == CAN_DRV_Receive(instance, &recvMsg))
            {
                CAN_HandleMsg(instance, &recvMsg);
            }
        }
    }
}

/*!
 * @brief CAN_SendTest 用于发送CANFD数据
 *
 * @param[in] instance: CAN 模块通道
 * @param[in] type: 缓冲区选择
 *              - CAN_TRANSMIT_PRIMARY
 *              - CAN_TRANSMIT_SECONDARY
 * @return STATUS_SUCCESS: 发送成功   其他值： 发送失败
 */
status_t CAN_SendTest(uint8_t instance, can_transmit_buff_t type)
{
    status_t ret;
    volatile uint32_t timeout;
    uint8_t index;
    static can_msg_info_t s_sendMsg = {0};
    static uint8_t sendData[64] = {0};

    s_sendMsg.ID = 0x220;                                      /* CAN ID */
    s_sendMsg.IDE = 0;                                         /* 标准帧 */
    s_sendMsg.RTR = 0;                                         /* 非远程帧 */
    s_sendMsg.FDF = 1;                                         /* CANFD */
    s_sendMsg.BRS = 1;                                         /* 使用可变波特率 */
    s_sendMsg.DLC = (uint8_t)CAN_MSG_DLC_64_BYTES;             /* 数据长度 */
    s_sendMsg.DATA = sendData;                                 /* 分配空间 */

    for (index = 0; index < 64; index++)
    {
        s_sendMsg.DATA[index] = index;
    }

    do
    {
        ret = CAN_DRV_Send(instance, &s_sendMsg, type);
        timeout++;
    } while ((STATUS_BUSY == ret) && (timeout < 0xFFF));

    if (STATUS_SUCCESS == ret)
    {
        s_canCurNode[instance].sendCount++;     /* 节点信息更新 */
    }

    return ret;
}

/*!
 * @brief CAN 模块IO口初始化
 *
 * @param[in] instance: CAN 模块通道
 * @return none
 */
void CAN_InitGPIO(uint8_t instance)
{
    if (0 == instance)
    {
        GPIO_DRV_SetMuxModeSel(PORTE, 4U, PORT_MUX_ALT5);        /* CAN0_RX */
        GPIO_DRV_SetMuxModeSel(PORTE, 5U, PORT_MUX_ALT5);        /* CAN0_TX */
        GPIO_DRV_SetMuxModeSel(PORTE, 10U, PORT_MUX_ALT5);       /* 配置收发器standby功能 */
    }
    else if (1 == instance)
    {
        GPIO_DRV_SetMuxModeSel(PORTC, 6U, PORT_MUX_ALT3);         /* CAN1_RX */
        GPIO_DRV_SetMuxModeSel(PORTC, 7U, PORT_MUX_ALT3);         /* CAN1_TX */
        GPIO_DRV_SetMuxModeSel(PORTE, 6U, PORT_MUX_ALT5);         /* 配置收发器standby功能 */
    }
    else if (2 == instance)
    {
        GPIO_DRV_SetMuxModeSel(PORTC, 16U, PORT_MUX_ALT3);        /* CAN2_RX */
        GPIO_DRV_SetMuxModeSel(PORTC, 17U, PORT_MUX_ALT3);        /* CAN2_TX */
        GPIO_DRV_SetMuxModeSel(PORTC, 15U, PORT_MUX_ALT5);        /* 配置收发器standby功能 */
    }
    else if (3 == instance)
    {
        GPIO_DRV_SetMuxModeSel(PORTC, 12U, PORT_MUX_ALT5);         /* CAN3_RX */
        GPIO_DRV_SetMuxModeSel(PORTC, 13U, PORT_MUX_ALT5);         /* CAN3_TX */
        GPIO_DRV_SetMuxModeSel(PORTC, 11U, PORT_MUX_ALT5);        /* 配置收发器standby功能 */
    }
}

/*!
 * @brief  CANFD_Test 用于测试CANFD
 *
 * @param[in] none
 * @return none
 */
void CANFD_Test(void)
{
   uint8_t instance = 0U;
    can_user_config_t canCfg = {0};
    can_bitrate_t bitrateIndex = CAN_BITRATE_500K;           /* 低速波特率设置，500K，75% */
    can_fd_bitrate_t databitrateIndex = CAN_FD_BITRATE_2M;   /* 高速波特率设置，2M，75% */
    can_transmit_buff_t type = CAN_TRANSMIT_SECONDARY;       /* 发送缓冲区选择次缓冲 */

    canCfg.filterNum = 0U;                                   /* 过滤器数量 */
    canCfg.canMode = CAN_NORMAL_MODE;                        /* 正常模式 */
    canCfg.interruptEn = true;                               /* 使能中断 */
    canCfg.tsMode = CAN_TSMODE_FIFO;                         /* 选择FIFO模式 */
    canCfg.tsAmount = CAN_TRANSMIT_SEC_ALL;                  /* TSALL */
    canCfg.tpss = false;                                     /* 失能PTB单次发送 */
    canCfg.tsss = false;                                     /* 失能STB单次发送 */
    canCfg.rom = CAN_ROM_OVER_WRITE;                         /* 接收缓冲区溢出后，新数据会覆盖旧数据 */
    canCfg.errorWarningLimit = 0x0BU;                        /* 错误警告限制，当TECNT|RECNT超过限制值，会触发EIF错误中断 */
    canCfg.fdModeEn = true;                                  /* 使能CANFD */
    canCfg.fdIsoEn = true;                                   /* 使能 ISO CANFD */
    canCfg.tdcEn = true;                                     /* 使能TDC ,如果CANFD数据域的波特率大于1MHz，建议使能*/
    canCfg.sspOffset = 16;                                   /* 建议SSPOFF配置等于tSeg_1 用户可以根据实际情况配置该值*/
    canCfg.fdBitrate = CAN_GetDataBitrate(databitrateIndex); /* 高速波特率配置 */
#if CAN_TIME_STAMP_ENABLE
    canCfg.timeStampEn = true;                               /* 使能时间戳 */
    canCfg.timeStampClkSrc = CAN_TIME_STAMP_CLK_SRC_EXT;     /* 时间戳时钟源选择 */
    canCfg.timeStampClkDiv = CAN_TIME_STAMP_CLK_DIV_8;       /* 时间戳时钟分频 */
    canCfg.timeStampPos = CAN_TIME_STAMP_SOF;                /* 时间戳采样位置 */
#endif
    canCfg.dmaRecvEn = false;                                 /* 不使用DMA */
    canCfg.memEccEn = false;                                  /* 失能存储ECC */
    canCfg.wakeupIntEn = false;                               /* 失能CAN低电平唤醒中断 */
    canCfg.busOffRecDisable = false;                          /* 失能自动总线关闭恢复，busoff产生后，会遵循ISO 11898规范 */
    canCfg.interruptMask = CAN_IRQ_ALL_ENABLE_MSK;            /* 使能所有中断掩码 */
    canCfg.bitrate = CAN_GetNormalBitrate(bitrateIndex);      /* 低速波特率配置 */
    canCfg.filterList = (can_filter_config_t *)s_canFilterList;/* 过滤器配置 */
    canCfg.callback = (can_callback_t)CAN_EventCallback;

    CAN_InitGPIO(instance);                                   /* CAN模块IO口初始化*/
    (void)CAN_DRV_Init(instance, &canCfg);                    /* CAN模块初始化*/
     GPIO_LedInit();                                          /* LED IO初始化 */
     while (1)
     {
        CAN_SendTest(instance, type);                         /* 发送测试 */
        OSIF_TimeDelay(500);
        LED3_TOGGLE;                                         /* 翻转LED3 */
     }
}
