drv_fdcan.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-02-24 heyuan the first version
  9. * 2020-08-17 malongwei Fix something
  10. * 2025-10-27 pandafeng Fix some bugs
  11. * 2026-03-16 sayaZhao Fix some bugs
  12. */
  13. #include "drv_fdcan.h"
  14. #if defined(RT_USING_CAN) && defined(RT_CAN_USING_CANFD)
  15. #if defined(BSP_USING_FDCAN1) || defined(BSP_USING_FDCAN2)
  16. //#define DRV_DEBUG
  17. #define LOG_TAG "drv_fdcan"
  18. #include <drv_log.h>
  19. #ifdef BSP_USING_FDCAN1
  20. static stm32_fdcan_t st_DrvCan1=
  21. {
  22. .name = "fdcan1",
  23. .fdcanHandle.Instance = FDCAN1,
  24. };
  25. #endif
  26. #ifdef BSP_USING_FDCAN2
  27. static stm32_fdcan_t st_DrvCan2=
  28. {
  29. .name = "fdcan2",
  30. .fdcanHandle.Instance = FDCAN2,
  31. };
  32. #endif
  33. /* 40MHz CAN clock */
  34. static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] =
  35. {
  36. {CAN1MBaud, {1, 29, 10, 8, 0}}, /* 1Mbps */
  37. {CAN800kBaud, {1, 37, 12, 8, 0}}, /* 800kbps */
  38. {CAN500kBaud, {1, 59, 20, 8, 0}}, /* 500kbps */
  39. {CAN250kBaud, {2, 63, 16, 8, 0}}, /* 250kbps */
  40. {CAN125kBaud, {5, 55, 8, 8, 0}}, /* 125kbps */
  41. {CAN100kBaud, {8, 41, 8, 8, 0}}, /* 100kbps */
  42. {CAN50kBaud, {16, 41, 8, 8, 0}}, /* 50kbps */
  43. {CAN20kBaud, {40,41,8,8,0}}, /* 20kbps */
  44. {CAN10kBaud, {100,31,8,8,0}} /* 10kbps */
  45. };
  46. /* 40MHz CAN clock */
  47. static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] =
  48. {
  49. {CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */
  50. {CAN1MBaud * 5, {1, 5, 2, 1, 0}}, /* 5Mbps */
  51. {CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */
  52. {CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */
  53. {CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */
  54. {CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */
  55. {CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */
  56. };
  57. /**
  58. * @brief Convert CAN-FD DLC (Data Length Code) back to actual frame length
  59. * @param dlc DLC code (0~15)
  60. * @return Actual length in bytes (0~64)
  61. */
  62. static uint8_t dlc_to_length(uint32_t dlc)
  63. {
  64. const uint8_t dlc_to_len_table[16] = {
  65. 0, 1, 2, 3, 4, 5, 6, 7,
  66. 8, 12, 16, 20, 24, 32, 48, 64
  67. };
  68. if (dlc > 15) return 8;
  69. return dlc_to_len_table[dlc];
  70. }
  71. /**
  72. * @brief Convert CAN-FD frame length to DLC (Data Length Code)
  73. *
  74. * CAN-FD DLC mapping (length → DLC):
  75. * Length 0~8 -> DLC 0~8
  76. * Length 9~12 -> DLC 9
  77. * Length 13~16 -> DLC 10
  78. * Length 17~20 -> DLC 11
  79. * Length 21~24 -> DLC 12
  80. * Length 25~32 -> DLC 13
  81. * Length 33~48 -> DLC 14
  82. * Length 49~64 -> DLC 15
  83. *
  84. * @param len Frame length in bytes (0~64)
  85. * @return DLC code (0~15)
  86. */
  87. uint8_t length_to_dlc(uint8_t len) {
  88. return (len <= 8) ? len :
  89. (len <= 12) ? 9 :
  90. (len <= 16) ? 10 :
  91. (len <= 20) ? 11 :
  92. (len <= 24) ? 12 :
  93. (len <= 32) ? 13 :
  94. (len <= 48) ? 14 : 15;
  95. }
  96. /**
  97. * @brief 获取 FDCAN 仲裁段波特率配置索引
  98. */
  99. static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate)
  100. {
  101. uint32_t len = sizeof(st_FDCAN_ArbTiming) / sizeof(st_FDCAN_ArbTiming[0]);
  102. for (uint32_t i = 0; i < len; i++)
  103. {
  104. if (st_FDCAN_ArbTiming[i].u32Baudrate == baud_rate)
  105. return i;
  106. }
  107. return -1;
  108. }
  109. /**
  110. * @brief Get the index of the FDCAN data segment bitrate configuration.
  111. *
  112. * @param baud_rate The desired data phase baud rate (in bps).
  113. * @retval uint32_t Index of the matching data segment configuration.
  114. * Returns -1 if no matching configuration is found.
  115. */
  116. static uint32_t _inline_get_DataBaudIndex(uint32_t baud_rate)
  117. {
  118. uint32_t len = sizeof(st_FDCAN_DataTiming) / sizeof(st_FDCAN_DataTiming[0]);
  119. for (uint32_t i = 0; i < len; i++)
  120. {
  121. if (st_FDCAN_DataTiming[i].u32Baudrate == baud_rate)
  122. return i;
  123. }
  124. return -1;
  125. }
  126. static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configure *cfg)
  127. {
  128. stm32_fdcan_t *pdrv_can;
  129. rt_uint32_t tmp_u32Index;
  130. RT_ASSERT(can);
  131. RT_ASSERT(cfg);
  132. pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
  133. RT_ASSERT(pdrv_can);
  134. pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
  135. pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
  136. pdrv_can->fdcanHandle.Init.AutoRetransmission = ENABLE;
  137. pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE;
  138. pdrv_can->fdcanHandle.Init.ProtocolException = ENABLE;
  139. switch (cfg->mode)
  140. {
  141. case RT_CAN_MODE_NORMAL:
  142. pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
  143. break;
  144. case RT_CAN_MODE_LISTEN:
  145. pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING;
  146. break;
  147. case RT_CAN_MODE_LOOPBACK:
  148. pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
  149. break;
  150. default:
  151. pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
  152. break;
  153. }
  154. uint32_t arb_idx = _inline_get_ArbBaudIndex(cfg->baud_rate);
  155. if (arb_idx == (uint32_t)-1)
  156. {
  157. LOG_E("not support %d baudrate", cfg->baud_rate);
  158. return -RT_ERROR;
  159. }
  160. /* FDCAN arbitration segment */
  161. pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler;
  162. pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw;
  163. pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1;
  164. pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg2;
  165. #ifdef RT_CAN_USING_CANFD
  166. if(cfg->enable_canfd) {
  167. uint32_t data_idx = _inline_get_DataBaudIndex(cfg->baud_rate_fd);
  168. if (data_idx == (uint32_t)-1)
  169. {
  170. LOG_E("not support %d baudrate", cfg->baud_rate_fd);
  171. return -RT_ERROR;
  172. }
  173. /* 数据段 */
  174. pdrv_can->fdcanHandle.Init.DataPrescaler = st_FDCAN_DataTiming[data_idx].cam_bit_timing.prescaler;
  175. pdrv_can->fdcanHandle.Init.DataSyncJumpWidth = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_sjw;
  176. pdrv_can->fdcanHandle.Init.DataTimeSeg1 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg1;
  177. pdrv_can->fdcanHandle.Init.DataTimeSeg2 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg2;
  178. }
  179. #endif
  180. /* Configure Message RAM */
  181. if(pdrv_can->fdcanHandle.Instance == FDCAN1)
  182. {
  183. pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0;
  184. }
  185. else
  186. {
  187. pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280;
  188. }
  189. pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2;
  190. pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2;
  191. pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1;
  192. pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
  193. pdrv_can->fdcanHandle.Init.RxFifo1ElmtsNbr = 0;
  194. pdrv_can->fdcanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
  195. pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0;
  196. pdrv_can->fdcanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
  197. pdrv_can->fdcanHandle.Init.TxEventsNbr = 0;
  198. pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3;
  199. pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0;
  200. pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  201. pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
  202. if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK)
  203. {
  204. return -RT_ERROR;
  205. }
  206. /* Transceiver Delay Compensation */
  207. #ifdef RT_CAN_USING_CANFD
  208. if (cfg->enable_canfd)
  209. {
  210. HAL_FDCAN_ConfigTxDelayCompensation(&pdrv_can->fdcanHandle, 0x0C, 0x00);
  211. HAL_FDCAN_EnableTxDelayCompensation(&pdrv_can->fdcanHandle);
  212. }
  213. #endif
  214. /* default filter config */
  215. HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig);
  216. /* FIFO RX INT */
  217. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
  218. /*init fdcan tx header*/
  219. pdrv_can->TxHeader.Identifier = 0x000000;
  220. pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID;
  221. pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  222. pdrv_can->TxHeader.DataLength = FDCAN_DLC_BYTES_8;
  223. pdrv_can->TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  224. pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  225. pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
  226. pdrv_can->TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  227. pdrv_can->TxHeader.MessageMarker = 0;
  228. /* can start */
  229. HAL_FDCAN_Start(&pdrv_can->fdcanHandle);
  230. return RT_EOK;
  231. }
  232. static rt_err_t _inline_can_filter_config(stm32_fdcan_t *pdrv_can,struct rt_can_filter_config *puser_can_filter_config)
  233. {
  234. int tmp_i32IndexCount;
  235. RT_ASSERT(pdrv_can);
  236. RT_ASSERT(puser_can_filter_config);
  237. /* get default filter */
  238. for (tmp_i32IndexCount = 0; tmp_i32IndexCount < puser_can_filter_config->count; tmp_i32IndexCount++)
  239. {
  240. pdrv_can->FilterConfig.FilterIndex = puser_can_filter_config->items[tmp_i32IndexCount].hdr_bank;
  241. pdrv_can->FilterConfig.FilterID1 = puser_can_filter_config->items[tmp_i32IndexCount].id;
  242. pdrv_can->FilterConfig.FilterID2 = puser_can_filter_config->items[tmp_i32IndexCount].mask;
  243. if(puser_can_filter_config->items[tmp_i32IndexCount].ide == RT_CAN_EXTID)
  244. {
  245. pdrv_can->FilterConfig.IdType = FDCAN_EXTENDED_ID;
  246. }
  247. else
  248. {
  249. pdrv_can->FilterConfig.IdType = FDCAN_STANDARD_ID;
  250. }
  251. pdrv_can->FilterConfig.FilterType = FDCAN_FILTER_MASK;
  252. pdrv_can->FilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  253. if(HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig) != HAL_OK)
  254. {
  255. return -RT_ERROR;
  256. }
  257. }
  258. return RT_EOK;
  259. }
  260. static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *arg)
  261. {
  262. rt_uint32_t argval;
  263. stm32_fdcan_t *pdrv_can;
  264. struct rt_can_filter_config *filter_cfg;
  265. RT_ASSERT(can != RT_NULL);
  266. pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
  267. RT_ASSERT(pdrv_can != RT_NULL);
  268. switch (cmd) {
  269. case RT_DEVICE_CTRL_CLR_INT:
  270. argval = (rt_uint32_t) arg;
  271. if (argval == RT_DEVICE_FLAG_INT_RX) {
  272. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
  273. } else if (argval == RT_DEVICE_FLAG_INT_TX) {
  274. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_FIFO_EMPTY);
  275. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE);
  276. } else if (argval == RT_DEVICE_CAN_INT_ERR) {
  277. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING);
  278. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE);
  279. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_LOGGING_OVERFLOW);
  280. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF);
  281. HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR);
  282. }
  283. break;
  284. case RT_DEVICE_CTRL_SET_INT:
  285. argval = (rt_uint32_t) arg;
  286. if (argval == RT_DEVICE_FLAG_INT_RX) {
  287. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
  288. FDCAN_INTERRUPT_LINE0);
  289. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
  290. if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
  291. HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 1);
  292. HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
  293. } else {
  294. HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 1);
  295. HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
  296. }
  297. } else if (argval == RT_DEVICE_FLAG_INT_TX) {
  298. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_LINE1);
  299. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0);
  300. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER1);
  301. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER2);
  302. if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
  303. HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2);
  304. HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
  305. } else {
  306. HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2);
  307. HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
  308. }
  309. } else if (argval == RT_DEVICE_CAN_INT_ERR) {
  310. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1);
  311. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, FDCAN_INTERRUPT_LINE1);
  312. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, FDCAN_INTERRUPT_LINE1);
  313. HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR,
  314. FDCAN_INTERRUPT_LINE1);
  315. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, 0);
  316. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, 0);
  317. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, 0);
  318. HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, 0);
  319. if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
  320. HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2);
  321. HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
  322. } else {
  323. HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2);
  324. HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
  325. }
  326. }
  327. break;
  328. case RT_CAN_CMD_SET_FILTER:
  329. if (RT_NULL == arg) {
  330. /* default filter config */
  331. HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle, &pdrv_can->FilterConfig);
  332. } else {
  333. filter_cfg = (struct rt_can_filter_config *) arg;
  334. _inline_can_filter_config(pdrv_can, filter_cfg);
  335. }
  336. break;
  337. case RT_CAN_CMD_SET_MODE:
  338. argval = (rt_uint32_t) arg;
  339. if (argval != RT_CAN_MODE_NORMAL &&
  340. argval != RT_CAN_MODE_LISTEN &&
  341. argval != RT_CAN_MODE_LOOPBACK &&
  342. argval != RT_CAN_MODE_LOOPBACKANLISTEN) {
  343. return -RT_ERROR;
  344. }
  345. if (argval != pdrv_can->device.config.mode) {
  346. pdrv_can->device.config.mode = argval;
  347. return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
  348. }
  349. break;
  350. case RT_CAN_CMD_SET_BAUD:
  351. argval = (rt_uint32_t) arg;
  352. uint32_t arb_idx = _inline_get_ArbBaudIndex(argval);
  353. if (arb_idx == (uint32_t) -1) {
  354. return -RT_ERROR;
  355. }
  356. if (argval != pdrv_can->device.config.baud_rate) {
  357. pdrv_can->device.config.baud_rate = argval;
  358. return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
  359. }
  360. break;
  361. case RT_CAN_CMD_SET_PRIV:
  362. argval = (rt_uint32_t) arg;
  363. if (argval != RT_CAN_MODE_PRIV &&
  364. argval != RT_CAN_MODE_NOPRIV) {
  365. return -RT_ERROR;
  366. }
  367. if (argval != pdrv_can->device.config.privmode) {
  368. pdrv_can->device.config.privmode = argval;
  369. return RT_EOK;
  370. }
  371. break;
  372. case RT_CAN_CMD_GET_STATUS: {
  373. rt_uint32_t tmp_u32Errcount;
  374. rt_uint32_t tmp_u32status;
  375. tmp_u32Errcount = pdrv_can->fdcanHandle.Instance->ECR;
  376. tmp_u32status = pdrv_can->fdcanHandle.Instance->PSR;
  377. pdrv_can->device.status.rcverrcnt = (tmp_u32Errcount >> 8) & 0x000000ff;
  378. pdrv_can->device.status.snderrcnt = (tmp_u32Errcount) & 0x000000ff;
  379. pdrv_can->device.status.lasterrtype = tmp_u32status & 0x000000007;
  380. rt_memcpy(arg, &pdrv_can->device.status, sizeof(pdrv_can->device.status));
  381. }
  382. break;
  383. case RT_CAN_CMD_SET_BAUD_FD: {
  384. argval = (rt_uint32_t) arg;
  385. uint32_t data_idx = _inline_get_DataBaudIndex(argval);
  386. if (data_idx == (uint32_t) -1) {
  387. return -RT_ERROR;
  388. }
  389. if (argval != pdrv_can->device.config.baud_rate_fd) {
  390. pdrv_can->device.config.baud_rate_fd = argval;
  391. return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
  392. }
  393. }
  394. }
  395. return RT_EOK;
  396. }
  397. static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
  398. {
  399. stm32_fdcan_t *pdrv_can;
  400. struct rt_can_msg *pmsg;
  401. uint32_t tmp_u32DataLen;
  402. RT_ASSERT(can);
  403. RT_ASSERT(buf);
  404. pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
  405. RT_ASSERT(pdrv_can);
  406. pmsg = (struct rt_can_msg *) buf;
  407. /* Check the parameters */
  408. tmp_u32DataLen = length_to_dlc( pmsg->len);
  409. if(pmsg->ide == RT_CAN_EXTID)
  410. {
  411. pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID;
  412. }
  413. else
  414. {
  415. pdrv_can->TxHeader.IdType = FDCAN_STANDARD_ID;
  416. }
  417. if (RT_CAN_DTR == pmsg->rtr)
  418. {
  419. pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  420. }
  421. else
  422. {
  423. pdrv_can->TxHeader.TxFrameType = FDCAN_REMOTE_FRAME;
  424. }
  425. pdrv_can->TxHeader.Identifier = pmsg->id;
  426. pdrv_can->TxHeader.DataLength = tmp_u32DataLen;
  427. if (pmsg->fd_frame == 1)
  428. {
  429. pdrv_can->TxHeader.FDFormat = FDCAN_FD_CAN;
  430. }
  431. else {
  432. pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
  433. }
  434. if (pmsg->brs == 1) {
  435. pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_ON;
  436. } else {
  437. pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  438. }
  439. if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK)
  440. {
  441. return -RT_ERROR;
  442. }
  443. else
  444. {
  445. /* Request transmission */
  446. HAL_FDCAN_EnableTxBufferRequest(&pdrv_can->fdcanHandle,FDCAN_TX_BUFFER0+box_num);
  447. return RT_EOK;
  448. }
  449. }
  450. static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
  451. {
  452. struct rt_can_msg *pmsg;
  453. stm32_fdcan_t *pdrv_can;
  454. RT_ASSERT(can);
  455. RT_ASSERT(buf);
  456. pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
  457. pmsg = (struct rt_can_msg *) buf;
  458. if(HAL_FDCAN_GetRxMessage(&pdrv_can->fdcanHandle,FDCAN_RX_FIFO0+fifo, &pdrv_can->RxHeader, pmsg->data) != HAL_OK)
  459. {
  460. return 0;
  461. }
  462. else
  463. {
  464. if(pdrv_can->RxHeader.IdType == FDCAN_EXTENDED_ID)
  465. {
  466. pmsg->ide = RT_CAN_EXTID;
  467. }
  468. else
  469. {
  470. pmsg->ide = RT_CAN_STDID;
  471. }
  472. if(pdrv_can->RxHeader.RxFrameType == FDCAN_DATA_FRAME)
  473. {
  474. pmsg->rtr = RT_CAN_DTR;
  475. }
  476. else
  477. {
  478. pmsg->rtr = RT_CAN_RTR;
  479. }
  480. pmsg->id = pdrv_can->RxHeader.Identifier;
  481. uint32_t actual_dlc = pdrv_can->RxHeader.DataLength;
  482. pmsg->len = dlc_to_length(actual_dlc);
  483. pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex;
  484. #ifdef RT_CAN_USING_CANFD
  485. pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20;
  486. pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;
  487. #endif
  488. return sizeof(struct rt_can_msg);
  489. }
  490. }
  491. static const struct rt_can_ops _can_ops =
  492. {
  493. _inline_can_config,
  494. _inline_can_control,
  495. _inline_can_sendmsg,
  496. _inline_can_recvmsg,
  497. };
  498. void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
  499. {
  500. if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
  501. {
  502. if(hfdcan->Instance == FDCAN1)
  503. {
  504. #ifdef BSP_USING_FDCAN1
  505. //CAN1
  506. /* Retreive Rx messages from RX FIFO0 */
  507. rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_RX_IND | 0 << 8);
  508. #endif
  509. }
  510. else
  511. {
  512. #ifdef BSP_USING_FDCAN2
  513. //CAN2
  514. /* Retreive Rx messages from RX FIFO0 */
  515. rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_RX_IND | 0 << 8);
  516. #endif
  517. }
  518. }
  519. }
  520. void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
  521. {
  522. if(hfdcan->Instance == FDCAN1)
  523. {
  524. #ifdef BSP_USING_FDCAN1
  525. //can1
  526. rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8));
  527. #endif
  528. }
  529. else
  530. {
  531. #ifdef BSP_USING_FDCAN2
  532. //can2
  533. rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8));
  534. #endif
  535. }
  536. }
  537. void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
  538. {
  539. if(hfdcan->Instance == FDCAN1)
  540. {
  541. #ifdef BSP_USING_FDCAN1
  542. rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE);
  543. #endif
  544. }
  545. else
  546. {
  547. #ifdef BSP_USING_FDCAN2
  548. rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE);
  549. #endif
  550. }
  551. }
  552. void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
  553. {
  554. rt_uint32_t tmp_u32Errcount;
  555. rt_uint32_t tmp_u32status;
  556. uint32_t ret = HAL_FDCAN_GetError(hfdcan);
  557. if(hfdcan->Instance == FDCAN1)
  558. {
  559. #ifdef BSP_USING_FDCAN1
  560. if((ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
  561. (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
  562. {
  563. //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
  564. hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
  565. st_DrvCan1.device.status.errcode = 0xff;
  566. }
  567. else
  568. {
  569. tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR;
  570. tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR;
  571. st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
  572. st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
  573. st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007;
  574. rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_FAIL);
  575. }
  576. #endif /*BSP_USING_FDCAN1*/
  577. }
  578. else
  579. {
  580. #ifdef BSP_USING_FDCAN2
  581. if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
  582. (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
  583. {
  584. //hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
  585. hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
  586. st_DrvCan2.device.status.errcode = 0xff;
  587. }
  588. else
  589. {
  590. //can2
  591. tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR;
  592. tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR;
  593. st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
  594. st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
  595. st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007;
  596. rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_FAIL);
  597. }
  598. #endif /*BSP_USING_FDCAN2*/
  599. }
  600. }
  601. #ifdef BSP_USING_FDCAN1
  602. void FDCAN1_IT0_IRQHandler(void) /* FDCAN1 interrupt line 0 */
  603. {
  604. rt_interrupt_enter();
  605. HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle);
  606. rt_interrupt_leave();
  607. }
  608. void FDCAN1_IT1_IRQHandler(void) /* FDCAN1 interrupt line 1 */
  609. {
  610. rt_interrupt_enter();
  611. HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle);
  612. rt_interrupt_leave();
  613. }
  614. #endif /*BSP_USING_FDCAN1*/
  615. #ifdef BSP_USING_FDCAN2
  616. void FDCAN2_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */
  617. {
  618. rt_interrupt_enter();
  619. HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle);
  620. rt_interrupt_leave();
  621. }
  622. void FDCAN2_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */
  623. {
  624. rt_interrupt_enter();
  625. HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle);
  626. rt_interrupt_leave();
  627. }
  628. #endif/*BSP_USING_FDCAN2*/
  629. static int rt_hw_can_init(void)
  630. {
  631. struct can_configure config;
  632. config.baud_rate = CAN1MBaud;
  633. config.msgboxsz = 48;
  634. config.sndboxnumber = 1;
  635. config.mode = RT_CAN_MODE_NORMAL;
  636. config.privmode = RT_CAN_MODE_NOPRIV;
  637. config.ticks = 50;
  638. #ifdef RT_CAN_USING_HDR
  639. config.maxhdr = 14;
  640. #endif
  641. #ifdef RT_CAN_USING_CANFD
  642. config.baud_rate_fd = CAN1MBaud * 8;
  643. config.enable_canfd = 1;
  644. #endif
  645. /* config default filter */
  646. FDCAN_FilterTypeDef sFilterConfig;
  647. sFilterConfig.IdType = FDCAN_STANDARD_ID;
  648. sFilterConfig.FilterIndex = 0;
  649. sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  650. sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  651. sFilterConfig.FilterID1 = 0;
  652. sFilterConfig.FilterID2 = 0x7FF;
  653. #ifdef BSP_USING_FDCAN1
  654. st_DrvCan1.FilterConfig = sFilterConfig;
  655. st_DrvCan1.device.config = config;
  656. /* register FDCAN1 device */
  657. rt_hw_can_register(&st_DrvCan1.device, st_DrvCan1.name, &_can_ops, &st_DrvCan1);
  658. #endif /* BSP_USING_FDCAN1 */
  659. #ifdef BSP_USING_FDCAN2
  660. st_DrvCan2.FilterConfig = sFilterConfig;
  661. st_DrvCan2.device.config = config;
  662. /* register FDCAN2 device */
  663. rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2);
  664. #endif /* BSP_USING_FDCAN2 */
  665. return 0;
  666. }
  667. INIT_BOARD_EXPORT(rt_hw_can_init);
  668. #endif /* BSP_USING_FDCAN1 || BSP_USING_FDCAN2 */
  669. #endif /* RT_USING_CAN */