drv_can.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. /*
  2. * Copyright (c) 2006-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-08-05 Xeon Xu the first version
  9. * 2019-01-22 YLZ port from stm324xx-HAL to bsp stm3210x-HAL
  10. * 2019-02-19 YLZ add support EXTID RTR Frame. modify send, recv functions.
  11. * fix bug.port to BSP [stm32]
  12. * 2019-03-27 YLZ support double can channels, support stm32F4xx (only Legacy mode).
  13. * 2019-06-17 YLZ port to new STM32F1xx HAL V1.1.3.
  14. * 2021-02-02 YuZhe XU fix bug in filter config
  15. * 2021-8-25 SVCHAO The baud rate is configured according to the different APB1 frequencies.
  16. f4-series only.
  17. * 2025-09-20 wdfk_prog Implemented sendmsg_nonblocking op to support framework's async TX.
  18. * 2026-02-02 wdfk_prog Drain multiple RX frames per ISR with a bounded limit.
  19. */
  20. #include "drv_can.h"
  21. #ifdef BSP_USING_CAN
  22. #define LOG_TAG "drv_can"
  23. #include <drv_log.h>
  24. #ifndef CAN_ISR_DRAIN_LIMIT
  25. /*
  26. * bxCAN FIFO depth is 3 (FMP[1:0]=0..3). Draining up to 3 frames can clear the FIFO in one ISR,
  27. * reducing FULL/OVERRUN without letting ISR time grow unbounded.
  28. */
  29. #define CAN_ISR_DRAIN_LIMIT 3
  30. #endif
  31. /* attention !!! baud calculation example: Tclk / ((ss + bs1 + bs2) * brp) = 36 / ((1 + 8 + 3) * 3) = 1MHz*/
  32. #if defined (SOC_SERIES_STM32F1)/* APB1 36MHz(max) */
  33. static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
  34. {
  35. {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 3)},
  36. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_3TQ | 5)},
  37. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 6)},
  38. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 12)},
  39. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 24)},
  40. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 30)},
  41. {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 60)},
  42. {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)},
  43. {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}
  44. };
  45. #elif defined (SOC_SERIES_STM32F4) /* 42MHz or 45MHz */
  46. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
  47. defined(STM32F401xC) || defined(STM32F401xE) /* 42MHz(max) */
  48. static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
  49. {
  50. {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)},
  51. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_4TQ | 4)},
  52. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 6)},
  53. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 12)},
  54. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 24)},
  55. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 30)},
  56. {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 60)},
  57. {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 150)},
  58. {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 300)}
  59. };
  60. #else /* APB1 45MHz(max) */
  61. static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
  62. {
  63. #ifdef BSP_USING_CAN168M
  64. {CAN1MBaud, (CAN_SJW_1TQ | CAN_BS1_3TQ | CAN_BS2_3TQ | 6)},
  65. #else
  66. {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 3)},
  67. #endif
  68. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)},
  69. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)},
  70. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)},
  71. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 24)},
  72. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 30)},
  73. {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 60)},
  74. {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)},
  75. {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)}
  76. };
  77. #endif
  78. #elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */
  79. static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
  80. {
  81. {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 3)},
  82. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_7TQ | 4)},
  83. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 6)},
  84. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 12)},
  85. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 24)},
  86. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 30)},
  87. {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 60)},
  88. {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 150)},
  89. {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 300)}
  90. };
  91. #elif defined (SOC_SERIES_STM32L4)/* APB1 80MHz(max) */
  92. static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
  93. {
  94. {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_2TQ | 10)},
  95. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_14TQ | CAN_BS2_5TQ | 5)},
  96. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_7TQ | CAN_BS2_2TQ | 16)},
  97. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 20)},
  98. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 40)},
  99. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 50)},
  100. {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 100)},
  101. {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 250)},
  102. {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 500)}
  103. };
  104. #endif
  105. #ifdef BSP_USING_CAN1
  106. static struct stm32_can drv_can1 =
  107. {
  108. .name = "can1",
  109. .CanHandle.Instance = CAN1,
  110. };
  111. #endif
  112. #ifdef BSP_USING_CAN2
  113. static struct stm32_can drv_can2 =
  114. {
  115. "can2",
  116. .CanHandle.Instance = CAN2,
  117. };
  118. #endif
  119. static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
  120. {
  121. rt_uint32_t len, index;
  122. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  123. for (index = 0; index < len; index++)
  124. {
  125. if (can_baud_rate_tab[index].baud_rate == baud)
  126. return index;
  127. }
  128. return 0; /* default baud is CAN1MBaud */
  129. }
  130. static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg)
  131. {
  132. struct stm32_can *drv_can;
  133. rt_uint32_t baud_index;
  134. RT_ASSERT(can);
  135. RT_ASSERT(cfg);
  136. drv_can = (struct stm32_can *)can->parent.user_data;
  137. RT_ASSERT(drv_can);
  138. drv_can->CanHandle.Init.TimeTriggeredMode = DISABLE;
  139. drv_can->CanHandle.Init.AutoBusOff = ENABLE;
  140. drv_can->CanHandle.Init.AutoWakeUp = DISABLE;
  141. drv_can->CanHandle.Init.AutoRetransmission = DISABLE;
  142. drv_can->CanHandle.Init.ReceiveFifoLocked = DISABLE;
  143. drv_can->CanHandle.Init.TransmitFifoPriority = ENABLE;
  144. switch (cfg->mode)
  145. {
  146. case RT_CAN_MODE_NORMAL:
  147. drv_can->CanHandle.Init.Mode = CAN_MODE_NORMAL;
  148. break;
  149. case RT_CAN_MODE_LISTEN:
  150. drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT;
  151. break;
  152. case RT_CAN_MODE_LOOPBACK:
  153. drv_can->CanHandle.Init.Mode = CAN_MODE_LOOPBACK;
  154. break;
  155. case RT_CAN_MODE_LOOPBACKANLISTEN:
  156. drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
  157. break;
  158. }
  159. baud_index = get_can_baud_index(cfg->baud_rate);
  160. drv_can->CanHandle.Init.SyncJumpWidth = BAUD_DATA(SJW, baud_index);
  161. drv_can->CanHandle.Init.TimeSeg1 = BAUD_DATA(BS1, baud_index);
  162. drv_can->CanHandle.Init.TimeSeg2 = BAUD_DATA(BS2, baud_index);
  163. drv_can->CanHandle.Init.Prescaler = BAUD_DATA(RRESCL, baud_index);
  164. /* init can */
  165. if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
  166. {
  167. return -RT_ERROR;
  168. }
  169. /* default filter config */
  170. HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
  171. return RT_EOK;
  172. }
  173. static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
  174. {
  175. rt_uint32_t argval;
  176. struct stm32_can *drv_can;
  177. struct rt_can_filter_config *filter_cfg;
  178. RT_ASSERT(can != RT_NULL);
  179. drv_can = (struct stm32_can *)can->parent.user_data;
  180. RT_ASSERT(drv_can != RT_NULL);
  181. switch (cmd)
  182. {
  183. case RT_DEVICE_CTRL_CLR_INT:
  184. argval = (rt_uint32_t) arg;
  185. if (argval == RT_DEVICE_FLAG_INT_RX)
  186. {
  187. if (CAN1 == drv_can->CanHandle.Instance)
  188. {
  189. HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
  190. HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
  191. }
  192. #ifdef CAN2
  193. if (CAN2 == drv_can->CanHandle.Instance)
  194. {
  195. HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
  196. HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
  197. }
  198. #endif
  199. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  200. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_FULL);
  201. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_OVERRUN);
  202. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  203. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
  204. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
  205. }
  206. else if (argval == RT_DEVICE_FLAG_INT_TX)
  207. {
  208. if (CAN1 == drv_can->CanHandle.Instance)
  209. {
  210. HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
  211. }
  212. #ifdef CAN2
  213. if (CAN2 == drv_can->CanHandle.Instance)
  214. {
  215. HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
  216. }
  217. #endif
  218. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
  219. }
  220. else if (argval == RT_DEVICE_CAN_INT_ERR)
  221. {
  222. if (CAN1 == drv_can->CanHandle.Instance)
  223. {
  224. NVIC_DisableIRQ(CAN1_SCE_IRQn);
  225. }
  226. #ifdef CAN2
  227. if (CAN2 == drv_can->CanHandle.Instance)
  228. {
  229. NVIC_DisableIRQ(CAN2_SCE_IRQn);
  230. }
  231. #endif
  232. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
  233. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
  234. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_BUSOFF);
  235. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_LAST_ERROR_CODE);
  236. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR);
  237. }
  238. break;
  239. case RT_DEVICE_CTRL_SET_INT:
  240. argval = (rt_uint32_t) arg;
  241. if (argval == RT_DEVICE_FLAG_INT_RX)
  242. {
  243. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  244. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_FULL);
  245. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_OVERRUN);
  246. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  247. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
  248. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
  249. if (CAN1 == drv_can->CanHandle.Instance)
  250. {
  251. HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
  252. HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  253. HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
  254. HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
  255. }
  256. #ifdef CAN2
  257. if (CAN2 == drv_can->CanHandle.Instance)
  258. {
  259. HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
  260. HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
  261. HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 1, 0);
  262. HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
  263. }
  264. #endif
  265. }
  266. else if (argval == RT_DEVICE_FLAG_INT_TX)
  267. {
  268. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
  269. if (CAN1 == drv_can->CanHandle.Instance)
  270. {
  271. HAL_NVIC_SetPriority(CAN1_TX_IRQn, 1, 0);
  272. HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
  273. }
  274. #ifdef CAN2
  275. if (CAN2 == drv_can->CanHandle.Instance)
  276. {
  277. HAL_NVIC_SetPriority(CAN2_TX_IRQn, 1, 0);
  278. HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
  279. }
  280. #endif
  281. }
  282. else if (argval == RT_DEVICE_CAN_INT_ERR)
  283. {
  284. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
  285. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
  286. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_BUSOFF);
  287. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_LAST_ERROR_CODE);
  288. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR);
  289. if (CAN1 == drv_can->CanHandle.Instance)
  290. {
  291. HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
  292. HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  293. }
  294. #ifdef CAN2
  295. if (CAN2 == drv_can->CanHandle.Instance)
  296. {
  297. HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 1, 0);
  298. HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
  299. }
  300. #endif
  301. }
  302. break;
  303. case RT_CAN_CMD_SET_FILTER:
  304. {
  305. rt_uint32_t id_h = 0;
  306. rt_uint32_t id_l = 0;
  307. rt_uint32_t mask_h = 0;
  308. rt_uint32_t mask_l = 0;
  309. rt_uint32_t mask_l_tail = 0; /*CAN_FxR2 bit [2:0]*/
  310. if (RT_NULL == arg)
  311. {
  312. /* default filter config */
  313. HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
  314. }
  315. else
  316. {
  317. filter_cfg = (struct rt_can_filter_config *)arg;
  318. if (!IS_CAN_FILTER_BANK_DUAL(drv_can->FilterConfig.SlaveStartFilterBank))
  319. {
  320. LOG_W("can%s invalid SlaveStartFilterBank=%d", drv_can->name, drv_can->FilterConfig.SlaveStartFilterBank);
  321. }
  322. /* get default filter */
  323. for (int i = 0; i < filter_cfg->count; i++)
  324. {
  325. if (filter_cfg->items[i].hdr_bank == -1)
  326. {
  327. /* use default filter bank settings */
  328. if (rt_strcmp(drv_can->name, "can1") == 0)
  329. {
  330. /* can1 banks 0~13 */
  331. drv_can->FilterConfig.FilterBank = i;
  332. }
  333. else if (rt_strcmp(drv_can->name, "can2") == 0)
  334. {
  335. /* can2 banks 14~27 */
  336. drv_can->FilterConfig.FilterBank = i + 14;
  337. }
  338. }
  339. else
  340. {
  341. /* use user-defined filter bank settings */
  342. drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr_bank;
  343. }
  344. if (!IS_CAN_FILTER_BANK_DUAL(drv_can->FilterConfig.FilterBank))
  345. {
  346. LOG_W("can%s invalid FilterBank=%d, skip item %d", drv_can->name, drv_can->FilterConfig.FilterBank, i);
  347. continue;
  348. }
  349. /**
  350. * ID | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
  351. * MASK | CAN_FxR2[31:24] | CAN_FxR2[23:16] | CAN_FxR2[15:8] | CAN_FxR2[7:0] |
  352. * STD ID | STID[10:3] | STDID[2:0] |<- 21bit ->|
  353. * EXT ID | EXTID[28:21] | EXTID[20:13] | EXTID[12:5] | EXTID[4:0] IDE RTR 0|
  354. * @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
  355. * -> but the id bit of struct rt_can_filter_item is 29,
  356. * -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
  357. * -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
  358. * -> FilterIdLow: ((STDid << 18) or (EXT id << 3)) & 0xFFFF.
  359. * @note the mask bit of struct rt_can_filter_item is 32,
  360. * -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF
  361. * -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF
  362. */
  363. if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
  364. {
  365. /* make sure the CAN_FxR1[2:0](IDE RTR) work */
  366. mask_l_tail = 0x06;
  367. }
  368. else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
  369. {
  370. /* same as CAN_FxR1 */
  371. mask_l_tail = (filter_cfg->items[i].ide << 2) |
  372. (filter_cfg->items[i].rtr << 1);
  373. }
  374. if (filter_cfg->items[i].ide == RT_CAN_STDID)
  375. {
  376. id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
  377. id_l = ((filter_cfg->items[i].id << 18) |
  378. (filter_cfg->items[i].ide << 2) |
  379. (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
  380. mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
  381. mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
  382. }
  383. else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
  384. {
  385. id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
  386. id_l = ((filter_cfg->items[i].id << 3) |
  387. (filter_cfg->items[i].ide << 2) |
  388. (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
  389. mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
  390. mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
  391. }
  392. drv_can->FilterConfig.FilterIdHigh = id_h;
  393. drv_can->FilterConfig.FilterIdLow = id_l;
  394. drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
  395. drv_can->FilterConfig.FilterMaskIdLow = mask_l;
  396. drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
  397. drv_can->FilterConfig.FilterFIFOAssignment = filter_cfg->items[i].rxfifo;/*rxfifo = CAN_RX_FIFO0/CAN_RX_FIFO1*/
  398. /* Filter conf */
  399. HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
  400. }
  401. }
  402. break;
  403. }
  404. case RT_CAN_CMD_SET_MODE:
  405. argval = (rt_uint32_t) arg;
  406. if (argval != RT_CAN_MODE_NORMAL &&
  407. argval != RT_CAN_MODE_LISTEN &&
  408. argval != RT_CAN_MODE_LOOPBACK &&
  409. argval != RT_CAN_MODE_LOOPBACKANLISTEN)
  410. {
  411. return -RT_ERROR;
  412. }
  413. if (argval != drv_can->device.config.mode)
  414. {
  415. drv_can->device.config.mode = argval;
  416. return _can_config(&drv_can->device, &drv_can->device.config);
  417. }
  418. break;
  419. case RT_CAN_CMD_SET_BAUD:
  420. argval = (rt_uint32_t) arg;
  421. if (argval != CAN1MBaud &&
  422. argval != CAN800kBaud &&
  423. argval != CAN500kBaud &&
  424. argval != CAN250kBaud &&
  425. argval != CAN125kBaud &&
  426. argval != CAN100kBaud &&
  427. argval != CAN50kBaud &&
  428. argval != CAN20kBaud &&
  429. argval != CAN10kBaud)
  430. {
  431. return -RT_ERROR;
  432. }
  433. if (argval != drv_can->device.config.baud_rate)
  434. {
  435. drv_can->device.config.baud_rate = argval;
  436. return _can_config(&drv_can->device, &drv_can->device.config);
  437. }
  438. break;
  439. case RT_CAN_CMD_SET_PRIV:
  440. argval = (rt_uint32_t) arg;
  441. if (argval != RT_CAN_MODE_PRIV &&
  442. argval != RT_CAN_MODE_NOPRIV)
  443. {
  444. return -RT_ERROR;
  445. }
  446. if (argval != drv_can->device.config.privmode)
  447. {
  448. drv_can->device.config.privmode = argval;
  449. return _can_config(&drv_can->device, &drv_can->device.config);
  450. }
  451. break;
  452. case RT_CAN_CMD_GET_STATUS:
  453. {
  454. rt_uint32_t errtype;
  455. errtype = drv_can->CanHandle.Instance->ESR;
  456. drv_can->device.status.rcverrcnt = errtype >> 24;
  457. drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF);
  458. drv_can->device.status.lasterrtype = errtype & 0x70;
  459. drv_can->device.status.errcode = errtype & 0x07;
  460. rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status));
  461. break;
  462. }
  463. case RT_CAN_CMD_START:
  464. argval = (rt_uint32_t) arg;
  465. if (argval == 0)
  466. {
  467. if (HAL_CAN_DeInit(&drv_can->CanHandle) != HAL_OK)
  468. {
  469. LOG_E("CAN deinitialization failed");
  470. return -RT_ERROR;
  471. }
  472. }
  473. else
  474. {
  475. rt_err_t result = _can_config(&drv_can->device, &drv_can->device.config);
  476. if (result != RT_EOK)
  477. {
  478. return result;
  479. }
  480. if (HAL_CAN_Start(&drv_can->CanHandle) != HAL_OK)
  481. {
  482. return -RT_ERROR;
  483. }
  484. }
  485. break;
  486. }
  487. return RT_EOK;
  488. }
  489. /**
  490. * @internal
  491. * @brief Low-level function to send a CAN message to a specific hardware mailbox.
  492. *
  493. * This function is part of the **blocking** send mechanism. It is called by
  494. * `_can_int_tx` after a hardware mailbox has already been acquired. Its role is
  495. * to format the message according to the STM32 hardware requirements and place
  496. * it into the specified mailbox for transmission.
  497. *
  498. * @param[in] can A pointer to the CAN device structure.
  499. * @param[in] buf A pointer to the `rt_can_msg` to be sent.
  500. * @param[in] box_num The specific hardware mailbox index (0, 1, or 2) to use for this tran
  501. *
  502. * @return `RT_EOK` on success, or an error code on failure.
  503. */
  504. static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
  505. {
  506. CAN_HandleTypeDef *hcan;
  507. hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  508. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  509. CAN_TxHeaderTypeDef txheader = {0};
  510. HAL_CAN_StateTypeDef state = hcan->State;
  511. /* Check the parameters */
  512. RT_ASSERT(IS_CAN_DLC(pmsg->len));
  513. if ((state == HAL_CAN_STATE_READY) ||
  514. (state == HAL_CAN_STATE_LISTENING))
  515. {
  516. /*check select mailbox is empty */
  517. uint32_t mailbox_mask;
  518. uint32_t tme_flag;
  519. switch (1 << box_num)
  520. {
  521. case CAN_TX_MAILBOX0:
  522. mailbox_mask = CAN_TX_MAILBOX0;
  523. tme_flag = CAN_TSR_TME0;
  524. break;
  525. case CAN_TX_MAILBOX1:
  526. mailbox_mask = CAN_TX_MAILBOX1;
  527. tme_flag = CAN_TSR_TME1;
  528. break;
  529. case CAN_TX_MAILBOX2:
  530. mailbox_mask = CAN_TX_MAILBOX2;
  531. tme_flag = CAN_TSR_TME2;
  532. break;
  533. default:
  534. RT_ASSERT(0);
  535. return -RT_ERROR;
  536. }
  537. if (HAL_IS_BIT_SET(hcan->Instance->TSR, tme_flag) != SET)
  538. {
  539. RT_UNUSED(mailbox_mask);
  540. return -RT_ERROR;
  541. }
  542. if (RT_CAN_STDID == pmsg->ide)
  543. {
  544. txheader.IDE = CAN_ID_STD;
  545. RT_ASSERT(IS_CAN_STDID(pmsg->id));
  546. txheader.StdId = pmsg->id;
  547. }
  548. else
  549. {
  550. txheader.IDE = CAN_ID_EXT;
  551. RT_ASSERT(IS_CAN_EXTID(pmsg->id));
  552. txheader.ExtId = pmsg->id;
  553. }
  554. if (RT_CAN_DTR == pmsg->rtr)
  555. {
  556. txheader.RTR = CAN_RTR_DATA;
  557. }
  558. else
  559. {
  560. txheader.RTR = CAN_RTR_REMOTE;
  561. }
  562. /* clear TIR */
  563. hcan->Instance->sTxMailBox[box_num].TIR &= CAN_TI0R_TXRQ;
  564. /* Set up the Id */
  565. if (RT_CAN_STDID == pmsg->ide)
  566. {
  567. hcan->Instance->sTxMailBox[box_num].TIR |= (txheader.StdId << CAN_TI0R_STID_Pos) | txheader.RTR;
  568. }
  569. else
  570. {
  571. hcan->Instance->sTxMailBox[box_num].TIR |= (txheader.ExtId << CAN_TI0R_EXID_Pos) | txheader.IDE | txheader.RTR;
  572. }
  573. /* Set up the DLC */
  574. hcan->Instance->sTxMailBox[box_num].TDTR = pmsg->len & 0x0FU;
  575. /* Set up the data field */
  576. WRITE_REG(hcan->Instance->sTxMailBox[box_num].TDHR,
  577. ((uint32_t)pmsg->data[7] << CAN_TDH0R_DATA7_Pos) |
  578. ((uint32_t)pmsg->data[6] << CAN_TDH0R_DATA6_Pos) |
  579. ((uint32_t)pmsg->data[5] << CAN_TDH0R_DATA5_Pos) |
  580. ((uint32_t)pmsg->data[4] << CAN_TDH0R_DATA4_Pos));
  581. WRITE_REG(hcan->Instance->sTxMailBox[box_num].TDLR,
  582. ((uint32_t)pmsg->data[3] << CAN_TDL0R_DATA3_Pos) |
  583. ((uint32_t)pmsg->data[2] << CAN_TDL0R_DATA2_Pos) |
  584. ((uint32_t)pmsg->data[1] << CAN_TDL0R_DATA1_Pos) |
  585. ((uint32_t)pmsg->data[0] << CAN_TDL0R_DATA0_Pos));
  586. /* Request transmission */
  587. SET_BIT(hcan->Instance->sTxMailBox[box_num].TIR, CAN_TI0R_TXRQ);
  588. return RT_EOK;
  589. }
  590. else
  591. {
  592. /* Update error code */
  593. hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
  594. return -RT_ERROR;
  595. }
  596. }
  597. /**
  598. * @internal
  599. * @brief Low-level, hardware-specific non-blocking function to send a CAN message.
  600. *
  601. * This function interacts directly with the STM32 HAL library to add a message
  602. * to a hardware TX mailbox. It returns immediately and does not wait for the
  603. * transmission to complete.
  604. *
  605. * @param[in] can A pointer to the CAN device structure.
  606. * @param[in] buf A pointer to the `rt_can_msg` to be sent.
  607. *
  608. * @return
  609. * - `RT_EOK` if the message was successfully accepted by the hardware.
  610. * - `-RT_EBUSY` if all hardware mailboxes are currently full.
  611. * - `-RT_ERROR` on other HAL failures.
  612. */
  613. static rt_ssize_t _can_sendmsg_nonblocking(struct rt_can_device *can, const void *buf)
  614. {
  615. CAN_HandleTypeDef *hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  616. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  617. CAN_TxHeaderTypeDef txheader = {0};
  618. uint32_t tx_mailbox;
  619. if ((hcan->State != HAL_CAN_STATE_READY) && (hcan->State != HAL_CAN_STATE_LISTENING))
  620. return -RT_ERROR;
  621. if (HAL_CAN_GetTxMailboxesFreeLevel(hcan) == 0)
  622. return -RT_EBUSY;
  623. txheader.DLC = pmsg->len;
  624. txheader.RTR = (pmsg->rtr == RT_CAN_RTR) ? CAN_RTR_REMOTE : CAN_RTR_DATA;
  625. txheader.IDE = (pmsg->ide == RT_CAN_STDID) ? CAN_ID_STD : CAN_ID_EXT;
  626. if (txheader.IDE == CAN_ID_STD)
  627. txheader.StdId = pmsg->id;
  628. else
  629. txheader.ExtId = pmsg->id;
  630. HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(hcan, &txheader, pmsg->data, &tx_mailbox);
  631. if (status != HAL_OK)
  632. {
  633. LOG_W("can sendmsg nonblocking send error %d", status);
  634. return -RT_ERROR;
  635. }
  636. return RT_EOK;
  637. }
  638. static rt_ssize_t _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
  639. {
  640. HAL_StatusTypeDef status;
  641. CAN_HandleTypeDef *hcan;
  642. struct rt_can_msg *pmsg;
  643. CAN_RxHeaderTypeDef rxheader = {0};
  644. RT_ASSERT(can);
  645. hcan = &((struct stm32_can *)can->parent.user_data)->CanHandle;
  646. pmsg = (struct rt_can_msg *) buf;
  647. /* get data */
  648. status = HAL_CAN_GetRxMessage(hcan, fifo, &rxheader, pmsg->data);
  649. if (HAL_OK != status)
  650. return -RT_ERROR;
  651. /* get id */
  652. if (CAN_ID_STD == rxheader.IDE)
  653. {
  654. pmsg->ide = RT_CAN_STDID;
  655. pmsg->id = rxheader.StdId;
  656. }
  657. else
  658. {
  659. pmsg->ide = RT_CAN_EXTID;
  660. pmsg->id = rxheader.ExtId;
  661. }
  662. /* get type */
  663. if (CAN_RTR_DATA == rxheader.RTR)
  664. {
  665. pmsg->rtr = RT_CAN_DTR;
  666. }
  667. else
  668. {
  669. pmsg->rtr = RT_CAN_RTR;
  670. }
  671. /*get rxfifo = CAN_RX_FIFO0/CAN_RX_FIFO1*/
  672. pmsg->rxfifo = fifo;
  673. /* get len */
  674. pmsg->len = rxheader.DLC;
  675. /* get hdr_index */
  676. if (hcan->Instance == CAN1)
  677. {
  678. pmsg->hdr_index = rxheader.FilterMatchIndex;
  679. }
  680. #ifdef CAN2
  681. else if (hcan->Instance == CAN2)
  682. {
  683. pmsg->hdr_index = rxheader.FilterMatchIndex;
  684. }
  685. #endif
  686. return RT_EOK;
  687. }
  688. static const struct rt_can_ops _can_ops =
  689. {
  690. .configure = _can_config,
  691. .control = _can_control,
  692. .sendmsg = _can_sendmsg,
  693. .recvmsg = _can_recvmsg,
  694. .sendmsg_nonblocking = _can_sendmsg_nonblocking,
  695. };
  696. static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
  697. {
  698. CAN_HandleTypeDef *hcan;
  699. RT_ASSERT(can);
  700. hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  701. switch (fifo)
  702. {
  703. case CAN_RX_FIFO0:
  704. /* save to user list: drain multiple frames per ISR to reduce FULL/OVERRUN */
  705. if (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_MSG_PENDING))
  706. {
  707. for (rt_uint32_t i = 0; i < CAN_ISR_DRAIN_LIMIT; i++)
  708. {
  709. if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) == 0)
  710. {
  711. break;
  712. }
  713. else
  714. {
  715. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  716. }
  717. }
  718. }
  719. /* Check FULL flag for FIFO0 */
  720. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_FULL))
  721. {
  722. /* Clear FIFO0 FULL Flag */
  723. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
  724. }
  725. /* Check Overrun flag for FIFO0 */
  726. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_OVERRUN))
  727. {
  728. /* Clear FIFO0 Overrun Flag */
  729. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
  730. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  731. }
  732. break;
  733. case CAN_RX_FIFO1:
  734. /* save to user list: drain multiple frames per ISR to reduce FULL/OVERRUN */
  735. if (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_MSG_PENDING))
  736. {
  737. for (rt_uint32_t i = 0; i < CAN_ISR_DRAIN_LIMIT; i++)
  738. {
  739. if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) == 0)
  740. {
  741. break;
  742. }
  743. else
  744. {
  745. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  746. }
  747. }
  748. }
  749. /* Check FULL flag for FIFO1 */
  750. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_FULL))
  751. {
  752. /* Clear FIFO1 FULL Flag */
  753. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
  754. }
  755. /* Check Overrun flag for FIFO1 */
  756. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_OVERRUN))
  757. {
  758. /* Clear FIFO1 Overrun Flag */
  759. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
  760. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  761. }
  762. break;
  763. }
  764. }
  765. static void _can_check_tx_complete(struct rt_can_device *can)
  766. {
  767. CAN_HandleTypeDef *hcan;
  768. RT_ASSERT(can);
  769. hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  770. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
  771. {
  772. if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
  773. {
  774. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  775. }
  776. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
  777. }
  778. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
  779. {
  780. if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
  781. {
  782. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  783. }
  784. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
  785. }
  786. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
  787. {
  788. if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
  789. {
  790. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  791. }
  792. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
  793. }
  794. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR0))/*IF AutoRetransmission = ENABLE,ACK ERR handler*/
  795. {
  796. SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);/*Abort the send request, trigger the TX interrupt,release completion quantity*/
  797. }
  798. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR1))
  799. {
  800. SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
  801. }
  802. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR2))
  803. {
  804. SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
  805. }
  806. }
  807. static void _can_sce_isr(struct rt_can_device *can)
  808. {
  809. CAN_HandleTypeDef *hcan;
  810. RT_ASSERT(can);
  811. hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  812. rt_uint32_t errtype = hcan->Instance->ESR;
  813. switch ((errtype & 0x70) >> 4)
  814. {
  815. case RT_CAN_BUS_BIT_PAD_ERR:
  816. can->status.bitpaderrcnt++;
  817. break;
  818. case RT_CAN_BUS_FORMAT_ERR:
  819. can->status.formaterrcnt++;
  820. break;
  821. case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
  822. can->status.ackerrcnt++;
  823. break;
  824. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  825. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  826. can->status.biterrcnt++;
  827. break;
  828. case RT_CAN_BUS_CRC_ERR:
  829. can->status.crcerrcnt++;
  830. break;
  831. }
  832. _can_check_tx_complete(can);
  833. can->status.lasterrtype = errtype & 0x70;
  834. can->status.rcverrcnt = errtype >> 24;
  835. can->status.snderrcnt = (errtype >> 16 & 0xFF);
  836. can->status.errcode = errtype & 0x07;
  837. hcan->Instance->MSR |= CAN_MSR_ERRI;
  838. }
  839. /**
  840. * @internal
  841. * @brief The low-level ISR for CAN TX events on STM32.
  842. *
  843. * This function's sole responsibility is to check the hardware status flags
  844. * to determine which mailbox completed a transmission and whether it was
  845. * successful or failed. It then reports the specific event to the upper
  846. * framework layer via `rt_hw_can_isr()`.
  847. *
  848. * @note This ISR contains NO framework-level logic (e.g., buffer handling).
  849. * It is a pure hardware event reporter, ensuring a clean separation
  850. * of concerns between the driver and the framework.
  851. *
  852. * @param[in] can A pointer to the CAN device structure.
  853. * @return void
  854. */
  855. static void _can_tx_isr(struct rt_can_device *can)
  856. {
  857. CAN_HandleTypeDef *hcan;
  858. RT_ASSERT(can);
  859. hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
  860. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
  861. {
  862. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
  863. {
  864. rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 0 << 8);
  865. }
  866. else
  867. {
  868. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  869. }
  870. /* Write 0 to Clear transmission status flag RQCPx */
  871. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
  872. }
  873. else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
  874. {
  875. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
  876. {
  877. rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 1 << 8);
  878. }
  879. else
  880. {
  881. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  882. }
  883. /* Write 0 to Clear transmission status flag RQCPx */
  884. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
  885. }
  886. else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
  887. {
  888. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
  889. {
  890. rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 2 << 8);
  891. }
  892. else
  893. {
  894. rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  895. }
  896. /* Write 0 to Clear transmission status flag RQCPx */
  897. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
  898. }
  899. }
  900. #ifdef BSP_USING_CAN1
  901. /**
  902. * @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
  903. */
  904. void CAN1_TX_IRQHandler(void)
  905. {
  906. rt_interrupt_enter();
  907. _can_tx_isr(&drv_can1.device);
  908. rt_interrupt_leave();
  909. }
  910. /**
  911. * @brief This function handles CAN1 RX0 interrupts.
  912. */
  913. void CAN1_RX0_IRQHandler(void)
  914. {
  915. rt_interrupt_enter();
  916. _can_rx_isr(&drv_can1.device, CAN_RX_FIFO0);
  917. rt_interrupt_leave();
  918. }
  919. /**
  920. * @brief This function handles CAN1 RX1 interrupts.
  921. */
  922. void CAN1_RX1_IRQHandler(void)
  923. {
  924. rt_interrupt_enter();
  925. _can_rx_isr(&drv_can1.device, CAN_RX_FIFO1);
  926. rt_interrupt_leave();
  927. }
  928. /**
  929. * @brief This function handles CAN1 SCE interrupts.
  930. */
  931. void CAN1_SCE_IRQHandler(void)
  932. {
  933. rt_interrupt_enter();
  934. _can_sce_isr(&drv_can1.device);
  935. rt_interrupt_leave();
  936. }
  937. #endif /* BSP_USING_CAN1 */
  938. #ifdef BSP_USING_CAN2
  939. /**
  940. * @brief This function handles CAN2 TX interrupts.
  941. */
  942. void CAN2_TX_IRQHandler(void)
  943. {
  944. rt_interrupt_enter();
  945. _can_tx_isr(&drv_can2.device);
  946. rt_interrupt_leave();
  947. }
  948. /**
  949. * @brief This function handles CAN2 RX0 interrupts.
  950. */
  951. void CAN2_RX0_IRQHandler(void)
  952. {
  953. rt_interrupt_enter();
  954. _can_rx_isr(&drv_can2.device, CAN_RX_FIFO0);
  955. rt_interrupt_leave();
  956. }
  957. /**
  958. * @brief This function handles CAN2 RX1 interrupts.
  959. */
  960. void CAN2_RX1_IRQHandler(void)
  961. {
  962. rt_interrupt_enter();
  963. _can_rx_isr(&drv_can2.device, CAN_RX_FIFO1);
  964. rt_interrupt_leave();
  965. }
  966. /**
  967. * @brief This function handles CAN2 SCE interrupts.
  968. */
  969. void CAN2_SCE_IRQHandler(void)
  970. {
  971. rt_interrupt_enter();
  972. _can_sce_isr(&drv_can2.device);
  973. rt_interrupt_leave();
  974. }
  975. #endif /* BSP_USING_CAN2 */
  976. int rt_hw_can_init(void)
  977. {
  978. struct can_configure config = CANDEFAULTCONFIG;
  979. config.privmode = RT_CAN_MODE_NOPRIV;
  980. config.ticks = 50;
  981. #ifdef RT_CAN_USING_HDR
  982. config.maxhdr = 14;
  983. #ifdef CAN2
  984. config.maxhdr = 28;
  985. #endif
  986. #endif
  987. /* config default filter */
  988. CAN_FilterTypeDef filterConf = {0};
  989. filterConf.FilterIdHigh = 0x0000;
  990. filterConf.FilterIdLow = 0x0000;
  991. filterConf.FilterMaskIdHigh = 0x0000;
  992. filterConf.FilterMaskIdLow = 0x0000;
  993. filterConf.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  994. filterConf.FilterBank = 0;
  995. filterConf.FilterMode = CAN_FILTERMODE_IDMASK;
  996. filterConf.FilterScale = CAN_FILTERSCALE_32BIT;
  997. filterConf.FilterActivation = ENABLE;
  998. filterConf.SlaveStartFilterBank = 14;
  999. #ifdef BSP_USING_CAN1
  1000. filterConf.FilterBank = 0;
  1001. drv_can1.FilterConfig = filterConf;
  1002. drv_can1.device.config = config;
  1003. /* register CAN1 device */
  1004. rt_hw_can_register(&drv_can1.device,
  1005. drv_can1.name,
  1006. &_can_ops,
  1007. &drv_can1);
  1008. #endif /* BSP_USING_CAN1 */
  1009. #ifdef BSP_USING_CAN2
  1010. filterConf.FilterBank = filterConf.SlaveStartFilterBank;
  1011. drv_can2.FilterConfig = filterConf;
  1012. drv_can2.device.config = config;
  1013. /* register CAN2 device */
  1014. rt_hw_can_register(&drv_can2.device,
  1015. drv_can2.name,
  1016. &_can_ops,
  1017. &drv_can2);
  1018. #endif /* BSP_USING_CAN2 */
  1019. return 0;
  1020. }
  1021. INIT_BOARD_EXPORT(rt_hw_can_init);
  1022. #endif /* BSP_USING_CAN */
  1023. /************************** end of file ******************/