drv_mcan.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. /*
  2. * Copyright (c) 2023-2025 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-04-07 HPMicro the first version
  9. * 2024-05-31 HPMicro add MCAN4-7 support
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <rthw.h>
  14. #include "board.h"
  15. #include "hpm_mcan_drv.h"
  16. #include "hpm_clock_drv.h"
  17. #define CAN_SEND_WAIT_MS_MAX (1000U) /* CAN maximum wait time for transmission */
  18. #define CAN_SENDBOX_NUM (1U) /* CAN Hardware Transmission buffer number */
  19. #define CAN_STD_FILTER_NUM_MAX (128U) /* std Filter number */
  20. #define CAN_EXT_FILTER_NUM_MAX (64U) /* ext Filter number */
  21. #ifdef RT_USING_CAN
  22. typedef struct _hpm_can_struct
  23. {
  24. MCAN_Type *can_base; /**< CAN Base address */
  25. const char *name; /**< CAN device name */
  26. int32_t irq_num; /**< CAN IRQ index */
  27. uint8_t irq_priority; /**< CAN IRQ priority */
  28. clock_name_t clk_name; /**< CAN clock name */
  29. uint32_t fifo_index; /**< FIFO index, it is a fake value to satisfy the driver framework */
  30. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  31. uint32_t ram_base;
  32. uint32_t ram_size;
  33. #endif
  34. mcan_config_t can_config; /**< CAN configuration for IP */
  35. struct rt_can_device can_dev; /**< CAN device configuration in rt-thread */
  36. uint32_t irq_txrx_err_enable_mask; /**< CAN TX and RX IRQ Enable Mask */
  37. uint32_t std_filter_num; /**< std Filter number */
  38. mcan_filter_elem_t std_can_filters[CAN_STD_FILTER_NUM_MAX];
  39. uint32_t ext_filter_num; /**< ext Filter number */
  40. mcan_filter_elem_t ext_can_filters[CAN_EXT_FILTER_NUM_MAX];
  41. } hpm_can_t;
  42. static const mcan_filter_elem_t k_default_std_id_filter = {
  43. /* Use classic filter */
  44. .filter_type = MCAN_FILTER_TYPE_CLASSIC_FILTER,
  45. /* Store message into RXFIFO0 if matching */
  46. .filter_config = MCAN_FILTER_ELEM_CFG_STORE_IN_RX_FIFO0_IF_MATCH,
  47. /* For Standard ID only */
  48. .can_id_type = MCAN_CAN_ID_TYPE_STANDARD,
  49. /* Sync Message, only evaluated when "CCCR.UTSU" is set */
  50. .sync_message = 0U,
  51. /* Don't care if mask is set to all 1s */
  52. .filter_id = 0U,
  53. /* Accept all messages */
  54. .filter_mask = 0x7FFU,
  55. };
  56. static const mcan_filter_elem_t k_default_ext_id_filter = {
  57. /* Use classic filter */
  58. .filter_type = MCAN_FILTER_TYPE_CLASSIC_FILTER,
  59. /* Store message into RXFIFO0 if matching */
  60. .filter_config = MCAN_FILTER_ELEM_CFG_STORE_IN_RX_FIFO0_IF_MATCH,
  61. /* For Extended ID only */
  62. .can_id_type = MCAN_CAN_ID_TYPE_EXTENDED,
  63. /* Sync Message, only evaluated when "CCCR.UTSU" is set */
  64. .sync_message = 0,
  65. /* Don't care if mask is set to all 1s */
  66. .filter_id = 0,
  67. /* Accept all messages */
  68. .filter_mask = 0x1FFFFFFFUL,
  69. };
  70. /**
  71. * @brief Configure CAN controller
  72. * @param [in/out] can CAN device pointer
  73. * @param [in] cfg CAN configuration pointer
  74. * @retval RT_EOK for valid configuration
  75. * @retval -RT_ERROR for invalid configuration
  76. */
  77. static rt_err_t hpm_mcan_configure(struct rt_can_device *can, struct can_configure *cfg);
  78. /**
  79. * @brief Control/Get CAN state
  80. * including:interrupt, mode, priority, baudrate, filter, status
  81. * @param [in/out] can CAN device pointer
  82. * @param [in] cmd Control command
  83. * @param [in/out] arg Argument pointer
  84. * @retval RT_EOK for valid control command and arg
  85. * @retval -RT_ERROR for invalid control command or arg
  86. */
  87. static rt_err_t hpm_mcan_control(struct rt_can_device *can, int cmd, void *arg);
  88. /**
  89. * @brief Send out CAN message
  90. * @param [in] can CAN device pointer
  91. * @param [in] buf CAN message buffer
  92. * @param [in] boxno Mailbox number, it is not used in this porting
  93. * @retval RT_EOK No error
  94. * @retval -RT_ETIMEOUT timeout happened
  95. * @retval -RT_EFULL Transmission buffer is full
  96. */
  97. static int hpm_mcan_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno);
  98. /**
  99. * @brief Receive message from CAN
  100. * @param [in] can CAN device pointer
  101. * @param [out] buf CAN receive buffer
  102. * @param [in] boxno Mailbox Number, it is not used in this porting
  103. * @retval RT_EOK no error
  104. * @retval -RT_ERROR Error happened during reading receive FIFO
  105. * @retval -RT_EMPTY no data in receive FIFO
  106. */
  107. static int hpm_mcan_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
  108. /**
  109. * @brief Common Interrupt Service routine
  110. * @param [in] hpm_can HPM CAN pointer
  111. */
  112. static void hpm_mcan_isr(hpm_can_t *hpm_can);
  113. /**
  114. * @brief Decode data bytes from DLC
  115. * @param [in] dlc Data Length Code
  116. * @return decoded data bytes
  117. */
  118. static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc);
  119. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  120. #if defined(HPM_MCAN0_BASE) && defined(BSP_USING_MCAN0)
  121. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan0_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  122. #endif
  123. #if defined(HPM_MCAN1_BASE) && defined(BSP_USING_MCAN1)
  124. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan1_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  125. #endif
  126. #if defined(HPM_MCAN2_BASE) && defined(BSP_USING_MCAN2)
  127. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan2_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  128. #endif
  129. #if defined(HPM_MCAN3_BASE) && defined(BSP_USING_MCAN3)
  130. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan3_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  131. #endif
  132. #if defined(HPM_MCAN4_BASE) && defined(BSP_USING_MCAN4)
  133. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan4_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  134. #endif
  135. #if defined(HPM_MCAN5_BASE) && defined(BSP_USING_MCAN5)
  136. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan5_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  137. #endif
  138. #if defined(HPM_MCAN6_BASE) && defined(BSP_USING_MCAN6)
  139. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan6_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  140. #endif
  141. #if defined(HPM_MCAN7_BASE) && defined(BSP_USING_MCAN7)
  142. ATTR_PLACE_AT(".ahb_sram") uint32_t mcan7_msg_buf[MCAN_MSG_BUF_SIZE_IN_WORDS];
  143. #endif
  144. #endif
  145. #if defined(HPM_MCAN0_BASE) && defined(BSP_USING_MCAN0)
  146. static hpm_can_t dev_can0 =
  147. {
  148. .can_base = HPM_MCAN0,
  149. .name = "can0",
  150. .irq_num = IRQn_MCAN0,
  151. #if defined(BSP_MCAN0_IRQ_PRIORITY)
  152. .irq_priority = BSP_MCAN0_IRQ_PRIORITY,
  153. #else
  154. .irq_priority = 1,
  155. #endif
  156. .fifo_index = 0,
  157. .clk_name = clock_can0,
  158. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  159. .ram_base = (uint32_t) &mcan0_msg_buf,
  160. .ram_size = sizeof(mcan0_msg_buf),
  161. #endif
  162. };
  163. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN0, can0_isr);
  164. void can0_isr(void)
  165. {
  166. hpm_mcan_isr(&dev_can0);
  167. }
  168. #endif
  169. #if defined(HPM_MCAN1_BASE) && defined(BSP_USING_MCAN1)
  170. static hpm_can_t dev_can1 =
  171. {
  172. .can_base = HPM_MCAN1,
  173. .name = "can1",
  174. .irq_num = IRQn_MCAN1,
  175. #if defined(BSP_MCAN1_IRQ_PRIORITY)
  176. .irq_priority = BSP_MCAN1_IRQ_PRIORITY,
  177. #else
  178. .irq_priority = 1,
  179. #endif
  180. .fifo_index = 1,
  181. .clk_name = clock_can1,
  182. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  183. .ram_base = (uint32_t) &mcan1_msg_buf,
  184. .ram_size = sizeof(mcan1_msg_buf),
  185. #endif
  186. };
  187. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN1, can1_isr);
  188. void can1_isr(void)
  189. {
  190. hpm_mcan_isr(&dev_can1);
  191. }
  192. #endif
  193. #if defined(HPM_MCAN2_BASE) && defined(BSP_USING_MCAN2)
  194. static hpm_can_t dev_can2 =
  195. {
  196. .can_base = HPM_MCAN2,
  197. .name = "can2",
  198. .irq_num = IRQn_MCAN2,
  199. #if defined(BSP_MCAN2_IRQ_PRIORITY)
  200. .irq_priority = BSP_MCAN2_IRQ_PRIORITY,
  201. #else
  202. .irq_priority = 1,
  203. #endif
  204. .fifo_index = 2,
  205. .clk_name = clock_can2,
  206. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  207. .ram_base = (uint32_t) &mcan2_msg_buf,
  208. .ram_size = sizeof(mcan2_msg_buf),
  209. #endif
  210. };
  211. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN2, can2_isr);
  212. void can2_isr(void)
  213. {
  214. hpm_mcan_isr(&dev_can2);
  215. }
  216. #endif
  217. #if defined(HPM_MCAN3_BASE) && defined(BSP_USING_MCAN3)
  218. static hpm_can_t dev_can3 =
  219. {
  220. .can_base = HPM_MCAN3,
  221. .name = "can3",
  222. .irq_num = IRQn_MCAN3,
  223. #if defined(BSP_MCAN3_IRQ_PRIORITY)
  224. .irq_priority = BSP_MCAN3_IRQ_PRIORITY,
  225. #else
  226. .irq_priority = 1,
  227. #endif
  228. .fifo_index = 3,
  229. .clk_name = clock_can3,
  230. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  231. .ram_base = (uint32_t) &mcan3_msg_buf,
  232. .ram_size = sizeof(mcan3_msg_buf),
  233. #endif
  234. };
  235. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN3, can3_isr);
  236. void can3_isr(void)
  237. {
  238. hpm_mcan_isr(&dev_can3);
  239. }
  240. #endif
  241. #if defined(HPM_MCAN4_BASE) && defined(BSP_USING_MCAN4)
  242. static hpm_can_t dev_can4 =
  243. {
  244. .can_base = HPM_MCAN4,
  245. .name = "can4",
  246. .irq_num = IRQn_MCAN4,
  247. #if defined(BSP_MCAN4_IRQ_PRIORITY)
  248. .irq_priority = BSP_MCAN4_IRQ_PRIORITY,
  249. #else
  250. .irq_priority = 1,
  251. #endif
  252. .fifo_index = 4,
  253. .clk_name = clock_can4,
  254. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  255. .ram_base = (uint32_t) &mcan4_msg_buf,
  256. .ram_size = sizeof(mcan4_msg_buf),
  257. #endif
  258. };
  259. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN4, can4_isr);
  260. void can4_isr(void)
  261. {
  262. hpm_mcan_isr(&dev_can4);
  263. }
  264. #endif
  265. #if defined(HPM_MCAN5_BASE) && defined(BSP_USING_MCAN5)
  266. static hpm_can_t dev_can5 =
  267. {
  268. .can_base = HPM_MCAN5,
  269. .name = "can5",
  270. .irq_num = IRQn_MCAN5,
  271. #if defined(BSP_MCAN5_IRQ_PRIORITY)
  272. .irq_priority = BSP_MCAN5_IRQ_PRIORITY,
  273. #else
  274. .irq_priority = 1,
  275. #endif
  276. .fifo_index = 5,
  277. .clk_name = clock_can5,
  278. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  279. .ram_base = (uint32_t) &mcan5_msg_buf,
  280. .ram_size = sizeof(mcan5_msg_buf),
  281. #endif
  282. };
  283. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN5, can5_isr);
  284. void can5_isr(void)
  285. {
  286. hpm_mcan_isr(&dev_can5);
  287. }
  288. #endif
  289. #if defined(HPM_MCAN6_BASE) && defined(BSP_USING_MCAN6)
  290. static hpm_can_t dev_can6 =
  291. {
  292. .can_base = HPM_MCAN6,
  293. .name = "can6",
  294. .irq_num = IRQn_MCAN6,
  295. #if defined(BSP_MCAN6_IRQ_PRIORITY)
  296. .irq_priority = BSP_MCAN6_IRQ_PRIORITY,
  297. #else
  298. .irq_priority = 1,
  299. #endif
  300. .fifo_index = 6,
  301. .clk_name = clock_can6,
  302. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  303. .ram_base = (uint32_t) &mcan6_msg_buf,
  304. .ram_size = sizeof(mcan6_msg_buf),
  305. #endif
  306. };
  307. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN6, can6_isr);
  308. void can6_isr(void)
  309. {
  310. hpm_mcan_isr(&dev_can6);
  311. }
  312. #endif
  313. #if defined(HPM_MCAN7_BASE) && defined(BSP_USING_MCAN7)
  314. static hpm_can_t dev_can7 =
  315. {
  316. .can_base = HPM_MCAN7,
  317. .name = "can7",
  318. .irq_num = IRQn_MCAN7,
  319. #if defined(BSP_MCAN7_IRQ_PRIORITY)
  320. .irq_priority = BSP_MCAN7_IRQ_PRIORITY,
  321. #else
  322. .irq_priority = 1,
  323. #endif
  324. .fifo_index = 7,
  325. .clk_name = clock_can7,
  326. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  327. .ram_base = (uint32_t) &mcan7_msg_buf,
  328. .ram_size = sizeof(mcan7_msg_buf),
  329. #endif
  330. };
  331. SDK_DECLARE_EXT_ISR_M(IRQn_MCAN7, can7_isr);
  332. void can7_isr(void)
  333. {
  334. hpm_mcan_isr(&dev_can7);
  335. }
  336. #endif
  337. static hpm_can_t *hpm_cans[] = {
  338. #if defined(HPM_MCAN0_BASE) && defined(BSP_USING_MCAN0)
  339. &dev_can0,
  340. #endif
  341. #if defined(HPM_MCAN1_BASE) && defined(BSP_USING_MCAN1)
  342. &dev_can1,
  343. #endif
  344. #if defined(HPM_MCAN2_BASE) && defined(BSP_USING_MCAN2)
  345. &dev_can2,
  346. #endif
  347. #if defined(HPM_MCAN3_BASE) && defined(BSP_USING_MCAN3)
  348. &dev_can3,
  349. #endif
  350. #if defined(HPM_MCAN4_BASE) && defined(BSP_USING_MCAN4)
  351. &dev_can4,
  352. #endif
  353. #if defined(HPM_MCAN5_BASE) && defined(BSP_USING_MCAN5)
  354. &dev_can5,
  355. #endif
  356. #if defined(HPM_MCAN6_BASE) && defined(BSP_USING_MCAN6)
  357. &dev_can6,
  358. #endif
  359. #if defined(HPM_MCAN7_BASE) && defined(BSP_USING_MCAN7)
  360. &dev_can7,
  361. #endif
  362. };
  363. static const struct rt_can_ops hpm_can_ops = {
  364. .configure = hpm_mcan_configure,
  365. .control = hpm_mcan_control,
  366. .sendmsg = hpm_mcan_sendmsg,
  367. .recvmsg = hpm_mcan_recvmsg,
  368. };
  369. static void hpm_mcan_isr(hpm_can_t *hpm_can)
  370. {
  371. uint8_t error_flags = mcan_get_last_error_code(hpm_can->can_base);
  372. uint32_t flags = mcan_get_interrupt_flags(hpm_can->can_base);
  373. mcan_error_count_t err_cnt;
  374. /* Transmit completed */
  375. if ((flags & (MCAN_EVENT_TRANSMIT)) != 0U) {
  376. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_TX_DONE | (0UL << 8));
  377. }
  378. /* Data available in FIFO */
  379. if ((flags & MCAN_EVENT_RECEIVE) != 0)
  380. {
  381. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_RX_IND | (hpm_can->fifo_index << 8));
  382. }
  383. /* RX FIFO overflow */
  384. if ((flags & MCAN_INT_RXFIFO0_FULL) != 0U)
  385. {
  386. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_RXOF_IND | (hpm_can->fifo_index << 8));
  387. }
  388. if ((flags & MCAN_INT_RXFIFO1_FULL) != 0U)
  389. {
  390. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_RXOF_IND | (hpm_can->fifo_index << 8));
  391. }
  392. /* Error happened on CAN Bus */
  393. if (((flags & MCAN_EVENT_ERROR) != 0U) || (error_flags != 0U))
  394. {
  395. mcan_get_error_counter(hpm_can->can_base, &err_cnt);
  396. switch(error_flags)
  397. {
  398. case 3:
  399. hpm_can->can_dev.status.ackerrcnt++;
  400. break;
  401. case 4:
  402. hpm_can->can_dev.status.biterrcnt++;
  403. break;
  404. case 6:
  405. hpm_can->can_dev.status.crcerrcnt++;
  406. break;
  407. case 2:
  408. hpm_can->can_dev.status.formaterrcnt++;
  409. break;
  410. case 1:
  411. hpm_can->can_dev.status.bitpaderrcnt++;
  412. break;
  413. }
  414. hpm_can->can_dev.status.rcverrcnt = err_cnt.receive_error_count;
  415. hpm_can->can_dev.status.snderrcnt = err_cnt.transmit_error_count;
  416. hpm_can->can_dev.status.lasterrtype = mcan_get_last_error_code(hpm_can->can_base);
  417. hpm_can->can_dev.status.errcode = 0;
  418. if ((error_flags & MCAN_INT_WARNING_STATUS) != 0U)
  419. {
  420. hpm_can->can_dev.status.errcode |= ERRWARNING;
  421. }
  422. if ((error_flags & MCAN_INT_ERROR_PASSIVE) != 0U)
  423. {
  424. hpm_can->can_dev.status.errcode |= ERRPASSIVE;
  425. }
  426. if (mcan_is_in_busoff_state(hpm_can->can_base))
  427. {
  428. hpm_can->can_dev.status.errcode |= BUSOFF;
  429. }
  430. }
  431. mcan_clear_interrupt_flags(hpm_can->can_base, flags);
  432. }
  433. static rt_err_t hpm_mcan_configure(struct rt_can_device *can, struct can_configure *cfg)
  434. {
  435. RT_ASSERT(can);
  436. RT_ASSERT(cfg);
  437. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  438. RT_ASSERT(drv_can);
  439. #ifdef RT_CAN_USING_CANFD
  440. drv_can->can_config.enable_canfd = (cfg->enable_canfd != 0) ? true : false;
  441. if (cfg->use_bit_timing != 0U)
  442. {
  443. drv_can->can_config.use_lowlevel_timing_setting = true;
  444. drv_can->can_config.can_timing.prescaler = cfg->can_timing.prescaler;
  445. drv_can->can_config.can_timing.num_seg1 = cfg->can_timing.num_seg1;
  446. drv_can->can_config.can_timing.num_seg2 = cfg->can_timing.num_seg2;
  447. drv_can->can_config.can_timing.num_sjw = cfg->can_timing.num_sjw;
  448. drv_can->can_config.canfd_timing.prescaler = cfg->canfd_timing.prescaler;
  449. drv_can->can_config.canfd_timing.num_seg1 = cfg->canfd_timing.num_seg1;
  450. drv_can->can_config.canfd_timing.num_seg2 = cfg->canfd_timing.num_seg2;
  451. drv_can->can_config.canfd_timing.num_sjw = cfg->canfd_timing.num_sjw;
  452. }
  453. else
  454. #endif
  455. {
  456. drv_can->can_config.use_lowlevel_timing_setting = false;
  457. drv_can->can_config.baudrate = cfg->baud_rate;
  458. #ifdef RT_CAN_USING_CANFD
  459. drv_can->can_config.baudrate_fd = cfg->baud_rate_fd;
  460. #endif
  461. }
  462. switch (cfg->mode)
  463. {
  464. case RT_CAN_MODE_NORMAL:
  465. drv_can->can_config.mode = mcan_mode_normal;
  466. break;
  467. case RT_CAN_MODE_LISTEN:
  468. drv_can->can_config.mode = mcan_mode_listen_only;
  469. break;
  470. case RT_CAN_MODE_LOOPBACK:
  471. drv_can->can_config.mode = mcan_mode_loopback_internal;
  472. break;
  473. default:
  474. return -RT_ERROR;
  475. break;
  476. }
  477. init_can_pins(drv_can->can_base);
  478. clock_add_to_group(drv_can->clk_name, BOARD_RUNNING_CORE & 0x1);
  479. uint32_t can_clk = clock_get_frequency(drv_can->clk_name);
  480. drv_can->can_config.all_filters_config.std_id_filter_list.filter_elem_list = &drv_can->std_can_filters[0];
  481. drv_can->can_config.all_filters_config.std_id_filter_list.mcan_filter_elem_count = drv_can->std_filter_num;
  482. drv_can->can_config.all_filters_config.ext_id_filter_list.filter_elem_list = &drv_can->ext_can_filters[0];
  483. drv_can->can_config.all_filters_config.ext_id_filter_list.mcan_filter_elem_count = drv_can->ext_filter_num;
  484. drv_can->can_config.all_filters_config.ext_id_mask = (1UL << 30) - 1UL;
  485. drv_can->can_config.txbuf_trans_interrupt_mask = ~0UL;
  486. hpm_stat_t status = mcan_init(drv_can->can_base, &drv_can->can_config, can_clk);
  487. if (status != status_success)
  488. {
  489. return -RT_ERROR;
  490. }
  491. return RT_EOK;
  492. }
  493. static rt_err_t hpm_mcan_control(struct rt_can_device *can, int cmd, void *arg)
  494. {
  495. RT_ASSERT(can);
  496. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  497. RT_ASSERT(drv_can);
  498. uint32_t arg_val;
  499. rt_err_t err = RT_EOK;
  500. uint32_t temp;
  501. uint32_t irq_txrx_mask;
  502. switch (cmd)
  503. {
  504. case RT_DEVICE_CTRL_CLR_INT:
  505. arg_val = (uint32_t) arg;
  506. intc_m_disable_irq(drv_can->irq_num);
  507. if (arg_val == RT_DEVICE_FLAG_INT_RX)
  508. {
  509. irq_txrx_mask = MCAN_EVENT_RECEIVE;
  510. drv_can->irq_txrx_err_enable_mask &= ~irq_txrx_mask;
  511. drv_can->can_config.interrupt_mask &= ~irq_txrx_mask;
  512. mcan_disable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  513. }
  514. else if (arg_val == RT_DEVICE_FLAG_INT_TX)
  515. {
  516. irq_txrx_mask = MCAN_EVENT_TRANSMIT;
  517. drv_can->irq_txrx_err_enable_mask &= ~irq_txrx_mask;
  518. drv_can->can_config.interrupt_mask &= ~irq_txrx_mask;
  519. mcan_disable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  520. mcan_disable_txbuf_interrupt(drv_can->can_base, ~0UL);
  521. } else if (arg_val == RT_DEVICE_CAN_INT_ERR) {
  522. irq_txrx_mask = MCAN_EVENT_ERROR;
  523. drv_can->irq_txrx_err_enable_mask &= ~irq_txrx_mask;
  524. drv_can->can_config.interrupt_mask &= ~irq_txrx_mask;
  525. mcan_disable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  526. } else {
  527. err = -RT_ERROR;
  528. }
  529. break;
  530. case RT_DEVICE_CTRL_SET_INT:
  531. arg_val = (uint32_t) arg;
  532. if (arg_val == RT_DEVICE_FLAG_INT_RX)
  533. {
  534. irq_txrx_mask = MCAN_EVENT_RECEIVE;
  535. drv_can->irq_txrx_err_enable_mask |= irq_txrx_mask;
  536. drv_can->can_config.interrupt_mask |= irq_txrx_mask;
  537. mcan_enable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  538. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  539. }
  540. else if (arg_val == RT_DEVICE_FLAG_INT_TX)
  541. {
  542. irq_txrx_mask = MCAN_EVENT_TRANSMIT;
  543. drv_can->irq_txrx_err_enable_mask |= irq_txrx_mask;
  544. drv_can->can_config.interrupt_mask |= irq_txrx_mask;
  545. mcan_enable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  546. mcan_enable_txbuf_interrupt(drv_can->can_base, ~0UL);
  547. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  548. }
  549. else if (arg_val == RT_DEVICE_CAN_INT_ERR)
  550. {
  551. irq_txrx_mask = MCAN_EVENT_ERROR;
  552. drv_can->irq_txrx_err_enable_mask |= irq_txrx_mask;
  553. drv_can->can_config.interrupt_mask |= irq_txrx_mask;
  554. mcan_enable_interrupts(drv_can->can_base, drv_can->irq_txrx_err_enable_mask);
  555. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  556. }
  557. else
  558. {
  559. err = -RT_ERROR;
  560. }
  561. break;
  562. case RT_CAN_CMD_SET_FILTER:
  563. {
  564. /* Convert the RT-Thread Filter format to the filter format supported by HPM CAN */
  565. struct rt_can_filter_config *filter = (struct rt_can_filter_config*)arg;
  566. drv_can->std_filter_num = 0;
  567. drv_can->ext_filter_num = 0;
  568. if (filter != NULL)
  569. {
  570. for (uint32_t i = 0; i < filter->count; i++)
  571. {
  572. if (filter->items[i].ide != 0)
  573. {
  574. drv_can->ext_can_filters[drv_can->ext_filter_num].filter_type = MCAN_FILTER_TYPE_CLASSIC_FILTER;
  575. drv_can->ext_can_filters[drv_can->ext_filter_num].filter_config = MCAN_FILTER_ELEM_CFG_STORE_IN_RX_FIFO0_IF_MATCH;
  576. drv_can->ext_can_filters[drv_can->ext_filter_num].can_id_type = MCAN_CAN_ID_TYPE_EXTENDED;
  577. drv_can->ext_can_filters[drv_can->ext_filter_num].filter_id = filter->items[i].id;
  578. drv_can->ext_can_filters[drv_can->ext_filter_num].filter_mask = filter->items[i].mask;
  579. drv_can->ext_filter_num++;
  580. RT_ASSERT(drv_can->ext_filter_num <= CAN_EXT_FILTER_NUM_MAX);
  581. }
  582. else
  583. {
  584. drv_can->std_can_filters[drv_can->std_filter_num].filter_type = MCAN_FILTER_TYPE_CLASSIC_FILTER;
  585. drv_can->std_can_filters[drv_can->std_filter_num].filter_config = MCAN_FILTER_ELEM_CFG_STORE_IN_RX_FIFO0_IF_MATCH;
  586. drv_can->std_can_filters[drv_can->std_filter_num].can_id_type = MCAN_CAN_ID_TYPE_STANDARD;
  587. drv_can->std_can_filters[drv_can->std_filter_num].filter_id = filter->items[i].id;
  588. drv_can->std_can_filters[drv_can->std_filter_num].filter_mask = filter->items[i].mask;
  589. drv_can->std_filter_num++;
  590. RT_ASSERT(drv_can->std_filter_num <= CAN_STD_FILTER_NUM_MAX);
  591. }
  592. if (filter->items[i].rtr != 0)
  593. {
  594. if (drv_can->ext_filter_num)
  595. {
  596. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_ext_frame = false;
  597. }
  598. else
  599. {
  600. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_ext_frame = true;
  601. }
  602. if (drv_can->std_filter_num)
  603. {
  604. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_std_frame = false;
  605. }
  606. else
  607. {
  608. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_std_frame = true;
  609. }
  610. }
  611. }
  612. if (filter->actived != 0U)
  613. {
  614. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_std_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_REJECT;
  615. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_ext_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_REJECT;
  616. }
  617. else
  618. {
  619. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_std_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_IN_RXFIFO0;
  620. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_ext_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_IN_RXFIFO0;
  621. }
  622. }
  623. else
  624. {
  625. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_ext_frame = false;
  626. drv_can->can_config.all_filters_config.global_filter_config.reject_remote_std_frame = false;
  627. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_std_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_IN_RXFIFO0;
  628. drv_can->can_config.all_filters_config.global_filter_config.accept_non_matching_ext_frame_option = MCAN_ACCEPT_NON_MATCHING_FRAME_OPTION_IN_RXFIFO0;
  629. drv_can->can_config.all_filters_config.ext_id_mask = 0x1FFFFFFFUL;
  630. drv_can->can_config.all_filters_config.std_id_filter_list.filter_elem_list = &k_default_std_id_filter;
  631. drv_can->can_config.all_filters_config.std_id_filter_list.mcan_filter_elem_count = 1;
  632. drv_can->can_config.all_filters_config.ext_id_filter_list.filter_elem_list = &k_default_ext_id_filter;
  633. drv_can->can_config.all_filters_config.ext_id_filter_list.mcan_filter_elem_count = 1;
  634. }
  635. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  636. #ifdef RT_CAN_USING_HDR
  637. if (filter == RT_NULL) {
  638. /*if use RT_CAN_USING_HDR, but if want to receive everything without filtering, use default filter, need to return NO-RT-OK status*/
  639. err = -RT_ETRAP;
  640. }
  641. #endif
  642. }
  643. break;
  644. case RT_CAN_CMD_SET_MODE:
  645. arg_val = (uint32_t) arg;
  646. if ((arg_val != RT_CAN_MODE_NORMAL) && (arg_val != RT_CAN_MODE_LISTEN) && (arg_val != RT_CAN_MODE_LOOPBACK))
  647. {
  648. err = -RT_ERROR;
  649. break;
  650. }
  651. if (arg_val != drv_can->can_dev.config.mode)
  652. {
  653. drv_can->can_dev.config.mode = arg_val;
  654. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  655. }
  656. break;
  657. case RT_CAN_CMD_SET_BAUD:
  658. arg_val = (uint32_t) arg;
  659. if (arg_val != drv_can->can_dev.config.baud_rate)
  660. {
  661. drv_can->can_dev.config.baud_rate = arg_val;
  662. }
  663. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  664. break;
  665. #ifdef RT_CAN_USING_CANFD
  666. case RT_CAN_CMD_SET_CANFD:
  667. arg_val = (uint32_t) arg;
  668. if (arg_val != drv_can->can_dev.config.enable_canfd)
  669. {
  670. drv_can->can_dev.config.enable_canfd = arg_val;
  671. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  672. }
  673. break;
  674. case RT_CAN_CMD_SET_BAUD_FD:
  675. arg_val = (uint32_t) arg;
  676. if (arg_val != drv_can->can_dev.config.baud_rate_fd)
  677. {
  678. drv_can->can_dev.config.baud_rate_fd = arg_val;
  679. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  680. }
  681. break;
  682. case RT_CAN_CMD_SET_BITTIMING:
  683. {
  684. struct rt_can_bit_timing_config *timing_configs = (struct rt_can_bit_timing_config*)arg;
  685. if ((timing_configs == RT_NULL) || (timing_configs->count < 1) || (timing_configs->count > 2))
  686. {
  687. return -RT_ERROR;
  688. }
  689. if (timing_configs->count != 0U)
  690. {
  691. drv_can->can_dev.config.can_timing = timing_configs->items[0];
  692. }
  693. if (timing_configs->count == 2)
  694. {
  695. drv_can->can_dev.config.canfd_timing = timing_configs->items[1];
  696. }
  697. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  698. }
  699. break;
  700. #endif
  701. case RT_CAN_CMD_SET_PRIV:
  702. arg_val = (uint32_t)arg;
  703. if ((arg_val != RT_CAN_MODE_PRIV) && (arg_val != RT_CAN_MODE_NOPRIV))
  704. {
  705. return -RT_ERROR;
  706. }
  707. if (arg_val != drv_can->can_dev.config.privmode)
  708. {
  709. drv_can->can_dev.config.privmode = arg_val;
  710. err = hpm_mcan_configure(can, &drv_can->can_dev.config);
  711. }
  712. break;
  713. case RT_CAN_CMD_GET_STATUS:
  714. mcan_error_count_t err_cnt;
  715. mcan_get_error_counter(drv_can->can_base, &err_cnt);
  716. drv_can->can_dev.status.rcverrcnt = err_cnt.receive_error_count;
  717. drv_can->can_dev.status.snderrcnt = err_cnt.transmit_error_count;
  718. drv_can->can_dev.status.lasterrtype = mcan_get_last_error_code(drv_can->can_base);
  719. temp = mcan_get_interrupt_flags(drv_can->can_base);
  720. drv_can->can_dev.status.errcode = 0;
  721. if ((temp & MCAN_INT_WARNING_STATUS) != 0U)
  722. {
  723. drv_can->can_dev.status.errcode |= ERRWARNING;
  724. }
  725. if ((temp & MCAN_INT_ERROR_PASSIVE) != 0U)
  726. {
  727. drv_can->can_dev.status.errcode |= ERRPASSIVE;
  728. }
  729. if (mcan_is_in_busoff_state(drv_can->can_base))
  730. {
  731. drv_can->can_dev.status.errcode |= BUSOFF;
  732. }
  733. rt_memcpy(arg, &drv_can->can_dev.status, sizeof(drv_can->can_dev.status));
  734. break;
  735. }
  736. return err;
  737. }
  738. static int hpm_mcan_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  739. {
  740. RT_ASSERT(can);
  741. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  742. RT_ASSERT(drv_can);
  743. struct rt_can_msg *can_msg = (struct rt_can_msg *) buf;
  744. mcan_tx_frame_t tx_frame = {0};
  745. memset(&tx_frame, 0, sizeof(tx_frame));
  746. if (can_msg->ide == RT_CAN_STDID)
  747. {
  748. tx_frame.use_ext_id = 0;
  749. tx_frame.std_id = can_msg->id;
  750. }
  751. else
  752. {
  753. tx_frame.use_ext_id = 1;
  754. tx_frame.ext_id = can_msg->id;
  755. }
  756. if (can_msg->rtr == RT_CAN_DTR)
  757. {
  758. tx_frame.rtr = false;
  759. }
  760. else
  761. {
  762. tx_frame.rtr = true;
  763. }
  764. #ifdef RT_CAN_USING_CANFD
  765. tx_frame.bitrate_switch = can_msg->brs;
  766. if (can_msg->fd_frame != 0)
  767. {
  768. tx_frame.canfd_frame = 1;
  769. RT_ASSERT(can_msg->len <= 15);
  770. }
  771. else
  772. #endif
  773. {
  774. RT_ASSERT(can_msg->len <= 8);
  775. }
  776. uint32_t msg_len = mcan_get_message_size_from_dlc(can_msg->len);
  777. for (uint32_t i = 0; i < msg_len; i++)
  778. {
  779. tx_frame.data_8[i] = can_msg->data[i];
  780. }
  781. tx_frame.dlc = can_msg->len;
  782. uint32_t delay_cnt = 0;
  783. while (mcan_is_txfifo_full(drv_can->can_base))
  784. {
  785. rt_thread_mdelay(1);
  786. delay_cnt++;
  787. if (delay_cnt >= CAN_SEND_WAIT_MS_MAX)
  788. {
  789. return -RT_ETIMEOUT;
  790. }
  791. }
  792. hpm_stat_t status = mcan_transmit_via_txbuf_nonblocking(drv_can->can_base, 0, &tx_frame);
  793. if (status != status_success)
  794. {
  795. return -RT_EFULL;
  796. }
  797. return RT_EOK;
  798. }
  799. static int hpm_mcan_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
  800. {
  801. RT_ASSERT(can);
  802. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  803. RT_ASSERT(drv_can);
  804. rt_can_msg_t can_msg = (rt_can_msg_t)buf;
  805. mcan_rx_message_t rx_buf;
  806. hpm_stat_t status = mcan_read_rxfifo(drv_can->can_base, 0, &rx_buf);
  807. if (status == status_success)
  808. {
  809. if (rx_buf.use_ext_id)
  810. {
  811. can_msg->ide = RT_CAN_EXTID;
  812. can_msg->id = rx_buf.ext_id;
  813. }
  814. else
  815. {
  816. can_msg->ide = RT_CAN_STDID;
  817. can_msg->id = rx_buf.std_id;
  818. }
  819. if (rx_buf.rtr != 0) {
  820. can_msg->rtr = RT_CAN_RTR;
  821. }
  822. else {
  823. can_msg->rtr = RT_CAN_DTR;
  824. }
  825. #ifdef RT_CAN_USING_CANFD
  826. can_msg->fd_frame = rx_buf.canfd_frame;
  827. can_msg->brs = rx_buf.bitrate_switch;
  828. #endif
  829. can_msg->len = rx_buf.dlc;
  830. uint32_t msg_len = mcan_get_message_size_from_dlc(can_msg->len);
  831. for(uint32_t i = 0; i < msg_len; i++) {
  832. can_msg->data[i] = rx_buf.data_8[i];
  833. }
  834. #ifdef RT_CAN_USING_HDR
  835. /* Hardware filter messages are valid */
  836. can_msg->hdr_index = boxno;
  837. can->hdr[can_msg->hdr_index].connected = 1;
  838. #endif
  839. }
  840. else
  841. {
  842. return -RT_EEMPTY;
  843. }
  844. return RT_EOK;
  845. }
  846. int rt_hw_mcan_init(void)
  847. {
  848. struct can_configure config = CANDEFAULTCONFIG;
  849. config.privmode = RT_CAN_MODE_NOPRIV;
  850. config.sndboxnumber = CAN_SENDBOX_NUM;
  851. config.ticks = 50;
  852. #ifdef RT_CAN_USING_HDR
  853. config.maxhdr = 32;
  854. #endif
  855. for (uint32_t i = 0; i < ARRAY_SIZE(hpm_cans); i++)
  856. {
  857. hpm_cans[i]->can_dev.config = config;
  858. hpm_cans[i]->ext_filter_num = 0;
  859. hpm_cans[i]->std_filter_num = 0;
  860. #if defined(MCAN_SOC_MSG_BUF_IN_AHB_RAM) && (MCAN_SOC_MSG_BUF_IN_AHB_RAM == 1)
  861. mcan_msg_buf_attr_t attr = { hpm_cans[i]->ram_base, hpm_cans[i]->ram_size };
  862. hpm_stat_t status = mcan_set_msg_buf_attr(hpm_cans[i]->can_base, &attr);
  863. #endif
  864. mcan_get_default_config(hpm_cans[i]->can_base, &hpm_cans[i]->can_config);
  865. rt_hw_can_register(&hpm_cans[i]->can_dev, hpm_cans[i]->name, &hpm_can_ops, hpm_cans[i]);
  866. }
  867. return RT_EOK;
  868. }
  869. INIT_BOARD_EXPORT(rt_hw_mcan_init);
  870. #endif