drv_mcan.c 25 KB

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