From 0c82d334aa10443d2305fd5ce722b7cd233b6b54 Mon Sep 17 00:00:00 2001 From: pandafeng1999 Date: Thu, 9 Oct 2025 13:17:35 +0800 Subject: [PATCH 01/15] =?UTF-8?q?=E6=B7=BB=E5=8A=A0H7=20fdcan=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 715 ++++++++++++++++++ .../libraries/HAL_Drivers/drivers/drv_fdcan.h | 46 ++ 2 files changed, 761 insertions(+) create mode 100644 bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c create mode 100644 bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c new file mode 100644 index 00000000000..fc20f3043c8 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-02-24 heyuan the first version + * 2020-08-17 malongwei Fix something + */ + +#include "drv_fdcan.h" + +#if defined(RT_USING_CAN) && defined(RT_CAN_USING_CANFD) + +#if defined(BSP_USING_FDCAN1) || defined(BSP_USING_FDCAN2) + + +//#define DRV_DEBUG +#define LOG_TAG "drv_fdcan" +#include + +#ifdef BSP_USING_FDCAN1 +static stm32_fdcan_t st_DrvCan1= +{ + .name = "fdcan1", + .fdcanHandle.Instance = FDCAN1, +}; +#endif + +#ifdef BSP_USING_FDCAN2 +static stm32_fdcan_t st_DrvCan2= +{ + .name = "fdcan2", + .fdcanHandle.Instance = FDCAN2, +}; +#endif + +/* 40MHz CAN clock */ +static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] = +{ + {CAN1MBaud, {1, 29, 10, 8, 0}}, /* 1Mbps */ + {CAN800kBaud, {1, 37, 12, 8, 0}}, /* 800kbps */ + {CAN500kBaud, {1, 59, 20, 8, 0}}, /* 500kbps */ + {CAN250kBaud, {2, 63, 16, 8, 0}}, /* 250kbps */ + {CAN125kBaud, {5, 55, 8, 8, 0}}, /* 125kbps */ + {CAN100kBaud, {8, 41, 8, 8, 0}}, /* 100kbps */ + {CAN50kBaud, {16, 41, 8, 8, 0}}, /* 50kbps */ + {CAN20kBaud, {40,41,8,8,0}}, /* 20kbps */ + {CAN10kBaud, {100,31,8,8,0}} /* 10kbps */ +}; +/* 40MHz CAN clock */ +static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] = +{ + {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */ + {CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */ + {CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */ + {CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */ + {CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */ + {CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */ +}; +/** + * @brief Convert CAN-FD frame length to DLC (Data Length Code) + * + * CAN-FD DLC mapping (length → DLC): + * Length 0~8 -> DLC 0~8 + * Length 9~12 -> DLC 9 + * Length 13~16 -> DLC 10 + * Length 17~20 -> DLC 11 + * Length 21~24 -> DLC 12 + * Length 25~32 -> DLC 13 + * Length 33~48 -> DLC 14 + * Length 49~64 -> DLC 15 + * + * @param len Frame length in bytes (0~64) + * @return DLC code (0~15) + */ +uint8_t length_to_dlc(uint8_t len) { + return (len <= 8) ? len : + (len <= 12) ? 9 : + (len <= 16) ? 10 : + (len <= 20) ? 11 : + (len <= 24) ? 12 : + (len <= 32) ? 13 : + (len <= 48) ? 14 : 15; +} + +/** + * @brief 获取 FDCAN 仲裁段波特率配置索引 + */ +static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate) +{ + uint32_t len = sizeof(st_FDCAN_ArbTiming) / sizeof(st_FDCAN_ArbTiming[0]); + + for (uint32_t i = 0; i < len; i++) + { + if (st_FDCAN_ArbTiming[i].u32Baudrate == baud_rate) + return i; + } + return -1; +} + +/** + * @brief 获取 FDCAN 数据段波特率配置索引 + */ +static uint32_t _inline_get_DataBaudIndex(uint32_t baud_rate) +{ + uint32_t len = sizeof(st_FDCAN_DataTiming) / sizeof(st_FDCAN_DataTiming[0]); + + for (uint32_t i = 0; i < len; i++) + { + if (st_FDCAN_DataTiming[i].u32Baudrate == baud_rate) + return i; + } + return -1; +} + +static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configure *cfg) +{ + stm32_fdcan_t *pdrv_can; + rt_uint32_t tmp_u32Index; + + RT_ASSERT(can); + RT_ASSERT(cfg); + + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + + RT_ASSERT(pdrv_can); + + pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_FD_BRS; + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + pdrv_can->fdcanHandle.Init.AutoRetransmission = ENABLE; + + pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE; + pdrv_can->fdcanHandle.Init.ProtocolException = ENABLE; + + switch (cfg->mode) + { + case RT_CAN_MODE_NORMAL: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + break; + case RT_CAN_MODE_LISTEN: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING; + break; + case RT_CAN_MODE_LOOPBACK: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + break; + default: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + break; + } + + uint32_t arb_idx = _inline_get_ArbBaudIndex(cfg->baud_rate); + if (arb_idx == (uint32_t)-1) + { + LOG_E("not support %d baudrate", cfg->baud_rate); + return -RT_ERROR; + } + /* 仲裁段 */ + pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler; + pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw; + pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1; + pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg2; +#ifdef RT_CAN_USING_CANFD + if(cfg->enable_canfd) { + uint32_t data_idx = _inline_get_DataBaudIndex(cfg->baud_rate_fd); + if (data_idx == (uint32_t)-1) + { + LOG_E("not support %d baudrate", cfg->baud_rate_fd); + return -RT_ERROR; + } + /* 数据段 */ + pdrv_can->fdcanHandle.Init.DataPrescaler = st_FDCAN_DataTiming[data_idx].cam_bit_timing.prescaler; + pdrv_can->fdcanHandle.Init.DataSyncJumpWidth = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_sjw; + pdrv_can->fdcanHandle.Init.DataTimeSeg1 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg1; + pdrv_can->fdcanHandle.Init.DataTimeSeg2 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg2; + } +#endif + /* Configure Message RAM */ + if(pdrv_can->fdcanHandle.Instance == FDCAN1) + { + pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0; + } + else + { + pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280; + } + pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2; + pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2; + pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1; + pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.RxFifo1ElmtsNbr = 0; + pdrv_can->fdcanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0; + pdrv_can->fdcanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.TxEventsNbr = 0; + pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3; + pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0; + pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_64; + + if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK) + { + return -RT_ERROR; + } + /* default filter config */ + HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig); + /*init fdcan tx header*/ + pdrv_can->TxHeader.Identifier = 0x000000; + pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; + pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; + pdrv_can->TxHeader.DataLength = FDCAN_DLC_BYTES_8; + pdrv_can->TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF; + pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + pdrv_can->TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + pdrv_can->TxHeader.MessageMarker = 0; + /* can start */ + HAL_FDCAN_Start(&pdrv_can->fdcanHandle); + return RT_EOK; +} + +static rt_err_t _inline_can_filter_config(stm32_fdcan_t *pdrv_can,struct rt_can_filter_config *puser_can_filter_config) +{ + int tmp_i32IndexCount; + RT_ASSERT(pdrv_can); + RT_ASSERT(puser_can_filter_config); + /* get default filter */ + for (tmp_i32IndexCount = 0; tmp_i32IndexCount < puser_can_filter_config->count; tmp_i32IndexCount++) + { + pdrv_can->FilterConfig.FilterIndex = puser_can_filter_config->items[tmp_i32IndexCount].hdr_bank; + pdrv_can->FilterConfig.FilterID1 = puser_can_filter_config->items[tmp_i32IndexCount].id; + pdrv_can->FilterConfig.FilterID2 = puser_can_filter_config->items[tmp_i32IndexCount].mask; + if(puser_can_filter_config->items[tmp_i32IndexCount].ide == RT_CAN_EXTID) + { + pdrv_can->FilterConfig.IdType = FDCAN_EXTENDED_ID; + } + else + { + pdrv_can->FilterConfig.IdType = FDCAN_STANDARD_ID; + } + pdrv_can->FilterConfig.FilterType = FDCAN_FILTER_MASK; + pdrv_can->FilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + if(HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig) != HAL_OK) + { + return -RT_ERROR; + } + } + return RT_EOK; +} + +static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *arg) +{ + + rt_uint32_t argval; + stm32_fdcan_t *pdrv_can; + struct rt_can_filter_config *filter_cfg; + RT_ASSERT(can != RT_NULL); + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + RT_ASSERT(pdrv_can != RT_NULL); + switch (cmd) { + case RT_DEVICE_CTRL_CLR_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE); + } else if (argval == RT_DEVICE_FLAG_INT_TX) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_FIFO_EMPTY); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE); + } else if (argval == RT_DEVICE_CAN_INT_ERR) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_LOGGING_OVERFLOW); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR); + } + break; + case RT_DEVICE_CTRL_SET_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, + FDCAN_INTERRUPT_LINE0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 1); + HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 1); + HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); + } + } else if (argval == RT_DEVICE_FLAG_INT_TX) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER1); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER2); + + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); + } + } else if (argval == RT_DEVICE_CAN_INT_ERR) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, + FDCAN_INTERRUPT_LINE1); + + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, 0); + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); + } + } + break; + case RT_CAN_CMD_SET_FILTER: + if (RT_NULL == arg) { + /* default filter config */ + HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle, &pdrv_can->FilterConfig); + } else { + filter_cfg = (struct rt_can_filter_config *) arg; + _inline_can_filter_config(pdrv_can, filter_cfg); + } + break; + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_NORMAL && + argval != RT_CAN_MODE_LISTEN && + argval != RT_CAN_MODE_LOOPBACK && + argval != RT_CAN_MODE_LOOPBACKANLISTEN) { + return -RT_ERROR; + } + if (argval != pdrv_can->device.config.mode) { + pdrv_can->device.config.mode = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + break; + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + /* 查找仲裁相位波特率是否存在 */ + uint32_t arb_idx = _inline_get_ArbBaudIndex(argval); + if (arb_idx == (uint32_t) -1) { + return -RT_ERROR; // 未找到匹配波特率 + } + if (argval != pdrv_can->device.config.baud_rate) { + pdrv_can->device.config.baud_rate = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + break; + + case RT_CAN_CMD_SET_PRIV: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_PRIV && + argval != RT_CAN_MODE_NOPRIV) { + return -RT_ERROR; + } + if (argval != pdrv_can->device.config.privmode) { + pdrv_can->device.config.privmode = argval; + + return RT_EOK; + } + break; + case RT_CAN_CMD_GET_STATUS: { + rt_uint32_t tmp_u32Errcount; + rt_uint32_t tmp_u32status; + tmp_u32Errcount = pdrv_can->fdcanHandle.Instance->ECR; + tmp_u32status = pdrv_can->fdcanHandle.Instance->PSR; + + pdrv_can->device.status.rcverrcnt = (tmp_u32Errcount >> 8) & 0x000000ff; + pdrv_can->device.status.snderrcnt = (tmp_u32Errcount) & 0x000000ff; + pdrv_can->device.status.lasterrtype = tmp_u32status & 0x000000007; + + rt_memcpy(arg, &pdrv_can->device.status, sizeof(pdrv_can->device.status)); + } + break; + case RT_CAN_CMD_SET_BAUD_FD: { + /* 查找仲裁相位波特率是否存在 */ + uint32_t data_idx = _inline_get_DataBaudIndex(argval); + if (data_idx == (uint32_t) -1) { + return -RT_ERROR; // 未找到匹配波特率 + } + if (argval != pdrv_can->device.config.baud_rate_fd) { + pdrv_can->device.config.baud_rate_fd = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + } + } + + + return RT_EOK; +} + +static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num) +{ + + stm32_fdcan_t *pdrv_can; + struct rt_can_msg *pmsg; + uint32_t tmp_u32DataLen; + RT_ASSERT(can); + RT_ASSERT(buf); + + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + + RT_ASSERT(pdrv_can); + + pmsg = (struct rt_can_msg *) buf; + + /* Check the parameters */ + tmp_u32DataLen = length_to_dlc( pmsg->len); + + if(pmsg->ide == RT_CAN_EXTID) + { + pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; + } + else + { + pdrv_can->TxHeader.IdType = FDCAN_STANDARD_ID; + } + + if (RT_CAN_DTR == pmsg->rtr) + { + pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; + } + else + { + pdrv_can->TxHeader.TxFrameType = FDCAN_REMOTE_FRAME; + } + + + pdrv_can->TxHeader.Identifier = pmsg->id; + + pdrv_can->TxHeader.DataLength = tmp_u32DataLen; + + + if (pmsg->fd_frame == 1) + { + pdrv_can->TxHeader.FDFormat = FDCAN_FD_CAN; + } + else { + pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + } + + if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK) + { + return -RT_ERROR; + } + else + { + /* Request transmission */ + HAL_FDCAN_EnableTxBufferRequest(&pdrv_can->fdcanHandle,FDCAN_TX_BUFFER0+box_num); + return RT_EOK; + } +} + +static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) +{ + //测试 + // fifo = 0; + struct rt_can_msg *pmsg; + stm32_fdcan_t *pdrv_can; + + RT_ASSERT(can); + RT_ASSERT(buf); + + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + pmsg = (struct rt_can_msg *) buf; + if(HAL_FDCAN_GetRxMessage(&pdrv_can->fdcanHandle,FDCAN_RX_FIFO0+fifo, &pdrv_can->RxHeader, pmsg->data) != HAL_OK) + { + return 0; + } + else + { + if(pdrv_can->RxHeader.IdType == FDCAN_EXTENDED_ID) + { + pmsg->ide = RT_CAN_EXTID; + } + else + { + pmsg->ide = RT_CAN_STDID; + } + + if(pdrv_can->RxHeader.RxFrameType == FDCAN_DATA_FRAME) + { + pmsg->rtr = RT_CAN_DTR; + } + else + { + pmsg->rtr = RT_CAN_RTR; + } + pmsg->id = pdrv_can->RxHeader.Identifier; + + // pmsg->len = (pdrv_can->RxHeader.DataLength >> 16) & 0x0f; + pmsg->len = pdrv_can->RxHeader.DataLength; + pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; + + #ifdef RT_CAN_USING_CANFD + pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20; + pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;; + #endif + + return sizeof(struct rt_can_msg); + } +} + +static const struct rt_can_ops _can_ops = +{ + _inline_can_config, + _inline_can_control, + _inline_can_sendmsg, + _inline_can_recvmsg, +}; + +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +{ + if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) + { + if(hfdcan->Instance == FDCAN1) + { +#ifdef BSP_USING_FDCAN1 + //CAN1 + /* Retreive Rx messages from RX FIFO0 */ + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_RX_IND | 0 << 8); +#endif + } + else + { +#ifdef BSP_USING_FDCAN2 + //CAN2 + /* Retreive Rx messages from RX FIFO0 */ + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_RX_IND | 0 << 8); +#endif + } + } +} + +void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ + if(hfdcan->Instance == FDCAN1) + { +#ifdef BSP_USING_FDCAN1 + //can1 + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); +#endif + } + else + { +#ifdef BSP_USING_FDCAN2 + //can2 + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); +#endif + } + +} + + +void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) +{ + if(hfdcan->Instance == FDCAN1) + { + //can1 + } + else + { + //can2 + } +} + +void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ + +} + +void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) +{ + rt_uint32_t tmp_u32Errcount; + rt_uint32_t tmp_u32status; + uint32_t ret = HAL_FDCAN_GetError(hfdcan); + + if(hfdcan->Instance == FDCAN1) + { +#ifdef BSP_USING_FDCAN1 + //can1 + if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && + (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) + { + //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; + st_DrvCan1.device.status.errcode = 0xff; + } + else + { + tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR; + tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR; + + st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; + st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; + st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007; + } +#endif /*BSP_USING_FDCAN1*/ + } + else + { +#ifdef BSP_USING_FDCAN2 + if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && + (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) + { + //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; + st_DrvCan2.device.status.errcode = 0xff; + } + else + { + //can2 + tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR; + tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR; + st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; + st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; + st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007; + } +#endif /*BSP_USING_FDCAN2*/ + } +} + +#ifdef BSP_USING_FDCAN1 + +void FDCAN1_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ +{ + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); + rt_interrupt_leave(); +} + +void FDCAN1_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ +{ + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); + rt_interrupt_leave(); +} + +#endif /*BSP_USING_FDCAN1*/ + +#ifdef BSP_USING_FDCAN2 +void FDCAN2_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ +{ + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); + rt_interrupt_leave(); +} + +void FDCAN2_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ +{ + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); + rt_interrupt_leave(); +} +#endif/*BSP_USING_FDCAN2*/ + + +static int rt_hw_can_init(void) +{ + struct can_configure config; + config.baud_rate = CAN1MBaud; + config.msgboxsz = 48; + config.sndboxnumber = 1; + config.mode = RT_CAN_MODE_NORMAL; + config.privmode = RT_CAN_MODE_NOPRIV; + config.ticks = 50; +#ifdef RT_CAN_USING_HDR + config.maxhdr = 14; +#endif +#ifdef RT_CAN_USING_CANFD + config.baud_rate_fd = CAN1MBaud * 8; + config.enable_canfd = 1; +#endif + + /* config default filter */ + FDCAN_FilterTypeDef sFilterConfig; + sFilterConfig.IdType = FDCAN_STANDARD_ID; + sFilterConfig.FilterIndex = 0; + sFilterConfig.FilterType = FDCAN_FILTER_MASK; + sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + sFilterConfig.FilterID1 = 0; + sFilterConfig.FilterID2 = 0x7FF; + +#ifdef BSP_USING_FDCAN1 + + st_DrvCan1.FilterConfig = sFilterConfig; + st_DrvCan1.device.config = config; + + /* register FDCAN1 device */ + rt_hw_can_register(&st_DrvCan1.device, st_DrvCan1.name, &_can_ops, &st_DrvCan1); +#endif /* BSP_USING_FDCAN1 */ + +#ifdef BSP_USING_FDCAN2 + st_DrvCan2.FilterConfig = sFilterConfig; + st_DrvCan2.device.config = config; + + /* register FDCAN1 device */ + rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2); +#endif /* BSP_USING_FDCAN2 */ + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_can_init); + +#endif /* BSP_USING_FDCAN1 || BSP_USING_FDCAN2 */ +#endif /* RT_USING_CAN */ \ No newline at end of file diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h new file mode 100644 index 00000000000..72c3fff81e7 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-02-24 heyuan the first version + * 2020-08-17 malongwei Fix something + */ + +#ifndef __DRV_FDCAN_H__ +#define __DRV_FDCAN_H__ + +#include +#include + +#if defined(RT_USING_CAN) && defined(RT_CAN_USING_CANFD) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + const char *name; + FDCAN_HandleTypeDef fdcanHandle; + FDCAN_RxHeaderTypeDef RxHeader; + FDCAN_TxHeaderTypeDef TxHeader; + uint8_t u8RxDataBuffer[8]; + uint8_t u8TxDataBuufer[8]; + FDCAN_FilterTypeDef FilterConfig; /*FDCAN filter*/ + struct rt_can_device device; /* inherit from can device */ +} stm32_fdcan_t; + +typedef struct { + uint32_t u32Baudrate; + struct rt_can_bit_timing cam_bit_timing; +}stm32_fdcan_timing_t; + +#ifdef __cplusplus +} +#endif + +#endif /* RT_USING_CAN */ +#endif /* __DRV_FDCAN_H__ */ From 15a097b5765298271e06a500019c8c97d448f214 Mon Sep 17 00:00:00 2001 From: pandafeng1999 Date: Thu, 9 Oct 2025 13:18:41 +0800 Subject: [PATCH 02/15] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20SConscript=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/libraries/HAL_Drivers/drivers/SConscript | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript index a9c77286c15..456327087b2 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript @@ -50,7 +50,10 @@ if GetDepend(['RT_USING_DAC']): src += ['drv_dac.c'] if GetDepend(['RT_USING_CAN']): - src += ['drv_can.c'] + if GetDepend(['SOC_SERIES_STM32H7']): + src += ['drv_fdcan.c'] + else: + src += ['drv_can.c'] if GetDepend(['RT_USING_PM']): src += ['drv_pm.c'] From 3d7e3d62b7a1f6da4da1f33ff1a75c7dee1df4f5 Mon Sep 17 00:00:00 2001 From: pandafeng1999 Date: Fri, 10 Oct 2025 13:50:37 +0800 Subject: [PATCH 03/15] Code Format --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 986 +++++++++--------- .../libraries/HAL_Drivers/drivers/drv_fdcan.h | 20 +- 2 files changed, 503 insertions(+), 503 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index fc20f3043c8..53cf0d53142 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -23,41 +23,41 @@ #ifdef BSP_USING_FDCAN1 static stm32_fdcan_t st_DrvCan1= { - .name = "fdcan1", - .fdcanHandle.Instance = FDCAN1, + .name = "fdcan1", + .fdcanHandle.Instance = FDCAN1, }; #endif #ifdef BSP_USING_FDCAN2 static stm32_fdcan_t st_DrvCan2= { - .name = "fdcan2", - .fdcanHandle.Instance = FDCAN2, + .name = "fdcan2", + .fdcanHandle.Instance = FDCAN2, }; #endif /* 40MHz CAN clock */ static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] = { - {CAN1MBaud, {1, 29, 10, 8, 0}}, /* 1Mbps */ - {CAN800kBaud, {1, 37, 12, 8, 0}}, /* 800kbps */ - {CAN500kBaud, {1, 59, 20, 8, 0}}, /* 500kbps */ - {CAN250kBaud, {2, 63, 16, 8, 0}}, /* 250kbps */ - {CAN125kBaud, {5, 55, 8, 8, 0}}, /* 125kbps */ - {CAN100kBaud, {8, 41, 8, 8, 0}}, /* 100kbps */ - {CAN50kBaud, {16, 41, 8, 8, 0}}, /* 50kbps */ - {CAN20kBaud, {40,41,8,8,0}}, /* 20kbps */ - {CAN10kBaud, {100,31,8,8,0}} /* 10kbps */ + {CAN1MBaud, {1, 29, 10, 8, 0}}, /* 1Mbps */ + {CAN800kBaud, {1, 37, 12, 8, 0}}, /* 800kbps */ + {CAN500kBaud, {1, 59, 20, 8, 0}}, /* 500kbps */ + {CAN250kBaud, {2, 63, 16, 8, 0}}, /* 250kbps */ + {CAN125kBaud, {5, 55, 8, 8, 0}}, /* 125kbps */ + {CAN100kBaud, {8, 41, 8, 8, 0}}, /* 100kbps */ + {CAN50kBaud, {16, 41, 8, 8, 0}}, /* 50kbps */ + {CAN20kBaud, {40,41,8,8,0}}, /* 20kbps */ + {CAN10kBaud, {100,31,8,8,0}} /* 10kbps */ }; /* 40MHz CAN clock */ static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] = { - {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */ - {CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */ - {CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */ - {CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */ - {CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */ - {CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */ + {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */ + {CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */ + {CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */ + {CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */ + {CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */ + {CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */ }; /** * @brief Convert CAN-FD frame length to DLC (Data Length Code) @@ -76,13 +76,13 @@ static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] = * @return DLC code (0~15) */ uint8_t length_to_dlc(uint8_t len) { - return (len <= 8) ? len : - (len <= 12) ? 9 : - (len <= 16) ? 10 : - (len <= 20) ? 11 : - (len <= 24) ? 12 : - (len <= 32) ? 13 : - (len <= 48) ? 14 : 15; + return (len <= 8) ? len : + (len <= 12) ? 9 : + (len <= 16) ? 10 : + (len <= 20) ? 11 : + (len <= 24) ? 12 : + (len <= 32) ? 13 : + (len <= 48) ? 14 : 15; } /** @@ -90,14 +90,14 @@ uint8_t length_to_dlc(uint8_t len) { */ static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate) { - uint32_t len = sizeof(st_FDCAN_ArbTiming) / sizeof(st_FDCAN_ArbTiming[0]); - - for (uint32_t i = 0; i < len; i++) - { - if (st_FDCAN_ArbTiming[i].u32Baudrate == baud_rate) - return i; - } - return -1; + uint32_t len = sizeof(st_FDCAN_ArbTiming) / sizeof(st_FDCAN_ArbTiming[0]); + + for (uint32_t i = 0; i < len; i++) + { + if (st_FDCAN_ArbTiming[i].u32Baudrate == baud_rate) + return i; + } + return -1; } /** @@ -105,365 +105,365 @@ static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate) */ static uint32_t _inline_get_DataBaudIndex(uint32_t baud_rate) { - uint32_t len = sizeof(st_FDCAN_DataTiming) / sizeof(st_FDCAN_DataTiming[0]); - - for (uint32_t i = 0; i < len; i++) - { - if (st_FDCAN_DataTiming[i].u32Baudrate == baud_rate) - return i; - } - return -1; + uint32_t len = sizeof(st_FDCAN_DataTiming) / sizeof(st_FDCAN_DataTiming[0]); + + for (uint32_t i = 0; i < len; i++) + { + if (st_FDCAN_DataTiming[i].u32Baudrate == baud_rate) + return i; + } + return -1; } static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configure *cfg) { - stm32_fdcan_t *pdrv_can; - rt_uint32_t tmp_u32Index; - - RT_ASSERT(can); - RT_ASSERT(cfg); - - pdrv_can = (stm32_fdcan_t *)can->parent.user_data; - - RT_ASSERT(pdrv_can); - - pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_FD_BRS; - pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; - pdrv_can->fdcanHandle.Init.AutoRetransmission = ENABLE; - - pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE; - pdrv_can->fdcanHandle.Init.ProtocolException = ENABLE; - - switch (cfg->mode) - { - case RT_CAN_MODE_NORMAL: - pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; - break; - case RT_CAN_MODE_LISTEN: - pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING; - break; - case RT_CAN_MODE_LOOPBACK: - pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; - break; - default: - pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; - break; - } - - uint32_t arb_idx = _inline_get_ArbBaudIndex(cfg->baud_rate); - if (arb_idx == (uint32_t)-1) - { - LOG_E("not support %d baudrate", cfg->baud_rate); - return -RT_ERROR; - } - /* 仲裁段 */ - pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler; - pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw; - pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1; - pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg2; + stm32_fdcan_t *pdrv_can; + rt_uint32_t tmp_u32Index; + + RT_ASSERT(can); + RT_ASSERT(cfg); + + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + + RT_ASSERT(pdrv_can); + + pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_FD_BRS; + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + pdrv_can->fdcanHandle.Init.AutoRetransmission = ENABLE; + + pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE; + pdrv_can->fdcanHandle.Init.ProtocolException = ENABLE; + + switch (cfg->mode) + { + case RT_CAN_MODE_NORMAL: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + break; + case RT_CAN_MODE_LISTEN: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING; + break; + case RT_CAN_MODE_LOOPBACK: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + break; + default: + pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL; + break; + } + + uint32_t arb_idx = _inline_get_ArbBaudIndex(cfg->baud_rate); + if (arb_idx == (uint32_t)-1) + { + LOG_E("not support %d baudrate", cfg->baud_rate); + return -RT_ERROR; + } + /* 仲裁段 */ + pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler; + pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw; + pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1; + pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg2; #ifdef RT_CAN_USING_CANFD - if(cfg->enable_canfd) { - uint32_t data_idx = _inline_get_DataBaudIndex(cfg->baud_rate_fd); - if (data_idx == (uint32_t)-1) - { - LOG_E("not support %d baudrate", cfg->baud_rate_fd); - return -RT_ERROR; - } - /* 数据段 */ - pdrv_can->fdcanHandle.Init.DataPrescaler = st_FDCAN_DataTiming[data_idx].cam_bit_timing.prescaler; - pdrv_can->fdcanHandle.Init.DataSyncJumpWidth = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_sjw; - pdrv_can->fdcanHandle.Init.DataTimeSeg1 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg1; - pdrv_can->fdcanHandle.Init.DataTimeSeg2 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg2; - } + if(cfg->enable_canfd) { + uint32_t data_idx = _inline_get_DataBaudIndex(cfg->baud_rate_fd); + if (data_idx == (uint32_t)-1) + { + LOG_E("not support %d baudrate", cfg->baud_rate_fd); + return -RT_ERROR; + } + /* 数据段 */ + pdrv_can->fdcanHandle.Init.DataPrescaler = st_FDCAN_DataTiming[data_idx].cam_bit_timing.prescaler; + pdrv_can->fdcanHandle.Init.DataSyncJumpWidth = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_sjw; + pdrv_can->fdcanHandle.Init.DataTimeSeg1 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg1; + pdrv_can->fdcanHandle.Init.DataTimeSeg2 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg2; + } #endif - /* Configure Message RAM */ - if(pdrv_can->fdcanHandle.Instance == FDCAN1) - { - pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0; - } - else - { - pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280; - } - pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2; - pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2; - pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1; - pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; - pdrv_can->fdcanHandle.Init.RxFifo1ElmtsNbr = 0; - pdrv_can->fdcanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; - pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0; - pdrv_can->fdcanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_64; - pdrv_can->fdcanHandle.Init.TxEventsNbr = 0; - pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3; - pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0; - pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; - pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_64; - - if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK) - { - return -RT_ERROR; - } - /* default filter config */ - HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig); - /*init fdcan tx header*/ - pdrv_can->TxHeader.Identifier = 0x000000; - pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; - pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; - pdrv_can->TxHeader.DataLength = FDCAN_DLC_BYTES_8; - pdrv_can->TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; - pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF; - pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; - pdrv_can->TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; - pdrv_can->TxHeader.MessageMarker = 0; - /* can start */ - HAL_FDCAN_Start(&pdrv_can->fdcanHandle); - return RT_EOK; + /* Configure Message RAM */ + if(pdrv_can->fdcanHandle.Instance == FDCAN1) + { + pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0; + } + else + { + pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280; + } + pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2; + pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2; + pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1; + pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.RxFifo1ElmtsNbr = 0; + pdrv_can->fdcanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0; + pdrv_can->fdcanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_64; + pdrv_can->fdcanHandle.Init.TxEventsNbr = 0; + pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3; + pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0; + pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_64; + + if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK) + { + return -RT_ERROR; + } + /* default filter config */ + HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig); + /*init fdcan tx header*/ + pdrv_can->TxHeader.Identifier = 0x000000; + pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; + pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; + pdrv_can->TxHeader.DataLength = FDCAN_DLC_BYTES_8; + pdrv_can->TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF; + pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + pdrv_can->TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + pdrv_can->TxHeader.MessageMarker = 0; + /* can start */ + HAL_FDCAN_Start(&pdrv_can->fdcanHandle); + return RT_EOK; } static rt_err_t _inline_can_filter_config(stm32_fdcan_t *pdrv_can,struct rt_can_filter_config *puser_can_filter_config) { - int tmp_i32IndexCount; - RT_ASSERT(pdrv_can); - RT_ASSERT(puser_can_filter_config); - /* get default filter */ - for (tmp_i32IndexCount = 0; tmp_i32IndexCount < puser_can_filter_config->count; tmp_i32IndexCount++) - { - pdrv_can->FilterConfig.FilterIndex = puser_can_filter_config->items[tmp_i32IndexCount].hdr_bank; - pdrv_can->FilterConfig.FilterID1 = puser_can_filter_config->items[tmp_i32IndexCount].id; - pdrv_can->FilterConfig.FilterID2 = puser_can_filter_config->items[tmp_i32IndexCount].mask; - if(puser_can_filter_config->items[tmp_i32IndexCount].ide == RT_CAN_EXTID) - { - pdrv_can->FilterConfig.IdType = FDCAN_EXTENDED_ID; - } - else - { - pdrv_can->FilterConfig.IdType = FDCAN_STANDARD_ID; - } - pdrv_can->FilterConfig.FilterType = FDCAN_FILTER_MASK; - pdrv_can->FilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; - if(HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig) != HAL_OK) - { - return -RT_ERROR; - } - } - return RT_EOK; + int tmp_i32IndexCount; + RT_ASSERT(pdrv_can); + RT_ASSERT(puser_can_filter_config); + /* get default filter */ + for (tmp_i32IndexCount = 0; tmp_i32IndexCount < puser_can_filter_config->count; tmp_i32IndexCount++) + { + pdrv_can->FilterConfig.FilterIndex = puser_can_filter_config->items[tmp_i32IndexCount].hdr_bank; + pdrv_can->FilterConfig.FilterID1 = puser_can_filter_config->items[tmp_i32IndexCount].id; + pdrv_can->FilterConfig.FilterID2 = puser_can_filter_config->items[tmp_i32IndexCount].mask; + if(puser_can_filter_config->items[tmp_i32IndexCount].ide == RT_CAN_EXTID) + { + pdrv_can->FilterConfig.IdType = FDCAN_EXTENDED_ID; + } + else + { + pdrv_can->FilterConfig.IdType = FDCAN_STANDARD_ID; + } + pdrv_can->FilterConfig.FilterType = FDCAN_FILTER_MASK; + pdrv_can->FilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + if(HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig) != HAL_OK) + { + return -RT_ERROR; + } + } + return RT_EOK; } static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *arg) { - rt_uint32_t argval; - stm32_fdcan_t *pdrv_can; - struct rt_can_filter_config *filter_cfg; - RT_ASSERT(can != RT_NULL); - pdrv_can = (stm32_fdcan_t *)can->parent.user_data; - RT_ASSERT(pdrv_can != RT_NULL); - switch (cmd) { - case RT_DEVICE_CTRL_CLR_INT: - argval = (rt_uint32_t) arg; - if (argval == RT_DEVICE_FLAG_INT_RX) { - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE); - } else if (argval == RT_DEVICE_FLAG_INT_TX) { - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_FIFO_EMPTY); - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE); - } else if (argval == RT_DEVICE_CAN_INT_ERR) { - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING); - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE); - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_LOGGING_OVERFLOW); - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF); - HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR); - } - break; - case RT_DEVICE_CTRL_SET_INT: - argval = (rt_uint32_t) arg; - if (argval == RT_DEVICE_FLAG_INT_RX) { - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, - FDCAN_INTERRUPT_LINE0); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); - - if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { - HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 1); - HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); - } else { - HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 1); - HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); - } - } else if (argval == RT_DEVICE_FLAG_INT_TX) { - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_LINE1); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER1); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER2); - - if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { - HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); - HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); - } else { - HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); - HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); - } - } else if (argval == RT_DEVICE_CAN_INT_ERR) { - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, FDCAN_INTERRUPT_LINE1); - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, FDCAN_INTERRUPT_LINE1); - HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, - FDCAN_INTERRUPT_LINE1); - - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, 0); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, 0); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, 0); - HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, 0); - if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { - HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); - HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); - } else { - HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); - HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); - } - } - break; - case RT_CAN_CMD_SET_FILTER: - if (RT_NULL == arg) { - /* default filter config */ - HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle, &pdrv_can->FilterConfig); - } else { - filter_cfg = (struct rt_can_filter_config *) arg; - _inline_can_filter_config(pdrv_can, filter_cfg); - } - break; - case RT_CAN_CMD_SET_MODE: - argval = (rt_uint32_t) arg; - if (argval != RT_CAN_MODE_NORMAL && - argval != RT_CAN_MODE_LISTEN && - argval != RT_CAN_MODE_LOOPBACK && - argval != RT_CAN_MODE_LOOPBACKANLISTEN) { - return -RT_ERROR; - } - if (argval != pdrv_can->device.config.mode) { - pdrv_can->device.config.mode = argval; - return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); - } - break; - case RT_CAN_CMD_SET_BAUD: - argval = (rt_uint32_t) arg; - /* 查找仲裁相位波特率是否存在 */ - uint32_t arb_idx = _inline_get_ArbBaudIndex(argval); - if (arb_idx == (uint32_t) -1) { - return -RT_ERROR; // 未找到匹配波特率 - } - if (argval != pdrv_can->device.config.baud_rate) { - pdrv_can->device.config.baud_rate = argval; - return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); - } - break; - - case RT_CAN_CMD_SET_PRIV: - argval = (rt_uint32_t) arg; - if (argval != RT_CAN_MODE_PRIV && - argval != RT_CAN_MODE_NOPRIV) { - return -RT_ERROR; - } - if (argval != pdrv_can->device.config.privmode) { - pdrv_can->device.config.privmode = argval; - - return RT_EOK; - } - break; - case RT_CAN_CMD_GET_STATUS: { - rt_uint32_t tmp_u32Errcount; - rt_uint32_t tmp_u32status; - tmp_u32Errcount = pdrv_can->fdcanHandle.Instance->ECR; - tmp_u32status = pdrv_can->fdcanHandle.Instance->PSR; - - pdrv_can->device.status.rcverrcnt = (tmp_u32Errcount >> 8) & 0x000000ff; - pdrv_can->device.status.snderrcnt = (tmp_u32Errcount) & 0x000000ff; - pdrv_can->device.status.lasterrtype = tmp_u32status & 0x000000007; - - rt_memcpy(arg, &pdrv_can->device.status, sizeof(pdrv_can->device.status)); - } - break; - case RT_CAN_CMD_SET_BAUD_FD: { - /* 查找仲裁相位波特率是否存在 */ - uint32_t data_idx = _inline_get_DataBaudIndex(argval); - if (data_idx == (uint32_t) -1) { - return -RT_ERROR; // 未找到匹配波特率 - } - if (argval != pdrv_can->device.config.baud_rate_fd) { - pdrv_can->device.config.baud_rate_fd = argval; - return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); - } - } - } - - - return RT_EOK; + rt_uint32_t argval; + stm32_fdcan_t *pdrv_can; + struct rt_can_filter_config *filter_cfg; + RT_ASSERT(can != RT_NULL); + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + RT_ASSERT(pdrv_can != RT_NULL); + switch (cmd) { + case RT_DEVICE_CTRL_CLR_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE); + } else if (argval == RT_DEVICE_FLAG_INT_TX) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_FIFO_EMPTY); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE); + } else if (argval == RT_DEVICE_CAN_INT_ERR) { + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_LOGGING_OVERFLOW); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF); + HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR); + } + break; + case RT_DEVICE_CTRL_SET_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, + FDCAN_INTERRUPT_LINE0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 1); + HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 1); + HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); + } + } else if (argval == RT_DEVICE_FLAG_INT_TX) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER1); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER2); + + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); + } + } else if (argval == RT_DEVICE_CAN_INT_ERR) { + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, FDCAN_INTERRUPT_LINE1); + HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, + FDCAN_INTERRUPT_LINE1); + + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, 0); + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, 0); + if (FDCAN1 == pdrv_can->fdcanHandle.Instance) { + HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn); + } else { + HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2); + HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn); + } + } + break; + case RT_CAN_CMD_SET_FILTER: + if (RT_NULL == arg) { + /* default filter config */ + HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle, &pdrv_can->FilterConfig); + } else { + filter_cfg = (struct rt_can_filter_config *) arg; + _inline_can_filter_config(pdrv_can, filter_cfg); + } + break; + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_NORMAL && + argval != RT_CAN_MODE_LISTEN && + argval != RT_CAN_MODE_LOOPBACK && + argval != RT_CAN_MODE_LOOPBACKANLISTEN) { + return -RT_ERROR; + } + if (argval != pdrv_can->device.config.mode) { + pdrv_can->device.config.mode = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + break; + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + /* 查找仲裁相位波特率是否存在 */ + uint32_t arb_idx = _inline_get_ArbBaudIndex(argval); + if (arb_idx == (uint32_t) -1) { + return -RT_ERROR; // 未找到匹配波特率 + } + if (argval != pdrv_can->device.config.baud_rate) { + pdrv_can->device.config.baud_rate = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + break; + + case RT_CAN_CMD_SET_PRIV: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_PRIV && + argval != RT_CAN_MODE_NOPRIV) { + return -RT_ERROR; + } + if (argval != pdrv_can->device.config.privmode) { + pdrv_can->device.config.privmode = argval; + + return RT_EOK; + } + break; + case RT_CAN_CMD_GET_STATUS: { + rt_uint32_t tmp_u32Errcount; + rt_uint32_t tmp_u32status; + tmp_u32Errcount = pdrv_can->fdcanHandle.Instance->ECR; + tmp_u32status = pdrv_can->fdcanHandle.Instance->PSR; + + pdrv_can->device.status.rcverrcnt = (tmp_u32Errcount >> 8) & 0x000000ff; + pdrv_can->device.status.snderrcnt = (tmp_u32Errcount) & 0x000000ff; + pdrv_can->device.status.lasterrtype = tmp_u32status & 0x000000007; + + rt_memcpy(arg, &pdrv_can->device.status, sizeof(pdrv_can->device.status)); + } + break; + case RT_CAN_CMD_SET_BAUD_FD: { + /* 查找仲裁相位波特率是否存在 */ + uint32_t data_idx = _inline_get_DataBaudIndex(argval); + if (data_idx == (uint32_t) -1) { + return -RT_ERROR; // 未找到匹配波特率 + } + if (argval != pdrv_can->device.config.baud_rate_fd) { + pdrv_can->device.config.baud_rate_fd = argval; + return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config); + } + } + } + + + return RT_EOK; } static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num) { - stm32_fdcan_t *pdrv_can; - struct rt_can_msg *pmsg; - uint32_t tmp_u32DataLen; - RT_ASSERT(can); - RT_ASSERT(buf); - - pdrv_can = (stm32_fdcan_t *)can->parent.user_data; - - RT_ASSERT(pdrv_can); - - pmsg = (struct rt_can_msg *) buf; - - /* Check the parameters */ - tmp_u32DataLen = length_to_dlc( pmsg->len); - - if(pmsg->ide == RT_CAN_EXTID) - { - pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; - } - else - { - pdrv_can->TxHeader.IdType = FDCAN_STANDARD_ID; - } - - if (RT_CAN_DTR == pmsg->rtr) - { - pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; - } - else - { - pdrv_can->TxHeader.TxFrameType = FDCAN_REMOTE_FRAME; - } - - - pdrv_can->TxHeader.Identifier = pmsg->id; - - pdrv_can->TxHeader.DataLength = tmp_u32DataLen; - - - if (pmsg->fd_frame == 1) - { - pdrv_can->TxHeader.FDFormat = FDCAN_FD_CAN; - } - else { - pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; - } - - if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK) - { - return -RT_ERROR; - } - else - { - /* Request transmission */ - HAL_FDCAN_EnableTxBufferRequest(&pdrv_can->fdcanHandle,FDCAN_TX_BUFFER0+box_num); - return RT_EOK; - } + stm32_fdcan_t *pdrv_can; + struct rt_can_msg *pmsg; + uint32_t tmp_u32DataLen; + RT_ASSERT(can); + RT_ASSERT(buf); + + pdrv_can = (stm32_fdcan_t *)can->parent.user_data; + + RT_ASSERT(pdrv_can); + + pmsg = (struct rt_can_msg *) buf; + + /* Check the parameters */ + tmp_u32DataLen = length_to_dlc( pmsg->len); + + if(pmsg->ide == RT_CAN_EXTID) + { + pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; + } + else + { + pdrv_can->TxHeader.IdType = FDCAN_STANDARD_ID; + } + + if (RT_CAN_DTR == pmsg->rtr) + { + pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME; + } + else + { + pdrv_can->TxHeader.TxFrameType = FDCAN_REMOTE_FRAME; + } + + + pdrv_can->TxHeader.Identifier = pmsg->id; + + pdrv_can->TxHeader.DataLength = tmp_u32DataLen; + + + if (pmsg->fd_frame == 1) + { + pdrv_can->TxHeader.FDFormat = FDCAN_FD_CAN; + } + else { + pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + } + + if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK) + { + return -RT_ERROR; + } + else + { + /* Request transmission */ + HAL_FDCAN_EnableTxBufferRequest(&pdrv_can->fdcanHandle,FDCAN_TX_BUFFER0+box_num); + return RT_EOK; + } } static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) { - //测试 - // fifo = 0; + //测试 + // fifo = 0; struct rt_can_msg *pmsg; stm32_fdcan_t *pdrv_can; @@ -474,39 +474,39 @@ static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t pmsg = (struct rt_can_msg *) buf; if(HAL_FDCAN_GetRxMessage(&pdrv_can->fdcanHandle,FDCAN_RX_FIFO0+fifo, &pdrv_can->RxHeader, pmsg->data) != HAL_OK) { - return 0; + return 0; } else { - if(pdrv_can->RxHeader.IdType == FDCAN_EXTENDED_ID) - { - pmsg->ide = RT_CAN_EXTID; - } - else - { - pmsg->ide = RT_CAN_STDID; - } - - if(pdrv_can->RxHeader.RxFrameType == FDCAN_DATA_FRAME) - { - pmsg->rtr = RT_CAN_DTR; - } - else - { - pmsg->rtr = RT_CAN_RTR; - } - pmsg->id = pdrv_can->RxHeader.Identifier; - - // pmsg->len = (pdrv_can->RxHeader.DataLength >> 16) & 0x0f; - pmsg->len = pdrv_can->RxHeader.DataLength; - pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; - - #ifdef RT_CAN_USING_CANFD - pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20; - pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;; - #endif - - return sizeof(struct rt_can_msg); + if(pdrv_can->RxHeader.IdType == FDCAN_EXTENDED_ID) + { + pmsg->ide = RT_CAN_EXTID; + } + else + { + pmsg->ide = RT_CAN_STDID; + } + + if(pdrv_can->RxHeader.RxFrameType == FDCAN_DATA_FRAME) + { + pmsg->rtr = RT_CAN_DTR; + } + else + { + pmsg->rtr = RT_CAN_RTR; + } + pmsg->id = pdrv_can->RxHeader.Identifier; + + // pmsg->len = (pdrv_can->RxHeader.DataLength >> 16) & 0x0f; + pmsg->len = pdrv_can->RxHeader.DataLength; + pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; + + #ifdef RT_CAN_USING_CANFD + pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20; + pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;; + #endif + + return sizeof(struct rt_can_msg); } } @@ -520,57 +520,57 @@ static const struct rt_can_ops _can_ops = void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { - if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) - { - if(hfdcan->Instance == FDCAN1) - { + if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) + { + if(hfdcan->Instance == FDCAN1) + { #ifdef BSP_USING_FDCAN1 - //CAN1 - /* Retreive Rx messages from RX FIFO0 */ - rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_RX_IND | 0 << 8); + //CAN1 + /* Retreive Rx messages from RX FIFO0 */ + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_RX_IND | 0 << 8); #endif - } - else - { + } + else + { #ifdef BSP_USING_FDCAN2 - //CAN2 - /* Retreive Rx messages from RX FIFO0 */ - rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_RX_IND | 0 << 8); + //CAN2 + /* Retreive Rx messages from RX FIFO0 */ + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_RX_IND | 0 << 8); #endif - } - } + } + } } void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) { - if(hfdcan->Instance == FDCAN1) - { + if(hfdcan->Instance == FDCAN1) + { #ifdef BSP_USING_FDCAN1 - //can1 - rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); + //can1 + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); #endif - } - else - { + } + else + { #ifdef BSP_USING_FDCAN2 - //can2 - rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); + //can2 + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); #endif - } + } } void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) { - if(hfdcan->Instance == FDCAN1) - { - //can1 - } - else - { - //can2 - } + if(hfdcan->Instance == FDCAN1) + { + //can1 + } + else + { + //can2 + } } void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) @@ -580,69 +580,69 @@ void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t Buffe void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) { - rt_uint32_t tmp_u32Errcount; - rt_uint32_t tmp_u32status; - uint32_t ret = HAL_FDCAN_GetError(hfdcan); + rt_uint32_t tmp_u32Errcount; + rt_uint32_t tmp_u32status; + uint32_t ret = HAL_FDCAN_GetError(hfdcan); - if(hfdcan->Instance == FDCAN1) - { + if(hfdcan->Instance == FDCAN1) + { #ifdef BSP_USING_FDCAN1 - //can1 - if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && - (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) - { - //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; - hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; - st_DrvCan1.device.status.errcode = 0xff; - } - else - { - tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR; - tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR; - - st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; - st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; - st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007; - } + //can1 + if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && + (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) + { + //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; + st_DrvCan1.device.status.errcode = 0xff; + } + else + { + tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR; + tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR; + + st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; + st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; + st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007; + } #endif /*BSP_USING_FDCAN1*/ - } - else - { + } + else + { #ifdef BSP_USING_FDCAN2 - if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && - (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) - { - //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; - hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; - st_DrvCan2.device.status.errcode = 0xff; - } - else - { - //can2 - tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR; - tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR; - st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; - st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; - st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007; - } + if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && + (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) + { + //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk; + st_DrvCan2.device.status.errcode = 0xff; + } + else + { + //can2 + tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR; + tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR; + st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; + st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; + st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007; + } #endif /*BSP_USING_FDCAN2*/ - } + } } #ifdef BSP_USING_FDCAN1 void FDCAN1_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ { - rt_interrupt_enter(); - HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); - rt_interrupt_leave(); + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); + rt_interrupt_leave(); } void FDCAN1_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ { - rt_interrupt_enter(); - HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); - rt_interrupt_leave(); + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); + rt_interrupt_leave(); } #endif /*BSP_USING_FDCAN1*/ @@ -650,16 +650,16 @@ void FDCAN1_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ #ifdef BSP_USING_FDCAN2 void FDCAN2_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ { - rt_interrupt_enter(); - HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); - rt_interrupt_leave(); + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); + rt_interrupt_leave(); } void FDCAN2_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ { - rt_interrupt_enter(); - HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); - rt_interrupt_leave(); + rt_interrupt_enter(); + HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle); + rt_interrupt_leave(); } #endif/*BSP_USING_FDCAN2*/ @@ -677,8 +677,8 @@ static int rt_hw_can_init(void) config.maxhdr = 14; #endif #ifdef RT_CAN_USING_CANFD - config.baud_rate_fd = CAN1MBaud * 8; - config.enable_canfd = 1; + config.baud_rate_fd = CAN1MBaud * 8; + config.enable_canfd = 1; #endif /* config default filter */ @@ -692,8 +692,8 @@ static int rt_hw_can_init(void) #ifdef BSP_USING_FDCAN1 - st_DrvCan1.FilterConfig = sFilterConfig; - st_DrvCan1.device.config = config; + st_DrvCan1.FilterConfig = sFilterConfig; + st_DrvCan1.device.config = config; /* register FDCAN1 device */ rt_hw_can_register(&st_DrvCan1.device, st_DrvCan1.name, &_can_ops, &st_DrvCan1); @@ -701,10 +701,10 @@ static int rt_hw_can_init(void) #ifdef BSP_USING_FDCAN2 st_DrvCan2.FilterConfig = sFilterConfig; - st_DrvCan2.device.config = config; + st_DrvCan2.device.config = config; - /* register FDCAN1 device */ - rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2); + /* register FDCAN1 device */ + rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2); #endif /* BSP_USING_FDCAN2 */ return 0; diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h index 72c3fff81e7..5415838253a 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h @@ -23,19 +23,19 @@ extern "C" { typedef struct { - const char *name; - FDCAN_HandleTypeDef fdcanHandle; - FDCAN_RxHeaderTypeDef RxHeader; - FDCAN_TxHeaderTypeDef TxHeader; - uint8_t u8RxDataBuffer[8]; - uint8_t u8TxDataBuufer[8]; - FDCAN_FilterTypeDef FilterConfig; /*FDCAN filter*/ - struct rt_can_device device; /* inherit from can device */ + const char *name; + FDCAN_HandleTypeDef fdcanHandle; + FDCAN_RxHeaderTypeDef RxHeader; + FDCAN_TxHeaderTypeDef TxHeader; + uint8_t u8RxDataBuffer[8]; + uint8_t u8TxDataBuufer[8]; + FDCAN_FilterTypeDef FilterConfig; /*FDCAN filter*/ + struct rt_can_device device; /* inherit from can device */ } stm32_fdcan_t; typedef struct { - uint32_t u32Baudrate; - struct rt_can_bit_timing cam_bit_timing; + uint32_t u32Baudrate; + struct rt_can_bit_timing cam_bit_timing; }stm32_fdcan_timing_t; #ifdef __cplusplus From 80e3f44d533a3f8ba5eefaeb420e347e59cb6ecd Mon Sep 17 00:00:00 2001 From: pandafeng1999 Date: Fri, 10 Oct 2025 18:13:44 +0800 Subject: [PATCH 04/15] Update Error Callback --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 53cf0d53142..09415bd8da2 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -561,21 +561,37 @@ void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t Bu } -void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) +void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) { if(hfdcan->Instance == FDCAN1) { - //can1 +#ifdef BSP_USING_FDCAN1 + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); +#endif } else { - //can2 +#ifdef BSP_USING_FDCAN2 + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); +#endif } } -void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) -{ +void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) +{ + if(hfdcan->Instance == FDCAN1) + { +#ifdef BSP_USING_FDCAN1 + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE); +#endif + } + else + { +#ifdef BSP_USING_FDCAN2 + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE); +#endif + } } void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) From ed657a5c6888b0fd6fbe50fc028e4fc2abc1c9d2 Mon Sep 17 00:00:00 2001 From: pandafeng1999 Date: Sat, 11 Oct 2025 10:37:11 +0800 Subject: [PATCH 05/15] add tx fail isr --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 09415bd8da2..a0ae8fb12df 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -615,10 +615,11 @@ void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) { tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR; tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR; - st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007; + rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_FAIL); + } #endif /*BSP_USING_FDCAN1*/ } @@ -640,6 +641,7 @@ void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff; st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff; st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007; + rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_FAIL); } #endif /*BSP_USING_FDCAN2*/ } From aee7eb45380deaa04ef7e9a6187e1f344e549b49 Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:06:36 +0800 Subject: [PATCH 06/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h index 5415838253a..d341fda4deb 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.h @@ -28,7 +28,7 @@ typedef struct FDCAN_RxHeaderTypeDef RxHeader; FDCAN_TxHeaderTypeDef TxHeader; uint8_t u8RxDataBuffer[8]; - uint8_t u8TxDataBuufer[8]; + uint8_t u8TxDataBuffer[8]; FDCAN_FilterTypeDef FilterConfig; /*FDCAN filter*/ struct rt_can_device device; /* inherit from can device */ } stm32_fdcan_t; From 38b99f3230f8f8dd5785d9686221a603614c21ff Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:07:15 +0800 Subject: [PATCH 07/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index a0ae8fb12df..009cc3a4d31 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -561,21 +561,6 @@ void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t Bu } -void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) -{ - if(hfdcan->Instance == FDCAN1) - { -#ifdef BSP_USING_FDCAN1 - rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); -#endif - } - else - { -#ifdef BSP_USING_FDCAN2 - rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); -#endif - } -} void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) From 1689aed8a1b8c81f40ad0ac33f3272616f89d31a Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:07:25 +0800 Subject: [PATCH 08/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 009cc3a4d31..b85d001b783 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -462,8 +462,6 @@ static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_ui static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) { - //测试 - // fifo = 0; struct rt_can_msg *pmsg; stm32_fdcan_t *pdrv_can; From 1e715e2aa02382bd3a2ff5ba4c9a2746fa641f68 Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:08:03 +0800 Subject: [PATCH 09/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index b85d001b783..dce4562c7c3 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -704,7 +704,7 @@ static int rt_hw_can_init(void) st_DrvCan2.FilterConfig = sFilterConfig; st_DrvCan2.device.config = config; - /* register FDCAN1 device */ + /* register FDCAN2 device */ rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2); #endif /* BSP_USING_FDCAN2 */ From 006f112dd8c79d3ba61ef89349bfeacaeab18a6d Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:48:33 +0800 Subject: [PATCH 10/15] Fix duplicate assignment of pmsg->brs --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index dce4562c7c3..43d1de735ba 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -501,7 +501,7 @@ static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t #ifdef RT_CAN_USING_CANFD pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20; - pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;; + pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10; #endif return sizeof(struct rt_can_msg); @@ -713,4 +713,4 @@ static int rt_hw_can_init(void) INIT_BOARD_EXPORT(rt_hw_can_init); #endif /* BSP_USING_FDCAN1 || BSP_USING_FDCAN2 */ -#endif /* RT_USING_CAN */ \ No newline at end of file +#endif /* RT_USING_CAN */ From ab8fe09987e321909d5bffd39b7a574f1275dc8b Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:28:27 +0800 Subject: [PATCH 11/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 43d1de735ba..5faec09efdf 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -495,7 +495,6 @@ static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t } pmsg->id = pdrv_can->RxHeader.Identifier; - // pmsg->len = (pdrv_can->RxHeader.DataLength >> 16) & 0x0f; pmsg->len = pdrv_can->RxHeader.DataLength; pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; From 442afff180cff148e75a17fc6c67fa073f6324a0 Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:29:35 +0800 Subject: [PATCH 12/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 5faec09efdf..c92a4ea4dd9 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -382,6 +382,7 @@ static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *ar } break; case RT_CAN_CMD_SET_BAUD_FD: { + argval = (rt_uint32_t) arg; /* 查找仲裁相位波特率是否存在 */ uint32_t data_idx = _inline_get_DataBaudIndex(argval); if (data_idx == (uint32_t) -1) { From 4bd2fd970c8dc1a01154490ae0c4e342ad08c6fe Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:29:48 +0800 Subject: [PATCH 13/15] Update bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index c92a4ea4dd9..ba388ef19af 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -632,14 +632,14 @@ void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) #ifdef BSP_USING_FDCAN1 -void FDCAN1_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ +void FDCAN1_IT0_IRQHandler(void) /* FDCAN1 interrupt line 0 */ { rt_interrupt_enter(); HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); rt_interrupt_leave(); } -void FDCAN1_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ +void FDCAN1_IT1_IRQHandler(void) /* FDCAN1 interrupt line 1 */ { rt_interrupt_enter(); HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); From 56143c4e9b2a92087d65d7f23377774e09d9d4f8 Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Mon, 27 Oct 2025 18:01:43 +0800 Subject: [PATCH 14/15] Update drv_fdcan.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复注释 --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index ba388ef19af..55d2c33cd0f 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -7,6 +7,7 @@ * Date Author Notes * 2020-02-24 heyuan the first version * 2020-08-17 malongwei Fix something + * 2025-10-27 pandafeng Fix some bugs */ #include "drv_fdcan.h" @@ -101,7 +102,11 @@ static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate) } /** - * @brief 获取 FDCAN 数据段波特率配置索引 + * @brief Get the index of the FDCAN data segment bitrate configuration. + * + * @param baud_rate The desired data phase baud rate (in bps). + * @retval uint32_t Index of the matching data segment configuration. + * Returns -1 if no matching configuration is found. */ static uint32_t _inline_get_DataBaudIndex(uint32_t baud_rate) { @@ -156,7 +161,7 @@ static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configu LOG_E("not support %d baudrate", cfg->baud_rate); return -RT_ERROR; } - /* 仲裁段 */ + /* FDCAN arbitration segment */ pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler; pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw; pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1; @@ -345,10 +350,9 @@ static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *ar break; case RT_CAN_CMD_SET_BAUD: argval = (rt_uint32_t) arg; - /* 查找仲裁相位波特率是否存在 */ uint32_t arb_idx = _inline_get_ArbBaudIndex(argval); if (arb_idx == (uint32_t) -1) { - return -RT_ERROR; // 未找到匹配波特率 + return -RT_ERROR; } if (argval != pdrv_can->device.config.baud_rate) { pdrv_can->device.config.baud_rate = argval; @@ -383,10 +387,9 @@ static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *ar break; case RT_CAN_CMD_SET_BAUD_FD: { argval = (rt_uint32_t) arg; - /* 查找仲裁相位波特率是否存在 */ uint32_t data_idx = _inline_get_DataBaudIndex(argval); if (data_idx == (uint32_t) -1) { - return -RT_ERROR; // 未找到匹配波特率 + return -RT_ERROR; } if (argval != pdrv_can->device.config.baud_rate_fd) { pdrv_can->device.config.baud_rate_fd = argval; From da6784a351ca0af0b3a3fdff8d73da778a6e2d0e Mon Sep 17 00:00:00 2001 From: PandaFeng <80824511+Pandafeng-HHU@users.noreply.github.com> Date: Tue, 28 Oct 2025 20:25:35 +0800 Subject: [PATCH 15/15] Update drv_fdcan.c --- .../libraries/HAL_Drivers/drivers/drv_fdcan.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index 55d2c33cd0f..ca41a38f10a 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -558,12 +558,8 @@ void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t Bu rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8)); #endif } - } - - - void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) { if(hfdcan->Instance == FDCAN1) @@ -589,8 +585,7 @@ void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) if(hfdcan->Instance == FDCAN1) { #ifdef BSP_USING_FDCAN1 - //can1 - if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && + if((ret & FDCAN_IT_ARB_PROTOCOL_ERROR) && (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)) { //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk; @@ -634,7 +629,6 @@ void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) } #ifdef BSP_USING_FDCAN1 - void FDCAN1_IT0_IRQHandler(void) /* FDCAN1 interrupt line 0 */ { rt_interrupt_enter(); @@ -648,9 +642,7 @@ void FDCAN1_IT1_IRQHandler(void) /* FDCAN1 interrupt line 1 */ HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle); rt_interrupt_leave(); } - #endif /*BSP_USING_FDCAN1*/ - #ifdef BSP_USING_FDCAN2 void FDCAN2_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */ { @@ -667,7 +659,6 @@ void FDCAN2_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */ } #endif/*BSP_USING_FDCAN2*/ - static int rt_hw_can_init(void) { struct can_configure config; @@ -684,7 +675,6 @@ static int rt_hw_can_init(void) config.baud_rate_fd = CAN1MBaud * 8; config.enable_canfd = 1; #endif - /* config default filter */ FDCAN_FilterTypeDef sFilterConfig; sFilterConfig.IdType = FDCAN_STANDARD_ID; @@ -693,24 +683,18 @@ static int rt_hw_can_init(void) sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; sFilterConfig.FilterID1 = 0; sFilterConfig.FilterID2 = 0x7FF; - #ifdef BSP_USING_FDCAN1 - st_DrvCan1.FilterConfig = sFilterConfig; st_DrvCan1.device.config = config; - /* register FDCAN1 device */ rt_hw_can_register(&st_DrvCan1.device, st_DrvCan1.name, &_can_ops, &st_DrvCan1); #endif /* BSP_USING_FDCAN1 */ - #ifdef BSP_USING_FDCAN2 st_DrvCan2.FilterConfig = sFilterConfig; st_DrvCan2.device.config = config; - /* register FDCAN2 device */ rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2); #endif /* BSP_USING_FDCAN2 */ - return 0; } INIT_BOARD_EXPORT(rt_hw_can_init);