drv_can.c 36 KB

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