|
8 | 8 | * 2020-02-24 heyuan the first version |
9 | 9 | * 2020-08-17 malongwei Fix something |
10 | 10 | * 2025-10-27 pandafeng Fix some bugs |
| 11 | + * 2026-03-16 sayaZhao Fix some bugs |
11 | 12 | */ |
12 | 13 |
|
13 | 14 | #include "drv_fdcan.h" |
@@ -54,12 +55,30 @@ static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] = |
54 | 55 | static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] = |
55 | 56 | { |
56 | 57 | {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */ |
| 58 | + {CAN1MBaud * 5, {1, 5, 2, 1, 0}}, /* 5Mbps */ |
57 | 59 | {CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */ |
58 | 60 | {CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */ |
59 | 61 | {CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */ |
60 | 62 | {CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */ |
61 | 63 | {CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */ |
62 | 64 | }; |
| 65 | + |
| 66 | +/** |
| 67 | + * @brief Convert CAN-FD DLC (Data Length Code) back to actual frame length |
| 68 | + * @param dlc DLC code (0~15) |
| 69 | + * @return Actual length in bytes (0~64) |
| 70 | + */ |
| 71 | +static uint8_t dlc_to_length(uint32_t dlc) |
| 72 | +{ |
| 73 | + const uint8_t dlc_to_len_table[16] = { |
| 74 | + 0, 1, 2, 3, 4, 5, 6, 7, |
| 75 | + 8, 12, 16, 20, 24, 32, 48, 64 |
| 76 | + }; |
| 77 | + |
| 78 | + if (dlc > 15) return 8; |
| 79 | + return dlc_to_len_table[dlc]; |
| 80 | +} |
| 81 | + |
63 | 82 | /** |
64 | 83 | * @brief Convert CAN-FD frame length to DLC (Data Length Code) |
65 | 84 | * |
@@ -208,8 +227,18 @@ static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configu |
208 | 227 | { |
209 | 228 | return -RT_ERROR; |
210 | 229 | } |
| 230 | +/* Transceiver Delay Compensation */ |
| 231 | +#ifdef RT_CAN_USING_CANFD |
| 232 | + if (cfg->enable_canfd) |
| 233 | + { |
| 234 | + HAL_FDCAN_ConfigTxDelayCompensation(&pdrv_can->fdcanHandle, 0x0C, 0x00); |
| 235 | + HAL_FDCAN_EnableTxDelayCompensation(&pdrv_can->fdcanHandle); |
| 236 | + } |
| 237 | +#endif |
211 | 238 | /* default filter config */ |
212 | 239 | HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig); |
| 240 | + /* FIFO RX INT */ |
| 241 | + HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); |
213 | 242 | /*init fdcan tx header*/ |
214 | 243 | pdrv_can->TxHeader.Identifier = 0x000000; |
215 | 244 | 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 |
452 | 481 | pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN; |
453 | 482 | } |
454 | 483 |
|
| 484 | + if (pmsg->brs == 1) { |
| 485 | + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_ON; |
| 486 | + } else { |
| 487 | + pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF; |
| 488 | + } |
| 489 | + |
455 | 490 | if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK) |
456 | 491 | { |
457 | 492 | return -RT_ERROR; |
@@ -499,7 +534,9 @@ static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t |
499 | 534 | } |
500 | 535 | pmsg->id = pdrv_can->RxHeader.Identifier; |
501 | 536 |
|
502 | | - pmsg->len = pdrv_can->RxHeader.DataLength; |
| 537 | + uint32_t actual_dlc = pdrv_can->RxHeader.DataLength; |
| 538 | + pmsg->len = dlc_to_length(actual_dlc); |
| 539 | + |
503 | 540 | pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex; |
504 | 541 |
|
505 | 542 | #ifdef RT_CAN_USING_CANFD |
|
0 commit comments