[bsp][stm32/fdcan]修复CAN-FD发送/接收问题并新增5Mbps ISO CAN-FD数据相位速率支持
Some checks are pending
RT-Thread BSP Static Build Check / 🔍 Summary of Git Diff Changes (push) Waiting to run
RT-Thread BSP Static Build Check / ${{ matrix.legs.RTT_BSP }} (push) Blocked by required conditions
RT-Thread BSP Static Build Check / collect-artifacts (push) Blocked by required conditions
pkgs_test / change (push) Waiting to run
utest_auto_run / A9 :components/dfs.cfg (push) Waiting to run
utest_auto_run / A9 :components/lwip.cfg (push) Waiting to run
utest_auto_run / A9 :components/netdev.cfg (push) Waiting to run
utest_auto_run / A9 :components/sal.cfg (push) Waiting to run
utest_auto_run / A9 :cpp11/cpp11.cfg (push) Waiting to run
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Waiting to run
utest_auto_run / A9-rtsmart :default.cfg (push) Waiting to run
utest_auto_run / RISCV-rtsmart :default.cfg (push) Waiting to run
utest_auto_run / XUANTIE-rtsmart :default.cfg (push) Waiting to run
utest_auto_run / AARCH64 :default.cfg (push) Waiting to run
utest_auto_run / AARCH64-smp :default.cfg (push) Waiting to run
utest_auto_run / A9 :default.cfg (push) Waiting to run
utest_auto_run / A9-smp :default.cfg (push) Waiting to run
utest_auto_run / RISCV :default.cfg (push) Waiting to run
utest_auto_run / RISCV-smp :default.cfg (push) Waiting to run
utest_auto_run / A9 :kernel/atomic_c11.cfg (push) Waiting to run
utest_auto_run / RISCV :kernel/atomic_c11.cfg (push) Waiting to run
utest_auto_run / A9 :kernel/ipc.cfg (push) Waiting to run
utest_auto_run / A9 :kernel/kernel_basic.cfg (push) Waiting to run
utest_auto_run / A9 :kernel/mem.cfg (push) Waiting to run

This commit is contained in:
takuya60
2026-03-22 12:02:04 +08:00
committed by GitHub
parent 4ca97e50dd
commit 25295501c0

View File

@@ -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;
@@ -352,7 +381,7 @@ static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *ar
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;
@@ -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,13 +534,14 @@ 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;
pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex;
uint32_t actual_dlc = pdrv_can->RxHeader.DataLength;
pmsg->len = dlc_to_length(actual_dlc);
#ifdef RT_CAN_USING_CANFD
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
#endif
return sizeof(struct rt_can_msg);
}