drv_can.c 22 KB

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