drv_can.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. /*
  2. * Copyright (c) 2021-2025 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-05-08 HPMicro the first version
  9. * 2023-05-08 HPMicro Adapt RT-Thread v5.0.0
  10. * 2025/03-25 HPMicro Add configurable interrupt priority support
  11. */
  12. #include <rtthread.h>
  13. #include <rtdevice.h>
  14. #include <rthw.h>
  15. #include "board.h"
  16. #include "hpm_can_drv.h"
  17. #include "hpm_clock_drv.h"
  18. #define CAN_SEND_WAIT_MS_MAX (1000U) /* CAN maximum wait time for transmission */
  19. #define CAN_SENDBOX_NUM (1U) /* CAN Hardware Transmission buffer number */
  20. #define CAN_FILTER_NUM_MAX (16U) /* CAN Hardware Filter number */
  21. #ifdef RT_USING_CAN
  22. typedef struct _hpm_can_struct
  23. {
  24. CAN_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. can_config_t can_config; /**< CAN configuration for IP */
  31. struct rt_can_device can_dev; /**< CAN device configuration in rt-thread */
  32. uint32_t filter_num; /**< Filter number */
  33. can_filter_config_t filter_list[CAN_FILTER_NUM_MAX]; /**< Filter list */
  34. } hpm_can_t;
  35. /**
  36. * @brief Configure CAN controller
  37. * @param [in/out] can CAN device pointer
  38. * @param [in] cfg CAN configuration pointer
  39. * @retval RT_EOK for valid configuration
  40. * @retval -RT_ERROR for invalid configuration
  41. */
  42. static rt_err_t hpm_can_configure(struct rt_can_device *can, struct can_configure *cfg);
  43. /**
  44. * @brief Control/Get CAN state
  45. * including:interrupt, mode, priority, baudrate, filter, status
  46. * @param [in/out] can CAN device pointer
  47. * @param [in] cmd Control command
  48. * @param [in/out] arg Argument pointer
  49. * @retval RT_EOK for valid control command and arg
  50. * @retval -RT_ERROR for invalid control command or arg
  51. */
  52. static rt_err_t hpm_can_control(struct rt_can_device *can, int cmd, void *arg);
  53. /**
  54. * @brief Send out CAN message
  55. * @param [in] can CAN device pointer
  56. * @param [in] buf CAN message buffer
  57. * @param [in] boxno Mailbox number, it is not used in this porting
  58. * @retval RT_EOK No error
  59. * @retval -RT_ETIMEOUT timeout happened
  60. * @retval -RT_EFULL Transmission buffer is full
  61. */
  62. static int hpm_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno);
  63. /**
  64. * @brief Receive message from CAN
  65. * @param [in] can CAN device pointer
  66. * @param [out] buf CAN receive buffer
  67. * @param [in] boxno Mailbox Number, it is not used in this porting
  68. * @retval RT_EOK no error
  69. * @retval -RT_ERROR Error happened during reading receive FIFO
  70. * @retval -RT_EMPTY no data in receive FIFO
  71. */
  72. static int hpm_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
  73. /**
  74. * @brief Common Interrupt Service routine
  75. * @param [in] hpm_can HPM CAN pointer
  76. */
  77. static void hpm_can_isr(hpm_can_t *hpm_can);
  78. /**
  79. * @brief Decode data bytes from DLC
  80. * @param [in] dlc Data Length Code
  81. * @return decoded data bytes
  82. */
  83. static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc);
  84. #if defined(HPM_CAN0_BASE) && defined(BSP_USING_CAN0)
  85. static hpm_can_t dev_can0 =
  86. {
  87. .can_base = HPM_CAN0,
  88. .name = "can0",
  89. .irq_num = IRQn_CAN0,
  90. .fifo_index = 0,
  91. .clk_name = clock_can0,
  92. #if defined(BSP_CAN0_IRQ_PRIORITY)
  93. .irq_priority = BSP_CAN0_IRQ_PRIORITY,
  94. #else
  95. .irq_priority = 1,
  96. #endif
  97. };
  98. SDK_DECLARE_EXT_ISR_M(IRQn_CAN0, can0_isr);
  99. void can0_isr(void)
  100. {
  101. hpm_can_isr(&dev_can0);
  102. }
  103. #endif
  104. #if defined(HPM_CAN1_BASE) && defined(BSP_USING_CAN1)
  105. static hpm_can_t dev_can1 =
  106. {
  107. .can_base = HPM_CAN1,
  108. .name = "can1",
  109. .irq_num = IRQn_CAN1,
  110. .fifo_index = 1,
  111. .clk_name = clock_can1,
  112. #if defined(BSP_CAN1_IRQ_PRIORITY)
  113. .irq_priority = BSP_CAN1_IRQ_PRIORITY,
  114. #else
  115. .irq_priority = 1,
  116. #endif
  117. };
  118. SDK_DECLARE_EXT_ISR_M(IRQn_CAN1, can1_isr);
  119. void can1_isr(void)
  120. {
  121. hpm_can_isr(&dev_can1);
  122. }
  123. #endif
  124. #if defined(HPM_CAN2_BASE) && defined(BSP_USING_CAN2)
  125. static hpm_can_t dev_can2 =
  126. {
  127. .can_base = HPM_CAN2,
  128. .name = "can2",
  129. .irq_num = IRQn_CAN2,
  130. .fifo_index = 2,
  131. .clk_name = clock_can2,
  132. #if defined(BSP_CAN2_IRQ_PRIORITY)
  133. .irq_priority = BSP_CAN2_IRQ_PRIORITY,
  134. #else
  135. .irq_priority = 1,
  136. #endif
  137. };
  138. SDK_DECLARE_EXT_ISR_M(IRQn_CAN2, can2_isr);
  139. void can2_isr(void)
  140. {
  141. hpm_can_isr(&dev_can2);
  142. }
  143. #endif
  144. #if defined(HPM_CAN3_BASE) && defined(BSP_USING_CAN3)
  145. static hpm_can_t dev_can3 =
  146. {
  147. .can_base = HPM_CAN3,
  148. .name = "can3",
  149. .irq_num = IRQn_CAN3,
  150. .fifo_index = 3,
  151. .clk_name = clock_can3,
  152. #if defined(BSP_CAN3_IRQ_PRIORITY)
  153. .irq_priority = BSP_CAN3_IRQ_PRIORITY,
  154. #else
  155. .irq_priority = 1,
  156. #endif
  157. };
  158. SDK_DECLARE_EXT_ISR_M(IRQn_CAN3, can3_isr);
  159. void can3_isr(void)
  160. {
  161. hpm_can_isr(&dev_can3);
  162. }
  163. #endif
  164. static hpm_can_t *hpm_cans[] = {
  165. #if defined(HPM_CAN0_BASE) && defined(BSP_USING_CAN0)
  166. &dev_can0,
  167. #endif
  168. #if defined(HPM_CAN1_BASE) && defined(BSP_USING_CAN1)
  169. &dev_can1,
  170. #endif
  171. #if defined(HPM_CAN2_BASE) && defined(BSP_USING_CAN2)
  172. &dev_can2,
  173. #endif
  174. #if defined(HPM_CAN3_BASE) && defined(BSP_USING_CAN3)
  175. &dev_can3,
  176. #endif
  177. };
  178. static const struct rt_can_ops hpm_can_ops = {
  179. .configure = hpm_can_configure,
  180. .control = hpm_can_control,
  181. .sendmsg = hpm_can_sendmsg,
  182. .recvmsg = hpm_can_recvmsg,
  183. };
  184. static void hpm_can_isr(hpm_can_t *hpm_can)
  185. {
  186. uint8_t tx_rx_flags = can_get_tx_rx_flags(hpm_can->can_base);
  187. uint8_t error_flags = can_get_error_interrupt_flags(hpm_can->can_base);
  188. /* High-priority message transmission done */
  189. if ((tx_rx_flags & CAN_EVENT_TX_PRIMARY_BUF) != 0U)
  190. {
  191. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_TX_DONE | (0UL << 8));
  192. }
  193. /* Normal priority message transmission done */
  194. if ((tx_rx_flags & CAN_EVENT_TX_SECONDARY_BUF) != 0U)
  195. {
  196. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_TX_DONE | (0UL << 8));
  197. }
  198. /* Data available in FIFO */
  199. if ((tx_rx_flags & CAN_EVENT_RECEIVE) == CAN_EVENT_RECEIVE)
  200. {
  201. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_RX_IND | (hpm_can->fifo_index << 8));
  202. }
  203. /* RX FIFO overflow */
  204. if ((tx_rx_flags & CAN_EVENT_RX_BUF_OVERRUN) != 0U)
  205. {
  206. rt_hw_can_isr(&hpm_can->can_dev, RT_CAN_EVENT_RXOF_IND | (hpm_can->fifo_index << 8));
  207. }
  208. /* Error happened on CAN Bus */
  209. if (((tx_rx_flags & CAN_EVENT_ERROR) != 0U) || (error_flags != 0U))
  210. {
  211. uint8_t err_kind = can_get_last_error_kind(hpm_can->can_base);
  212. switch(err_kind)
  213. {
  214. case CAN_KIND_OF_ERROR_ACK_ERROR:
  215. hpm_can->can_dev.status.ackerrcnt++;
  216. break;
  217. case CAN_KIND_OF_ERROR_BIT_ERROR:
  218. hpm_can->can_dev.status.biterrcnt++;
  219. break;
  220. case CAN_KIND_OF_ERROR_CRC_ERROR:
  221. hpm_can->can_dev.status.crcerrcnt++;
  222. break;
  223. case CAN_KIND_OF_ERROR_FORM_ERROR:
  224. hpm_can->can_dev.status.formaterrcnt++;
  225. break;
  226. case CAN_KIND_OF_ERROR_STUFF_ERROR:
  227. hpm_can->can_dev.status.bitpaderrcnt++;
  228. break;
  229. }
  230. hpm_can->can_dev.status.rcverrcnt = can_get_receive_error_count(hpm_can->can_base);
  231. hpm_can->can_dev.status.snderrcnt = can_get_transmit_error_count(hpm_can->can_base);
  232. hpm_can->can_dev.status.lasterrtype = can_get_last_error_kind(hpm_can->can_base);
  233. hpm_can->can_dev.status.errcode = 0;
  234. if ((error_flags & CAN_ERROR_WARNING_LIMIT_FLAG) != 0U)
  235. {
  236. hpm_can->can_dev.status.errcode |= ERRWARNING;
  237. }
  238. if ((error_flags & CAN_ERROR_PASSIVE_INT_FLAG) != 0U)
  239. {
  240. hpm_can->can_dev.status.errcode |= ERRPASSIVE;
  241. }
  242. if (can_is_in_bus_off_mode(hpm_can->can_base))
  243. {
  244. hpm_can->can_dev.status.errcode |= BUSOFF;
  245. }
  246. }
  247. can_clear_tx_rx_flags(hpm_can->can_base, tx_rx_flags);
  248. can_clear_error_interrupt_flags(hpm_can->can_base, error_flags);
  249. }
  250. static rt_err_t hpm_can_configure(struct rt_can_device *can, struct can_configure *cfg)
  251. {
  252. RT_ASSERT(can);
  253. RT_ASSERT(cfg);
  254. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  255. RT_ASSERT(drv_can);
  256. #ifdef RT_CAN_USING_CANFD
  257. drv_can->can_config.enable_canfd = (cfg->enable_canfd != 0) ? true : false;
  258. if (cfg->use_bit_timing != 0U)
  259. {
  260. drv_can->can_config.use_lowlevel_timing_setting = true;
  261. drv_can->can_config.can_timing.prescaler = cfg->can_timing.prescaler;
  262. drv_can->can_config.can_timing.num_seg1 = cfg->can_timing.num_seg1;
  263. drv_can->can_config.can_timing.num_seg2 = cfg->can_timing.num_seg2;
  264. drv_can->can_config.can_timing.num_sjw = cfg->can_timing.num_sjw;
  265. drv_can->can_config.canfd_timing.prescaler = cfg->canfd_timing.prescaler;
  266. drv_can->can_config.canfd_timing.num_seg1 = cfg->canfd_timing.num_seg1;
  267. drv_can->can_config.canfd_timing.num_seg2 = cfg->canfd_timing.num_seg2;
  268. drv_can->can_config.canfd_timing.num_sjw = cfg->canfd_timing.num_sjw;
  269. }
  270. else
  271. #endif
  272. {
  273. drv_can->can_config.use_lowlevel_timing_setting = false;
  274. drv_can->can_config.baudrate = cfg->baud_rate;
  275. #ifdef RT_CAN_USING_CANFD
  276. drv_can->can_config.baudrate_fd = cfg->baud_rate_fd;
  277. #endif
  278. }
  279. switch (cfg->mode)
  280. {
  281. case RT_CAN_MODE_NORMAL:
  282. drv_can->can_config.mode = can_mode_normal;
  283. break;
  284. case RT_CAN_MODE_LISTEN:
  285. drv_can->can_config.mode = can_mode_listen_only;
  286. break;
  287. case RT_CAN_MODE_LOOPBACK:
  288. drv_can->can_config.mode = can_mode_loopback_internal;
  289. break;
  290. default:
  291. return -RT_ERROR;
  292. break;
  293. }
  294. drv_can->can_config.enable_tx_buffer_priority_mode = (cfg->privmode != 0U) ? true : false;
  295. init_can_pins(drv_can->can_base);
  296. clock_add_to_group(drv_can->clk_name, BOARD_RUNNING_CORE & 0x1);
  297. uint32_t can_clk = clock_get_frequency(drv_can->clk_name);
  298. drv_can->can_config.filter_list_num = drv_can->filter_num;
  299. drv_can->can_config.filter_list = &drv_can->filter_list[0];
  300. hpm_stat_t status = can_init(drv_can->can_base, &drv_can->can_config, can_clk);
  301. if (status != status_success)
  302. {
  303. return -RT_ERROR;
  304. }
  305. return RT_EOK;
  306. }
  307. static rt_err_t hpm_can_control(struct rt_can_device *can, int cmd, void *arg)
  308. {
  309. RT_ASSERT(can);
  310. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  311. RT_ASSERT(drv_can);
  312. uint32_t arg_val;
  313. rt_err_t err = RT_EOK;
  314. uint32_t temp;
  315. switch (cmd)
  316. {
  317. case RT_DEVICE_CTRL_CLR_INT:
  318. arg_val = (uint32_t) arg;
  319. intc_m_disable_irq(drv_can->irq_num);
  320. if (arg_val == RT_DEVICE_FLAG_INT_RX)
  321. {
  322. uint8_t irq_txrx_mask = CAN_EVENT_RECEIVE | CAN_EVENT_RX_BUF_ALMOST_FULL | CAN_EVENT_RX_BUF_FULL | CAN_EVENT_RX_BUF_OVERRUN;
  323. drv_can->can_config.irq_txrx_enable_mask &= (uint8_t)~irq_txrx_mask;
  324. can_disable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  325. }
  326. else if (arg_val == RT_DEVICE_FLAG_INT_TX)
  327. {
  328. uint8_t irq_txrx_mask = CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF;
  329. drv_can->can_config.irq_txrx_enable_mask &= (uint8_t)~irq_txrx_mask;
  330. can_disable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  331. }
  332. else if (arg_val == RT_DEVICE_CAN_INT_ERR)
  333. {
  334. uint8_t irq_txrx_mask = CAN_EVENT_ERROR;
  335. uint8_t irq_error_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
  336. drv_can->can_config.irq_txrx_enable_mask &= (uint8_t)~irq_txrx_mask;
  337. drv_can->can_config.irq_error_enable_mask &= (uint8_t)~irq_error_mask;
  338. can_disable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  339. can_disable_error_irq(drv_can->can_base, irq_error_mask);
  340. }
  341. else
  342. {
  343. err = -RT_ERROR;
  344. }
  345. break;
  346. case RT_DEVICE_CTRL_SET_INT:
  347. arg_val = (uint32_t) arg;
  348. if (arg_val == RT_DEVICE_FLAG_INT_RX)
  349. {
  350. uint8_t irq_txrx_mask = CAN_EVENT_RECEIVE | CAN_EVENT_RX_BUF_ALMOST_FULL | CAN_EVENT_RX_BUF_FULL | CAN_EVENT_RX_BUF_OVERRUN;
  351. drv_can->can_config.irq_txrx_enable_mask |= irq_txrx_mask;
  352. can_enable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  353. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  354. }
  355. else if (arg_val == RT_DEVICE_FLAG_INT_TX)
  356. {
  357. uint8_t irq_txrx_mask = CAN_EVENT_TX_PRIMARY_BUF | CAN_EVENT_TX_SECONDARY_BUF;
  358. drv_can->can_config.irq_txrx_enable_mask |= irq_txrx_mask;
  359. can_enable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  360. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  361. }
  362. else if (arg_val == RT_DEVICE_CAN_INT_ERR)
  363. {
  364. uint8_t irq_txrx_mask = CAN_EVENT_ERROR;
  365. uint8_t irq_error_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
  366. drv_can->can_config.irq_txrx_enable_mask |= irq_txrx_mask;
  367. drv_can->can_config.irq_error_enable_mask |= irq_error_mask;
  368. can_enable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
  369. can_enable_error_irq(drv_can->can_base, irq_error_mask);
  370. intc_m_enable_irq_with_priority(drv_can->irq_num, drv_can->irq_priority);
  371. }
  372. else
  373. {
  374. err = -RT_ERROR;
  375. }
  376. break;
  377. case RT_CAN_CMD_SET_FILTER:
  378. {
  379. /* Convert the RT-Thread Filter format to the filter format supported by HPM CAN */
  380. struct rt_can_filter_config *filter = (struct rt_can_filter_config*)arg;
  381. if (filter != NULL)
  382. {
  383. drv_can->filter_num = filter->count;
  384. RT_ASSERT(filter->count <= CAN_FILTER_NUM_MAX);
  385. for (uint32_t i=0; i<filter->count; i++)
  386. {
  387. drv_can->filter_list[i].index = i;
  388. drv_can->filter_list[i].enable = (filter->actived != 0U) ? true : false;
  389. drv_can->filter_list[i].code = filter->items[i].id;
  390. drv_can->filter_list[i].id_mode = (filter->items[i].ide != 0U) ? can_filter_id_mode_extended_frames : can_filter_id_mode_standard_frames;
  391. drv_can->filter_list[i].mask = (~filter->items[i].mask) & ~(7UL <<29);
  392. }
  393. }
  394. else
  395. {
  396. drv_can->filter_num = 0;
  397. }
  398. err = hpm_can_configure(can, &drv_can->can_dev.config);
  399. #ifdef RT_CAN_USING_HDR
  400. if (filter == RT_NULL) {
  401. /*if use RT_CAN_USING_HDR, but if want to receive everything without filtering, use default filter, need to return NO-RT-OK status*/
  402. err = -RT_ETRAP;
  403. }
  404. #endif
  405. }
  406. break;
  407. case RT_CAN_CMD_SET_MODE:
  408. arg_val = (uint32_t) arg;
  409. if ((arg_val != RT_CAN_MODE_NORMAL) && (arg_val != RT_CAN_MODE_LISTEN) && (arg_val != RT_CAN_MODE_LOOPBACK))
  410. {
  411. err = -RT_ERROR;
  412. break;
  413. }
  414. if (arg_val != drv_can->can_dev.config.mode)
  415. {
  416. drv_can->can_dev.config.mode = arg_val;
  417. err = hpm_can_configure(can, &drv_can->can_dev.config);
  418. }
  419. break;
  420. case RT_CAN_CMD_SET_BAUD:
  421. arg_val = (uint32_t) arg;
  422. if (arg_val != drv_can->can_dev.config.baud_rate)
  423. {
  424. drv_can->can_dev.config.baud_rate = arg_val;
  425. }
  426. err = hpm_can_configure(can, &drv_can->can_dev.config);
  427. break;
  428. #ifdef RT_CAN_USING_CANFD
  429. case RT_CAN_CMD_SET_CANFD:
  430. arg_val = (uint32_t) arg;
  431. if (arg_val != drv_can->can_dev.config.enable_canfd)
  432. {
  433. drv_can->can_dev.config.enable_canfd = arg_val;
  434. err = hpm_can_configure(can, &drv_can->can_dev.config);
  435. }
  436. break;
  437. case RT_CAN_CMD_SET_BAUD_FD:
  438. arg_val = (uint32_t) arg;
  439. if (arg_val != drv_can->can_dev.config.baud_rate_fd)
  440. {
  441. drv_can->can_dev.config.baud_rate_fd = arg_val;
  442. err = hpm_can_configure(can, &drv_can->can_dev.config);
  443. }
  444. break;
  445. case RT_CAN_CMD_SET_BITTIMING:
  446. {
  447. struct rt_can_bit_timing_config *timing_configs = (struct rt_can_bit_timing_config*)arg;
  448. if ((timing_configs == RT_NULL) || (timing_configs->count < 1) || (timing_configs->count > 2))
  449. {
  450. return -RT_ERROR;
  451. }
  452. if (timing_configs->count != 0U)
  453. {
  454. drv_can->can_dev.config.can_timing = timing_configs->items[0];
  455. }
  456. if (timing_configs->count == 2)
  457. {
  458. drv_can->can_dev.config.canfd_timing = timing_configs->items[1];
  459. }
  460. err = hpm_can_configure(can, &drv_can->can_dev.config);
  461. }
  462. break;
  463. #endif
  464. case RT_CAN_CMD_SET_PRIV:
  465. arg_val = (uint32_t)arg;
  466. if ((arg_val != RT_CAN_MODE_PRIV) && (arg_val != RT_CAN_MODE_NOPRIV))
  467. {
  468. return -RT_ERROR;
  469. }
  470. if (arg_val != drv_can->can_dev.config.privmode)
  471. {
  472. drv_can->can_dev.config.privmode = arg_val;
  473. err = hpm_can_configure(can, &drv_can->can_dev.config);
  474. }
  475. break;
  476. case RT_CAN_CMD_GET_STATUS:
  477. drv_can->can_dev.status.rcverrcnt = can_get_receive_error_count(drv_can->can_base);
  478. drv_can->can_dev.status.snderrcnt = can_get_transmit_error_count(drv_can->can_base);
  479. drv_can->can_dev.status.lasterrtype = can_get_last_error_kind(drv_can->can_base);
  480. temp = can_get_error_interrupt_flags(drv_can->can_base);
  481. drv_can->can_dev.status.errcode = 0;
  482. if ((temp & CAN_ERROR_WARNING_LIMIT_FLAG) != 0U)
  483. {
  484. drv_can->can_dev.status.errcode |= ERRWARNING;
  485. }
  486. if ((temp & CAN_ERROR_PASSIVE_INT_FLAG) != 0U)
  487. {
  488. drv_can->can_dev.status.errcode |= ERRPASSIVE;
  489. }
  490. if (can_is_in_bus_off_mode(drv_can->can_base))
  491. {
  492. drv_can->can_dev.status.errcode |= BUSOFF;
  493. }
  494. rt_memcpy(arg, &drv_can->can_dev.status, sizeof(drv_can->can_dev.status));
  495. break;
  496. }
  497. return err;
  498. }
  499. static int hpm_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  500. {
  501. RT_ASSERT(can);
  502. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  503. RT_ASSERT(drv_can);
  504. struct rt_can_msg *can_msg = (struct rt_can_msg *) buf;
  505. can_transmit_buf_t tx_buf = { 0 };
  506. tx_buf.id = can_msg->id;
  507. if (can_msg->ide == RT_CAN_STDID)
  508. {
  509. tx_buf.extend_id = false;
  510. }
  511. else
  512. {
  513. tx_buf.extend_id = true;
  514. }
  515. if (can_msg->rtr == RT_CAN_DTR)
  516. {
  517. tx_buf.remote_frame = false;
  518. }
  519. else
  520. {
  521. tx_buf.remote_frame = true;
  522. }
  523. #ifdef RT_CAN_USING_CANFD
  524. tx_buf.bitrate_switch = can_msg->brs;
  525. if (can_msg->fd_frame != 0)
  526. {
  527. tx_buf.canfd_frame = 1;
  528. RT_ASSERT(can_msg->len <= 15);
  529. }
  530. else
  531. #endif
  532. {
  533. RT_ASSERT(can_msg->len <= 8);
  534. }
  535. uint32_t msg_len = can_get_data_bytes_from_dlc(can_msg->len);
  536. for (uint32_t i = 0; i < msg_len; i++)
  537. {
  538. tx_buf.data[i] = can_msg->data[i];
  539. }
  540. tx_buf.dlc = can_msg->len;
  541. uint32_t delay_cnt = 0;
  542. if (can_msg->priv != 0U)
  543. {
  544. while (can_is_primary_transmit_buffer_full(drv_can->can_base))
  545. {
  546. rt_thread_mdelay(1);
  547. delay_cnt++;
  548. if (delay_cnt >= CAN_SEND_WAIT_MS_MAX)
  549. {
  550. return -RT_ETIMEOUT;
  551. }
  552. }
  553. hpm_stat_t status = can_send_message_nonblocking(drv_can->can_base, &tx_buf);
  554. if (status != status_success)
  555. {
  556. return -RT_EFULL;
  557. }
  558. }
  559. else
  560. {
  561. while (can_is_secondary_transmit_buffer_full(drv_can->can_base))
  562. {
  563. rt_thread_mdelay(1);
  564. delay_cnt++;
  565. if (delay_cnt >= CAN_SEND_WAIT_MS_MAX)
  566. {
  567. return -RT_ETIMEOUT;
  568. }
  569. }
  570. hpm_stat_t status = can_send_message_nonblocking(drv_can->can_base, &tx_buf);
  571. if (status != status_success)
  572. {
  573. return -RT_EFULL;
  574. }
  575. }
  576. return RT_EOK;
  577. }
  578. static int hpm_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
  579. {
  580. RT_ASSERT(can);
  581. hpm_can_t *drv_can = (hpm_can_t*) can->parent.user_data;
  582. RT_ASSERT(drv_can);
  583. rt_can_msg_t can_msg = (rt_can_msg_t)buf;
  584. if (can_is_data_available_in_receive_buffer(drv_can->can_base)) {
  585. can_receive_buf_t rx_buf;
  586. hpm_stat_t status = can_read_received_message(drv_can->can_base, &rx_buf);
  587. if (status != status_success) {
  588. return -RT_ERROR;
  589. }
  590. if (rx_buf.extend_id != 0) {
  591. can_msg->ide = RT_CAN_EXTID;
  592. }
  593. else {
  594. can_msg->ide = RT_CAN_STDID;
  595. }
  596. can_msg->id = rx_buf.id;
  597. if (rx_buf.remote_frame != 0) {
  598. can_msg->rtr = RT_CAN_RTR;
  599. }
  600. else {
  601. can_msg->rtr = RT_CAN_DTR;
  602. }
  603. #ifdef RT_CAN_USING_CANFD
  604. can_msg->fd_frame = rx_buf.canfd_frame;
  605. can_msg->brs = rx_buf.bitrate_switch;
  606. #endif
  607. can_msg->len = rx_buf.dlc;
  608. uint32_t msg_len = can_get_data_bytes_from_dlc(can_msg->len);
  609. for(uint32_t i = 0; i < msg_len; i++) {
  610. can_msg->data[i] = rx_buf.data[i];
  611. }
  612. #ifdef RT_CAN_USING_HDR
  613. /* Hardware filter messages are valid */
  614. can_msg->hdr_index = boxno;
  615. can->hdr[can_msg->hdr_index].connected = 1;
  616. #endif
  617. }
  618. else {
  619. return -RT_EEMPTY;
  620. }
  621. return RT_EOK;
  622. }
  623. static uint8_t can_get_data_bytes_from_dlc(uint32_t dlc)
  624. {
  625. uint32_t data_bytes = 0;
  626. dlc &= 0xFU;
  627. if (dlc <= 8U) {
  628. data_bytes = dlc;
  629. } else {
  630. switch (dlc) {
  631. case can_payload_size_12:
  632. data_bytes = 12U;
  633. break;
  634. case can_payload_size_16:
  635. data_bytes = 16U;
  636. break;
  637. case can_payload_size_20:
  638. data_bytes = 20U;
  639. break;
  640. case can_payload_size_24:
  641. data_bytes = 24U;
  642. break;
  643. case can_payload_size_32:
  644. data_bytes = 32U;
  645. break;
  646. case can_payload_size_48:
  647. data_bytes = 48U;
  648. break;
  649. case can_payload_size_64:
  650. data_bytes = 64U;
  651. break;
  652. default:
  653. /* Code should never touch here */
  654. break;
  655. }
  656. }
  657. return data_bytes;
  658. }
  659. int rt_hw_can_init(void)
  660. {
  661. struct can_configure config = CANDEFAULTCONFIG;
  662. config.privmode = RT_CAN_MODE_NOPRIV;
  663. config.sndboxnumber = CAN_SENDBOX_NUM;
  664. config.ticks = 50;
  665. #ifdef RT_CAN_USING_HDR
  666. config.maxhdr = 16;
  667. #endif
  668. for (uint32_t i = 0; i < ARRAY_SIZE(hpm_cans); i++)
  669. {
  670. hpm_cans[i]->can_dev.config = config;
  671. hpm_cans[i]->filter_num = 0;
  672. can_get_default_config(&hpm_cans[i]->can_config);
  673. rt_hw_can_register(&hpm_cans[i]->can_dev, hpm_cans[i]->name, &hpm_can_ops, hpm_cans[i]);
  674. }
  675. return RT_EOK;
  676. }
  677. INIT_BOARD_EXPORT(rt_hw_can_init);
  678. #endif