drv_mcan.c 28 KB

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