drv_can.c 19 KB

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