diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c index ca41a38f10a..50e316ff102 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_fdcan.c @@ -8,6 +8,7 @@ * 2020-02-24 heyuan the first version * 2020-08-17 malongwei Fix something * 2025-10-27 pandafeng Fix some bugs + * 2026-03-16 sayaZhao Fix some bugs */ #include "drv_fdcan.h" @@ -54,12 +55,30 @@ static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] = static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] = { {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */ + {CAN1MBaud * 5, {1, 5, 2, 1, 0}}, /* 5Mbps */ {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 DLC (Data Length Code) back to actual frame length + * @param dlc DLC code (0~15) + * @return Actual length in bytes (0~64) + */ +static uint8_t dlc_to_length(uint32_t dlc) +{ + const uint8_t dlc_to_len_table[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 12, 16, 20, 24, 32, 48, 64 + }; + + if (dlc > 15) return 8; + return dlc_to_len_table[dlc]; +} + /** * @brief Convert CAN-FD frame length to DLC (Data Length Code) * @@ -208,8 +227,18 @@ static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configu { return -RT_ERROR; } +/* Transceiver Delay Compensation */ +#ifdef RT_CAN_USING_CANFD + if (cfg->enable_canfd) + { + HAL_FDCAN_ConfigTxDelayCompensation(&pdrv_can->fdcanHandle, 0x0C, 0x00); + HAL_FDCAN_EnableTxDelayCompensation(&pdrv_can->fdcanHandle); + } +#endif /* default filter config */ HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig); + /* FIFO RX INT */ + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); /*init fdcan tx header*/ pdrv_can->TxHeader.Identifier = 0x000000; pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID; @@ -452,6 +481,12 @@ static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_ui pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; } + if (pmsg->brs == 1) { + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_ON; + } else { + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF; + } + if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK) { return -RT_ERROR; @@ -499,7 +534,9 @@ 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; + uint32_t actual_dlc = pdrv_can->RxHeader.DataLength; + pmsg->len = dlc_to_length(actual_dlc); + pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; #ifdef RT_CAN_USING_CANFD