drv_can.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-11-09 wangyq the first version
  9. */
  10. #include "drv_can.h"
  11. #ifdef BSP_USING_CAN
  12. static struct es32f0_can can;
  13. /* attention !!! baud calculation example: Pclk / ((sjw + seg1 + seg2) * psc) 48 / ((1 + 3 + 2) * 8) = 1MHz */
  14. static const struct es32f0_baud_rate_tab can_baud_rate_tab[] =
  15. {
  16. {CAN1MBaud, 8},
  17. {CAN800kBaud, 10},
  18. {CAN500kBaud, 16},
  19. {CAN250kBaud, 32},
  20. {CAN125kBaud, 64},
  21. {CAN100kBaud, 80},
  22. {CAN50kBaud, 160},
  23. {CAN20kBaud, 400},
  24. {CAN10kBaud, 800}
  25. };
  26. static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
  27. {
  28. rt_uint32_t len, index;
  29. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  30. for (index = 0; index < len; index++)
  31. {
  32. if (can_baud_rate_tab[index].baud_rate == baud)
  33. return index;
  34. }
  35. return 0; /* default baud is CAN1MBaud */
  36. }
  37. static rt_err_t _can_config(struct rt_can_device *can_device, struct can_configure *cfg)
  38. {
  39. struct es32f0_can *drv_can;
  40. rt_uint32_t baud_index;
  41. RT_ASSERT(can_device);
  42. RT_ASSERT(cfg);
  43. drv_can = (struct es32f0_can *)can_device->parent.user_data;
  44. RT_ASSERT(drv_can);
  45. drv_can->CanHandle.perh = CAN0;
  46. drv_can->CanHandle.init.ttcm = DISABLE;
  47. drv_can->CanHandle.init.abom = ENABLE;
  48. drv_can->CanHandle.init.awk = DISABLE;
  49. drv_can->CanHandle.init.artx = DISABLE;
  50. drv_can->CanHandle.init.rfom = DISABLE;
  51. drv_can->CanHandle.init.txmp = ENABLE;
  52. switch (cfg->mode)
  53. {
  54. case RT_CAN_MODE_NORMAL:
  55. drv_can->CanHandle.init.mode = CAN_MODE_NORMAL;
  56. break;
  57. case RT_CAN_MODE_LISEN:
  58. drv_can->CanHandle.init.mode = CAN_MODE_SILENT;
  59. break;
  60. case RT_CAN_MODE_LOOPBACK:
  61. drv_can->CanHandle.init.mode = CAN_MODE_LOOPBACK;
  62. break;
  63. case RT_CAN_MODE_LOOPBACKANLISEN:
  64. drv_can->CanHandle.init.mode = CAN_MODE_SILENT_LOOPBACK;
  65. break;
  66. }
  67. baud_index = get_can_baud_index(cfg->baud_rate);
  68. drv_can->CanHandle.init.sjw = CAN_SJW_1;
  69. drv_can->CanHandle.init.seg1 = CAN_SEG1_3;
  70. drv_can->CanHandle.init.seg2 = CAN_SEG2_2;
  71. drv_can->CanHandle.init.psc = can_baud_rate_tab[baud_index].config_data;
  72. /* init can */
  73. if (ald_can_init(&drv_can->CanHandle) != OK)
  74. {
  75. return -RT_ERROR;
  76. }
  77. /* default filter config */
  78. ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
  79. return RT_EOK;
  80. }
  81. static rt_err_t _can_control(struct rt_can_device *can_device, int cmd, void *arg)
  82. {
  83. rt_uint32_t argval;
  84. struct es32f0_can *drv_can;
  85. struct rt_can_filter_config *filter_cfg;
  86. RT_ASSERT(can_device != RT_NULL);
  87. drv_can = (struct es32f0_can *)can_device->parent.user_data;
  88. RT_ASSERT(drv_can != RT_NULL);
  89. switch (cmd)
  90. {
  91. case RT_DEVICE_CTRL_CLR_INT:
  92. argval = (rt_uint32_t) arg;
  93. if (argval == RT_DEVICE_FLAG_INT_RX)
  94. {
  95. ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_FP0 | CAN_IT_FF0 | CAN_IT_FOV0 |
  96. CAN_IT_FP1 | CAN_IT_FF1 | CAN_IT_FOV1), DISABLE);
  97. }
  98. else if (argval == RT_DEVICE_FLAG_INT_TX)
  99. {
  100. ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, DISABLE);
  101. }
  102. else if (argval == RT_DEVICE_CAN_INT_ERR)
  103. {
  104. ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_WARN | CAN_IT_PERR | CAN_IT_BOF |
  105. CAN_IT_PRERR | CAN_IT_ERR), DISABLE);
  106. }
  107. break;
  108. case RT_DEVICE_CTRL_SET_INT:
  109. argval = (rt_uint32_t) arg;
  110. if (argval == RT_DEVICE_FLAG_INT_RX)
  111. {
  112. NVIC_SetPriority(CAN0_IRQn, 1);
  113. NVIC_EnableIRQ(CAN0_IRQn);
  114. ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_FP0 | CAN_IT_FP1), ENABLE);
  115. }
  116. else if (argval == RT_DEVICE_FLAG_INT_TX)
  117. {
  118. NVIC_SetPriority(CAN0_IRQn, 1);
  119. NVIC_EnableIRQ(CAN0_IRQn);
  120. ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, ENABLE);
  121. }
  122. else if (argval == RT_DEVICE_CAN_INT_ERR)
  123. {
  124. NVIC_SetPriority(CAN0_IRQn, 1);
  125. NVIC_EnableIRQ(CAN0_IRQn);
  126. ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_WARN | CAN_IT_PERR | CAN_IT_BOF |
  127. CAN_IT_PRERR | CAN_IT_ERR), ENABLE);
  128. }
  129. break;
  130. case RT_CAN_CMD_SET_FILTER:
  131. if (RT_NULL == arg)
  132. {
  133. /* default filter config */
  134. ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
  135. }
  136. else
  137. {
  138. filter_cfg = (struct rt_can_filter_config *)arg;
  139. /* get default filter */
  140. for (int i = 0; i < filter_cfg->count; i++)
  141. {
  142. drv_can->FilterConfig.number = filter_cfg->items[i].hdr;
  143. drv_can->FilterConfig.id_high = (filter_cfg->items[i].id >> 13) & 0xFFFF;
  144. drv_can->FilterConfig.id_low = ((filter_cfg->items[i].id << 3) |
  145. (filter_cfg->items[i].ide << 2) |
  146. (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
  147. drv_can->FilterConfig.mask_id_high = (filter_cfg->items[i].mask >> 16) & 0xFFFF;
  148. drv_can->FilterConfig.mask_id_low = filter_cfg->items[i].mask & 0xFFFF;
  149. drv_can->FilterConfig.mode = (can_filter_mode_t)filter_cfg->items[i].mode;
  150. /* Filter conf */
  151. ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
  152. }
  153. }
  154. break;
  155. case RT_CAN_CMD_SET_MODE:
  156. argval = (rt_uint32_t) arg;
  157. if (argval != RT_CAN_MODE_NORMAL &&
  158. argval != RT_CAN_MODE_LISEN &&
  159. argval != RT_CAN_MODE_LOOPBACK &&
  160. argval != RT_CAN_MODE_LOOPBACKANLISEN)
  161. {
  162. return -RT_ERROR;
  163. }
  164. if (argval != drv_can->device.config.mode)
  165. {
  166. drv_can->device.config.mode = argval;
  167. return _can_config(&drv_can->device, &drv_can->device.config);
  168. }
  169. break;
  170. case RT_CAN_CMD_SET_BAUD:
  171. argval = (rt_uint32_t) arg;
  172. if (argval != CAN1MBaud &&
  173. argval != CAN800kBaud &&
  174. argval != CAN500kBaud &&
  175. argval != CAN250kBaud &&
  176. argval != CAN125kBaud &&
  177. argval != CAN100kBaud &&
  178. argval != CAN50kBaud &&
  179. argval != CAN20kBaud &&
  180. argval != CAN10kBaud)
  181. {
  182. return -RT_ERROR;
  183. }
  184. if (argval != drv_can->device.config.baud_rate)
  185. {
  186. drv_can->device.config.baud_rate = argval;
  187. return _can_config(&drv_can->device, &drv_can->device.config);
  188. }
  189. break;
  190. case RT_CAN_CMD_SET_PRIV:
  191. argval = (rt_uint32_t) arg;
  192. if (argval != RT_CAN_MODE_PRIV &&
  193. argval != RT_CAN_MODE_NOPRIV)
  194. {
  195. return -RT_ERROR;
  196. }
  197. if (argval != drv_can->device.config.privmode)
  198. {
  199. drv_can->device.config.privmode = argval;
  200. return _can_config(&drv_can->device, &drv_can->device.config);
  201. }
  202. break;
  203. case RT_CAN_CMD_GET_STATUS:
  204. {
  205. rt_uint32_t errtype;
  206. errtype = drv_can->CanHandle.perh->ERRSTAT;
  207. drv_can->device.status.rcverrcnt = errtype >> 24;
  208. drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF);
  209. drv_can->device.status.lasterrtype = errtype & 0x70;
  210. drv_can->device.status.errcode = errtype & 0x07;
  211. rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status));
  212. }
  213. break;
  214. }
  215. return RT_EOK;
  216. }
  217. static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
  218. {
  219. can_handle_t *h_can;
  220. h_can = &((struct es32f0_can *) can->parent.user_data)->CanHandle;
  221. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  222. can_tx_msg_t txheader = {0};
  223. can_state_t state = h_can->state;
  224. /* Check the parameters */
  225. RT_ASSERT(IS_CAN_DATA_LEN(pmsg->len));
  226. if ((state == CAN_STATE_READY) ||
  227. (state == CAN_STATE_BUSY_RX0))
  228. {
  229. /*check select mailbox is empty */
  230. switch (1 << box_num)
  231. {
  232. case CAN_TX_MAILBOX_0:
  233. if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM0) != SET)
  234. {
  235. /* Change CAN state */
  236. h_can->state = CAN_STATE_ERROR;
  237. /* Return function status */
  238. return -RT_ERROR;
  239. }
  240. break;
  241. case CAN_TX_MAILBOX_1:
  242. if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM1) != SET)
  243. {
  244. /* Change CAN state */
  245. h_can->state = CAN_STATE_ERROR;
  246. /* Return function status */
  247. return -RT_ERROR;
  248. }
  249. break;
  250. case CAN_TX_MAILBOX_2:
  251. if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM2) != SET)
  252. {
  253. /* Change CAN state */
  254. h_can->state = CAN_STATE_ERROR;
  255. /* Return function status */
  256. return -RT_ERROR;
  257. }
  258. break;
  259. default:
  260. RT_ASSERT(0);
  261. break;
  262. }
  263. if (RT_CAN_STDID == pmsg->ide)
  264. {
  265. txheader.type = CAN_ID_STD;
  266. RT_ASSERT(IS_CAN_STDID(pmsg->id));
  267. txheader.std = pmsg->id;
  268. }
  269. else
  270. {
  271. txheader.type = CAN_ID_EXT;
  272. RT_ASSERT(IS_CAN_EXTID(pmsg->id));
  273. txheader.ext = pmsg->id;
  274. }
  275. if (RT_CAN_DTR == pmsg->rtr)
  276. {
  277. txheader.rtr = CAN_RTR_DATA;
  278. }
  279. else
  280. {
  281. txheader.rtr = CAN_RTR_REMOTE;
  282. }
  283. /* clear TIR */
  284. h_can->perh->TxMailBox[box_num].TXID &= CAN_TXID0_TXMREQ_MSK;
  285. /* Set up the Id */
  286. if (RT_CAN_STDID == pmsg->ide)
  287. {
  288. h_can->perh->TxMailBox[box_num].TXID |= (txheader.std << CAN_TXID0_STDID_POSS) | txheader.rtr;
  289. }
  290. else
  291. {
  292. h_can->perh->TxMailBox[box_num].TXID |= (txheader.ext << CAN_TXID0_EXID_POSS) | txheader.type | txheader.rtr;
  293. }
  294. /* Set up the DLC */
  295. h_can->perh->TxMailBox[box_num].TXFCON = pmsg->len & 0x0FU;
  296. /* Set up the data field */
  297. WRITE_REG(h_can->perh->TxMailBox[box_num].TXDH,
  298. ((uint32_t)pmsg->data[7] << CAN_TXDH0_BYTE7_POSS) |
  299. ((uint32_t)pmsg->data[6] << CAN_TXDH0_BYTE6_POSS) |
  300. ((uint32_t)pmsg->data[5] << CAN_TXDH0_BYTE5_POSS) |
  301. ((uint32_t)pmsg->data[4] << CAN_TXDH0_BYTE4_POSS));
  302. WRITE_REG(h_can->perh->TxMailBox[box_num].TXDL,
  303. ((uint32_t)pmsg->data[3] << CAN_TXDL0_BYTE3_POSS) |
  304. ((uint32_t)pmsg->data[2] << CAN_TXDL0_BYTE2_POSS) |
  305. ((uint32_t)pmsg->data[1] << CAN_TXDL0_BYTE1_POSS) |
  306. ((uint32_t)pmsg->data[0] << CAN_TXDL0_BYTE0_POSS));
  307. /* Request transmission */
  308. SET_BIT(h_can->perh->TxMailBox[box_num].TXID, CAN_TXID0_TXMREQ_MSK);
  309. return RT_EOK;
  310. }
  311. else
  312. {
  313. /* Update error code */
  314. h_can->err |= 0x00040000U;
  315. return -RT_ERROR;
  316. }
  317. }
  318. static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
  319. {
  320. can_handle_t *h_can;
  321. struct rt_can_msg *pmsg;
  322. can_rx_msg_t rxheader = {0};
  323. RT_ASSERT(can);
  324. h_can = &((struct es32f0_can *)can->parent.user_data)->CanHandle;
  325. pmsg = (struct rt_can_msg *) buf;
  326. /* get data */
  327. if (ald_can_recv(h_can, (can_rx_fifo_t)fifo, &rxheader, 0xFFFF) != OK)
  328. return -RT_ERROR;
  329. pmsg->data[0] = rxheader.data[0];
  330. pmsg->data[1] = rxheader.data[1];
  331. pmsg->data[2] = rxheader.data[2];
  332. pmsg->data[3] = rxheader.data[3];
  333. pmsg->data[4] = rxheader.data[4];
  334. pmsg->data[5] = rxheader.data[5];
  335. pmsg->data[6] = rxheader.data[6];
  336. pmsg->data[7] = rxheader.data[7];
  337. /* get id */
  338. if (CAN_ID_STD == rxheader.type)
  339. {
  340. pmsg->ide = RT_CAN_STDID;
  341. pmsg->id = rxheader.std;
  342. }
  343. else
  344. {
  345. pmsg->ide = RT_CAN_EXTID;
  346. pmsg->id = rxheader.ext;
  347. }
  348. /* get type */
  349. if (CAN_RTR_DATA == rxheader.rtr)
  350. {
  351. pmsg->rtr = RT_CAN_DTR;
  352. }
  353. else
  354. {
  355. pmsg->rtr = RT_CAN_RTR;
  356. }
  357. /* get len */
  358. pmsg->len = rxheader.len;
  359. /* get hdr */
  360. pmsg->hdr = (rxheader.fmi + 1) >> 1;
  361. return RT_EOK;
  362. }
  363. static const struct rt_can_ops _can_ops =
  364. {
  365. _can_config,
  366. _can_control,
  367. _can_sendmsg,
  368. _can_recvmsg,
  369. };
  370. static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
  371. {
  372. can_handle_t *h_can;
  373. RT_ASSERT(can);
  374. h_can = &((struct es32f0_can *) can->parent.user_data)->CanHandle;
  375. switch (fifo)
  376. {
  377. case CAN_RX_FIFO0:
  378. /* Check Overrun flag for FIFO0 */
  379. if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV0) && ald_can_get_it_status(h_can, CAN_IT_FOV0))
  380. {
  381. /* Clear FIFO0 Overrun Flag */
  382. ald_can_clear_flag_status(h_can, CAN_FLAG_FOV0);
  383. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  384. }
  385. /* RX interrupt */
  386. else
  387. {
  388. /* save to user list */
  389. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  390. /* Clear FIFO0 rx Flag */
  391. SET_BIT(h_can->perh->RXF0, CAN_RXF0_FREE_MSK);
  392. }
  393. break;
  394. case CAN_RX_FIFO1:
  395. /* Check Overrun flag for FIFO1 */
  396. if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV1) && ald_can_get_it_status(h_can, CAN_IT_FOV1))
  397. {
  398. /* Clear FIFO1 Overrun Flag */
  399. ald_can_clear_flag_status(h_can, CAN_FLAG_FOV1);
  400. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  401. }
  402. /* RX interrupt */
  403. else
  404. {
  405. /* save to user list */
  406. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  407. /* Clear FIFO0 rx Flag */
  408. SET_BIT(h_can->perh->RXF1, CAN_RXF1_FREE_MSK);
  409. }
  410. break;
  411. }
  412. }
  413. /**
  414. * @brief This function handles CAN interrupts.
  415. */
  416. void CAN0_Handler(void)
  417. {
  418. rt_interrupt_enter();
  419. rt_uint32_t errtype;
  420. can_handle_t *h_can;
  421. h_can = &can.CanHandle;
  422. /* RX FIFO0 interrupt */
  423. if ((ald_can_get_it_status(h_can, CAN_IT_FP0)) && (CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO0) != 0))
  424. {
  425. _can_rx_isr(&can.device, CAN_RX_FIFO0);
  426. }
  427. /* RX FIFO1 interrupt */
  428. if ((ald_can_get_it_status(h_can, CAN_IT_FP1)) && (CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO1) != 0))
  429. {
  430. _can_rx_isr(&can.device, CAN_RX_FIFO1);
  431. }
  432. /* TX interrupt. transmit fifo0/1/2 is empty can trigger this interrupt */
  433. if (ald_can_get_flag_status(h_can, CAN_FLAG_M0REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
  434. {
  435. if (ald_can_get_flag_status(h_can, CAN_FLAG_M0TXC))
  436. {
  437. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 0 << 8);
  438. }
  439. else
  440. {
  441. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  442. }
  443. /* Clear transmission status flag M0REQC */
  444. ald_can_clear_flag_status(h_can, CAN_FLAG_M0REQC);
  445. }
  446. else if (ald_can_get_flag_status(h_can, CAN_FLAG_M1REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
  447. {
  448. if (ald_can_get_flag_status(h_can, CAN_FLAG_M1TXC))
  449. {
  450. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 1 << 8);
  451. }
  452. else
  453. {
  454. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  455. }
  456. ald_can_clear_flag_status(h_can, CAN_FLAG_M1REQC);
  457. }
  458. else if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
  459. {
  460. if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC))
  461. {
  462. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 2 << 8);
  463. }
  464. else
  465. {
  466. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  467. }
  468. ald_can_clear_flag_status(h_can, CAN_FLAG_M2REQC);
  469. }
  470. /* CAN error interrupt */
  471. if (ald_can_get_flag_status(h_can, CAN_FLAG_ERR) && ald_can_get_it_status(h_can, CAN_IT_ERR))
  472. {
  473. errtype = h_can->perh->ERRSTAT;
  474. switch ((errtype & 0x70) >> 4)
  475. {
  476. case RT_CAN_BUS_BIT_PAD_ERR:
  477. can.device.status.bitpaderrcnt++;
  478. break;
  479. case RT_CAN_BUS_FORMAT_ERR:
  480. can.device.status.formaterrcnt++;
  481. break;
  482. case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
  483. can.device.status.ackerrcnt++;
  484. if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
  485. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  486. else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
  487. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  488. else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
  489. rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  490. break;
  491. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  492. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  493. can.device.status.biterrcnt++;
  494. break;
  495. case RT_CAN_BUS_CRC_ERR:
  496. can.device.status.crcerrcnt++;
  497. break;
  498. }
  499. can.device.status.lasterrtype = errtype & 0x70;
  500. can.device.status.rcverrcnt = errtype >> 24;
  501. can.device.status.snderrcnt = (errtype >> 16 & 0xFF);
  502. can.device.status.errcode = errtype & 0x07;
  503. h_can->perh->IFC |= CAN_IFC_ERRIFC_MSK;
  504. }
  505. rt_interrupt_leave();
  506. }
  507. int rt_hw_can_init(void)
  508. {
  509. gpio_init_t h_gpio;
  510. struct can_configure config = CANDEFAULTCONFIG;
  511. config.privmode = RT_CAN_MODE_NOPRIV;
  512. config.ticks = 50;
  513. #ifdef RT_CAN_USING_HDR
  514. config.maxhdr = 14;
  515. #endif
  516. /* Initialize can common pin */
  517. h_gpio.odos = GPIO_PUSH_PULL;
  518. h_gpio.pupd = GPIO_PUSH_UP;
  519. h_gpio.odrv = GPIO_OUT_DRIVE_NORMAL;
  520. h_gpio.flt = GPIO_FILTER_DISABLE;
  521. h_gpio.type = GPIO_TYPE_TTL;
  522. h_gpio.func = GPIO_FUNC_4;
  523. /* Initialize can rx pin */
  524. h_gpio.mode = GPIO_MODE_INPUT;
  525. ald_gpio_init(GPIOA, GPIO_PIN_11, &h_gpio);
  526. /* Initialize can tx pin */
  527. h_gpio.mode = GPIO_MODE_OUTPUT;
  528. ald_gpio_init(GPIOA, GPIO_PIN_12, &h_gpio);
  529. /* config default filter */
  530. can_filter_t filter = {0};
  531. filter.id_high = 0x0000;
  532. filter.id_low = 0x0000;
  533. filter.mask_id_high = 0x0000;
  534. filter.mask_id_low = 0x0000;
  535. filter.fifo = CAN_FILTER_FIFO0;
  536. filter.number = 0;
  537. filter.mode = CAN_FILTER_MODE_MASK;
  538. filter.scale = CAN_FILTER_SCALE_32;
  539. filter.active = ENABLE;
  540. can.FilterConfig = filter;
  541. can.device.config = config;
  542. /* register CAN1 device */
  543. rt_hw_can_register(&can.device, "can", &_can_ops, &can);
  544. return 0;
  545. }
  546. INIT_BOARD_EXPORT(rt_hw_can_init);
  547. #endif /* BSP_USING_CAN */