drv_can.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-08-22 QT-one first version
  9. */
  10. #include <rtdbg.h>
  11. #include "drv_can.h"
  12. #include "ht32_can_config.h"
  13. #ifdef BSP_USING_CAN
  14. #if !defined(BSP_USING_CAN)
  15. #error "Please define at least one BSP_USING_CAN"
  16. #endif
  17. #define CAN_UMASK_MODE 0
  18. #define CAN_MASK_MODE 1
  19. struct ht32_can_msg_type
  20. {
  21. CAN_MSG_TypeDef cfg_msg;
  22. uint32_t data_len;
  23. uint8_t data[8];
  24. };
  25. /* Baud rate mapping structure */
  26. struct ht32_baud_rate
  27. {
  28. enum CANBAUD rt_baud_rate;
  29. uint32_t us_baus_rate;
  30. };
  31. /* CAN Filter Table Configuration Structure */
  32. struct ht32_can_filter_config
  33. {
  34. /* Each bit represents a message;1: the message is occupied;0: the message is not occupied */
  35. uint32_t filter_flag;
  36. /* Filter table configuration information */
  37. CAN_MSG_TypeDef filter_mag[MSG_OBJ_TOTAL_NUM];
  38. };
  39. /* CAN Object Structures */
  40. struct ht32_can
  41. {
  42. char *name; /* Equipment name */
  43. HT_CAN_TypeDef *can_x; /* peripheral base address */
  44. struct can_configure cfg; /* CAN Configuration Structure */
  45. struct rt_can_device device; /* Inherited device options */
  46. struct ht32_can_filter_config filter_cfg; /* Filter Table Configuration */
  47. };
  48. /* CAN Baud Rate Mapping Table */
  49. static const struct ht32_baud_rate can_baud_rate_tab[] =
  50. {
  51. {CAN1MBaud, 1000000},
  52. {CAN800kBaud, 800000},
  53. {CAN500kBaud, 500000},
  54. {CAN250kBaud, 250000},
  55. {CAN125kBaud, 125000},
  56. {CAN100kBaud, 100000},
  57. {CAN50kBaud, 50000},
  58. {CAN20kBaud, 20000},
  59. {CAN10kBaud, 10000},
  60. };
  61. /* CAN Object Information */
  62. static struct ht32_can ht32_can_config =
  63. {
  64. .name = BSP_USING_CAN_NAME,
  65. .can_x = HT_CAN0,
  66. .cfg = {0},
  67. .device = RT_NULL,
  68. .filter_cfg = {0},
  69. };
  70. /**
  71. * @brief Default Filter Table Configuration
  72. * @param can_instance:CAN object
  73. * @retval
  74. */
  75. static rt_uint32_t cfg_can_default_filter(struct ht32_can *can_instance)
  76. {
  77. uint8_t filter_num = BSP_USING_CAN_MSG_NUM;
  78. can_instance->filter_cfg.filter_flag |= 1 << filter_num;
  79. can_instance->filter_cfg.filter_mag[filter_num].MsgNum = filter_num + 1;
  80. can_instance->filter_cfg.filter_mag[filter_num].IdType = (CAN_IdType_Enum)BSP_USING_CAN_ID_MODE;
  81. can_instance->filter_cfg.filter_mag[filter_num].IdMask = BSP_USING_CAN_MASK;
  82. can_instance->filter_cfg.filter_mag[filter_num].FrameType = (CAN_FrameType_Enum)BSP_USING_CAN_FRAME_MODE;
  83. can_instance->filter_cfg.filter_mag[filter_num].Id = BSP_USING_CAN_ID;
  84. CAN_SetRxMsg(can_instance->can_x, &can_instance->filter_cfg.filter_mag[filter_num], 1);
  85. return RT_EOK;
  86. }
  87. /**
  88. * @brief Get baud rate mapping parameters for CAN
  89. * @info This function is mainly used to convert the baud rate of RTT format to HT32 format baud rate
  90. * @param baud:CAN baud rate in RTT format
  91. * @retval Returns the CAN baud rate in HT32 format.
  92. */
  93. static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
  94. {
  95. rt_uint32_t len, index;
  96. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  97. for (index = 0; index < len; index++)
  98. {
  99. if (can_baud_rate_tab[index].rt_baud_rate == baud)
  100. return can_baud_rate_tab[index].us_baus_rate;
  101. }
  102. return 0;
  103. }
  104. /**
  105. * @brief Configuring CAN Structures
  106. * @info This function depends on the ht32_can_config.h file
  107. * @param can_ck:System clock for CAN
  108. * @param can_buad:CAN baud rate to be configured
  109. * @param mode:Modes of CAN
  110. * @param nart:enable or disable the no automatic retransmission
  111. * @param CAN_InitStruct:Structures to be configured
  112. * @retval 1:success;0:error
  113. */
  114. static rt_uint32_t config_can_struct(uint32_t can_ck,
  115. uint32_t can_buad,
  116. uint8_t mode,
  117. ControlStatus nart,
  118. CAN_InitTypeDef* CAN_InitStruct)
  119. {
  120. uint8_t cf0_nbt = 0;
  121. uint32_t nominal_bit_time = 0;
  122. for (cf0_nbt = 25; cf0_nbt > 8; cf0_nbt--)
  123. {
  124. if ((can_ck / can_buad / cf0_nbt) > 0)
  125. {
  126. if (((can_ck / (can_ck / can_buad / cf0_nbt)) / cf0_nbt) <= can_buad)
  127. {
  128. nominal_bit_time = cf0_nbt;
  129. break;
  130. }
  131. }
  132. }
  133. if (cf0_nbt < 8)
  134. {
  135. return 0;
  136. }
  137. CAN_InitStruct->CAN_BRPrescaler = (can_ck / (can_buad * nominal_bit_time));
  138. CAN_InitStruct->CAN_SJW = HTCFG_CAN_CF0_BIT_TIME_SJW;
  139. CAN_InitStruct->CAN_TSEG1 = (nominal_bit_time - (nominal_bit_time * HTCFG_CAN_CF0_SAMPLE_POINT) / 100);
  140. CAN_InitStruct->CAN_TSEG0 = (nominal_bit_time - 1 - CAN_InitStruct->CAN_TSEG1);
  141. CAN_InitStruct->CAN_NART = nart;
  142. CAN_InitStruct->CAN_Mode = mode;
  143. return 1;
  144. }
  145. /**
  146. * @brief CAN Configuration Functions
  147. * @param
  148. * @retval
  149. */
  150. static rt_err_t ht32_can_configure(struct rt_can_device *can, struct can_configure *cfg)
  151. {
  152. CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
  153. struct ht32_can *can_instance = RT_NULL;
  154. rt_uint32_t can_baud = 0;
  155. rt_uint8_t can_mode = 0;
  156. CAN_InitTypeDef CAN_InitStruct = {0};
  157. RT_ASSERT(can);
  158. RT_ASSERT(cfg);
  159. can_instance = (struct ht32_can *)can->parent.user_data;
  160. RT_ASSERT(can_instance != RT_NULL);
  161. CKCUClock.Bit.AFIO = 1;
  162. CKCUClock.Bit.CAN0 = 1;
  163. CKCU_PeripClockConfig(CKCUClock, ENABLE);
  164. ht32_can_gpio_init(can_instance->can_x);
  165. /* Get baud rate */
  166. can_baud = get_can_baud_index(cfg->baud_rate);
  167. if (can_baud == 0)
  168. {
  169. return -RT_ERROR;
  170. }
  171. can_instance->cfg.baud_rate = cfg->baud_rate;
  172. can_instance->cfg.mode = cfg->mode;
  173. /* Configuring the operating mode of CAN */
  174. switch (cfg->mode)
  175. {
  176. case RT_CAN_MODE_NORMAL:
  177. can_mode = CAN_MODE_NORMAL;
  178. break;
  179. case RT_CAN_MODE_LISTEN:
  180. can_mode = CAN_MODE_SILENT;
  181. break;
  182. case RT_CAN_MODE_LOOPBACK:
  183. can_mode = CAN_MODE_LBACK;
  184. break;
  185. case RT_CAN_MODE_LOOPBACKANLISTEN:
  186. can_mode = CAN_MODE_SILENT | CAN_MODE_LBACK;
  187. break;
  188. default:
  189. return -RT_ERROR;
  190. }
  191. if (0 == (config_can_struct(_HTCFG_CF0_CK_CAN, can_baud, can_mode, DISABLE, &CAN_InitStruct)))
  192. {
  193. return -RT_ERROR;
  194. }
  195. /* Reset CAN */
  196. CAN_DeInit(can_instance->can_x);
  197. /* Initialising CAN */
  198. CAN_Init(can_instance->can_x, &CAN_InitStruct);
  199. /* Configuring the Default Filter for CAN */
  200. cfg_can_default_filter(can_instance);
  201. return RT_EOK;
  202. }
  203. /**
  204. * @brief CAN Control Functions
  205. * @param
  206. * @retval
  207. */
  208. rt_err_t ht32_can_control(struct rt_can_device *can, int cmd, void *arg)
  209. {
  210. rt_uint32_t argval;
  211. struct ht32_can *can_instance;
  212. struct rt_can_filter_config *filter_cfg;
  213. RT_ASSERT(can != RT_NULL);
  214. can_instance = (struct ht32_can *)can->parent.user_data;
  215. RT_ASSERT(can_instance != RT_NULL);
  216. switch (cmd)
  217. {
  218. case RT_DEVICE_CTRL_CLR_INT:/* Clear Interrupt */
  219. {
  220. argval = (rt_uint32_t) arg;
  221. if (argval == RT_DEVICE_FLAG_INT_RX) /* receive interruptions */
  222. {
  223. if (CAN_GetFlagStatus(can_instance->can_x, CAN_FLAG_RXOK))
  224. {
  225. /* Clear RXOK Flag */
  226. CAN_ClearFlag(can_instance->can_x, CAN_FLAG_RXOK);
  227. }
  228. }
  229. else if (argval == RT_DEVICE_FLAG_INT_TX) /* Send Interrupt */
  230. {
  231. if (CAN_GetFlagStatus(can_instance->can_x, CAN_FLAG_TXOK))
  232. {
  233. /* Clear TXOK flag*/
  234. CAN_ClearFlag(can_instance->can_x, CAN_FLAG_TXOK);
  235. }
  236. }
  237. else if (argval == RT_DEVICE_CAN_INT_ERR) /* false interruption */
  238. {
  239. /* Error Process*/
  240. CAN_LastErrorCode_TypeDef lec = CAN_GetLastErrorCode(can_instance->can_x);
  241. if (lec != NO_ERROR)
  242. {
  243. LOG_W("LEC: %d\r\n", lec);
  244. }
  245. if (CAN_GetFlagStatus(can_instance->can_x, CAN_FLAG_BOFF))
  246. {
  247. /* Recover from Bus off state.*/
  248. CAN_BusOffRecovery(can_instance->can_x);
  249. }
  250. }
  251. break;
  252. }
  253. case RT_DEVICE_CTRL_SET_INT:/* Setting Up Interruptions */
  254. {
  255. argval = (rt_uint32_t) arg;
  256. if (argval == RT_DEVICE_FLAG_INT_RX) /* interrupt receive mode */
  257. {
  258. LOG_W("Configuring Receive Interrupts!\r\n");
  259. CAN_IntConfig(can_instance->can_x, CAN_INT_EIE | CAN_INT_SIE | CAN_INT_IE, ENABLE);
  260. NVIC_EnableIRQ(CAN0_IRQn);
  261. }
  262. else if (argval == RT_DEVICE_FLAG_INT_TX) /* interrupt transmission mode */
  263. {
  264. LOG_W("Configuring Transmit Interrupts!\r\n");
  265. }
  266. else if (argval == RT_DEVICE_CAN_INT_ERR) /* false interruption */
  267. {
  268. LOG_W("Configuration error interrupt!\r\n");
  269. }
  270. break;
  271. }
  272. case RT_CAN_CMD_SET_FILTER:/* Configuring the Hardware Filter Table */
  273. {
  274. int i = 0;
  275. uint8_t filter_num = 0;
  276. uint32_t idmask = 0;
  277. if (RT_NULL == arg)
  278. {
  279. /* default filter config */
  280. cfg_can_default_filter(can_instance);
  281. }
  282. else
  283. {
  284. filter_cfg = (struct rt_can_filter_config *)arg;
  285. if (filter_cfg->count > MSG_OBJ_TOTAL_NUM)
  286. {
  287. LOG_W("Filter list length exceeds the limit(max 32)!");
  288. return -RT_ERROR;
  289. }
  290. for (i = 0; i < filter_cfg->count; i++)
  291. {
  292. /* Specify the filter table number or no */
  293. if (filter_cfg->items[i].hdr_bank == -1)
  294. {
  295. filter_num = i;
  296. }
  297. else
  298. {
  299. if (filter_cfg->items[i].hdr_bank > MSG_OBJ_TOTAL_NUM)
  300. {
  301. LOG_W("Filter List Number Out of Limits(1-32)!");
  302. return -RT_ERROR;
  303. }
  304. else
  305. {
  306. filter_num = filter_cfg->items[i].hdr_bank;
  307. }
  308. }
  309. if (can_instance->filter_cfg.filter_flag & (1 << filter_num))
  310. {
  311. LOG_W("This filter channel will be changed(num:%d)!", filter_num);
  312. rt_kprintf("This filter channel will be changed(num:%d)!", filter_num);
  313. }
  314. can_instance->filter_cfg.filter_flag |= 1 << filter_num;
  315. can_instance->filter_cfg.filter_mag[filter_num].MsgNum = filter_num + 1;
  316. /* Standard or Extended Frames */
  317. if (filter_cfg->items[i].ide == RT_CAN_STDID)
  318. {
  319. can_instance->filter_cfg.filter_mag[filter_num].IdType = CAN_STD_ID;
  320. idmask = 0x7FF;
  321. }
  322. else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
  323. {
  324. can_instance->filter_cfg.filter_mag[filter_num].IdType = CAN_EXT_ID;
  325. idmask = 0x1FFFFFFF;
  326. }
  327. else
  328. {
  329. LOG_W("Frame pattern error(CAN_STD_ID/CAN_EXT_ID)!");
  330. return -RT_ERROR;
  331. }
  332. /* Whether to use MASK mode */
  333. if (filter_cfg->items[i].mode == CAN_UMASK_MODE)
  334. {
  335. can_instance->filter_cfg.filter_mag[filter_num].IdMask = idmask;
  336. }
  337. else if (filter_cfg->items[i].mode == CAN_MASK_MODE)
  338. {
  339. can_instance->filter_cfg.filter_mag[filter_num].IdMask = filter_cfg->items[i].mask;
  340. }
  341. else
  342. {
  343. LOG_W("MASK mode error(CAN_UMASK_MODE/CAN_MASK_MODE)!");
  344. return -RT_ERROR;
  345. }
  346. /* Remote frames or data frames */
  347. if (filter_cfg->items[i].rtr == RT_CAN_RTR)
  348. {
  349. can_instance->filter_cfg.filter_mag[filter_num].FrameType = CAN_REMOTE_FRAME;
  350. }
  351. else if (filter_cfg->items[i].rtr == RT_CAN_DTR)
  352. {
  353. can_instance->filter_cfg.filter_mag[filter_num].FrameType = CAN_DATA_FRAME;
  354. }
  355. /* Setting ID */
  356. can_instance->filter_cfg.filter_mag[filter_num].Id = filter_cfg->items[i].id;
  357. /* Setting up the CAN filter table */
  358. CAN_SetRxMsg(can_instance->can_x, &can_instance->filter_cfg.filter_mag[filter_num], 1);
  359. }
  360. }
  361. break;
  362. }
  363. case RT_CAN_CMD_SET_BAUD:/* Setting the baud rate */
  364. {
  365. argval = (rt_uint32_t) arg;
  366. if (argval != CAN1MBaud &&
  367. argval != CAN800kBaud &&
  368. argval != CAN500kBaud &&
  369. argval != CAN250kBaud &&
  370. argval != CAN125kBaud &&
  371. argval != CAN100kBaud &&
  372. argval != CAN50kBaud &&
  373. argval != CAN20kBaud &&
  374. argval != CAN10kBaud)
  375. {
  376. return -RT_ERROR;
  377. }
  378. if (argval != can_instance->cfg.baud_rate)
  379. {
  380. can_instance->cfg.baud_rate = argval;
  381. return ht32_can_configure(&can_instance->device, &can_instance->cfg);
  382. }
  383. break;
  384. }
  385. case RT_CAN_CMD_SET_MODE:/* Setting the CAN Operating Mode */
  386. {
  387. argval = (rt_uint32_t) arg;
  388. if (argval != RT_CAN_MODE_NORMAL &&
  389. argval != RT_CAN_MODE_LISTEN &&
  390. argval != RT_CAN_MODE_LOOPBACK &&
  391. argval != RT_CAN_MODE_LOOPBACKANLISTEN)
  392. {
  393. return -RT_ERROR;
  394. }
  395. if (argval != can_instance->cfg.mode)
  396. {
  397. can_instance->cfg.mode = argval;
  398. return ht32_can_configure(&can_instance->device, &can_instance->cfg);
  399. }
  400. break;
  401. }
  402. case RT_CAN_CMD_GET_STATUS:/* Get CAN device status */
  403. {
  404. rt_uint32_t errtype;
  405. errtype = can_instance->can_x->ECR;
  406. can_instance->device.status.rcverrcnt = ((errtype >> 8) & 0x7f);
  407. can_instance->device.status.snderrcnt = (errtype & 0xff);
  408. errtype = can_instance->can_x->SR;
  409. can_instance->device.status.lasterrtype = (errtype & 0x07);
  410. can_instance->device.status.errcode = ((errtype >> 5) & 0x07);
  411. rt_memcpy(arg, &can_instance->device.status, sizeof(can_instance->device.status));
  412. break;
  413. }
  414. default:
  415. return -RT_ERROR;
  416. }
  417. return RT_EOK;
  418. }
  419. /**
  420. * @brief CAN sends data
  421. * @param
  422. * @retval
  423. */
  424. rt_ssize_t ht32_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  425. {
  426. struct ht32_can *can_instance = RT_NULL;
  427. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  428. struct ht32_can_msg_type tx_msg = {0};
  429. RT_ASSERT(can != RT_NULL);
  430. can_instance = (struct ht32_can *)can->parent.user_data;
  431. RT_ASSERT(can_instance != RT_NULL);
  432. /* Standard and Extended Frames */
  433. if (CAN_STD_ID == pmsg->ide)
  434. {
  435. tx_msg.cfg_msg.IdType = CAN_STD_ID;
  436. tx_msg.cfg_msg.Id = pmsg->id;
  437. }
  438. else if (CAN_EXT_ID == pmsg->ide)
  439. {
  440. tx_msg.cfg_msg.IdType = CAN_EXT_ID;
  441. tx_msg.cfg_msg.Id = pmsg->id;
  442. }
  443. else
  444. {
  445. LOG_W("Frame pattern error(CAN_STD_ID/CAN_EXT_ID)!");
  446. return -RT_ERROR;
  447. }
  448. /* Teleframes and data frames */
  449. if (RT_CAN_RTR == pmsg->rtr)
  450. {
  451. tx_msg.cfg_msg.FrameType = CAN_REMOTE_FRAME;
  452. }
  453. else if (RT_CAN_DTR == pmsg->rtr)
  454. {
  455. tx_msg.cfg_msg.FrameType = CAN_DATA_FRAME;
  456. }
  457. else
  458. {
  459. LOG_W("Remote frame setting error(CAN_REMOTE_FRAME/CAN_DATA_FRAME)!");
  460. return -RT_ERROR;
  461. }
  462. /* Length of sent data */
  463. tx_msg.data_len = pmsg->len & 0x0FU;
  464. /* data being sent */
  465. tx_msg.data[0] = pmsg->data[0];
  466. tx_msg.data[1] = pmsg->data[1];
  467. tx_msg.data[2] = pmsg->data[2];
  468. tx_msg.data[3] = pmsg->data[3];
  469. tx_msg.data[4] = pmsg->data[4];
  470. tx_msg.data[5] = pmsg->data[5];
  471. tx_msg.data[6] = pmsg->data[6];
  472. tx_msg.data[7] = pmsg->data[7];
  473. /* Waiting tx Msg idle */
  474. while (CAN_TransmitStatus(can_instance->can_x, &tx_msg.cfg_msg) == 0);
  475. /* Loopback data */
  476. CAN_Transmit(can_instance->can_x, &tx_msg.cfg_msg, tx_msg.data, tx_msg.data_len);
  477. return RT_EOK;
  478. }
  479. /**
  480. * @brief CAN receive data
  481. * @param
  482. * @retval
  483. */
  484. rt_ssize_t ht32_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
  485. {
  486. uint8_t i = 0;
  487. uint32_t msgnum = 0;
  488. CAN_RxStatus_TypeDef rx_status;
  489. struct ht32_can_msg_type rx_msg = {0};
  490. struct ht32_can *can_instance = RT_NULL;
  491. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  492. RT_ASSERT(can != RT_NULL);
  493. RT_ASSERT(pmsg != RT_NULL);
  494. can_instance = (struct ht32_can *)can->parent.user_data;
  495. RT_ASSERT(can_instance != RT_NULL);
  496. msgnum = can_instance->filter_cfg.filter_flag;
  497. for (i = 0; i < MSG_OBJ_TOTAL_NUM; i++)
  498. {
  499. if ((msgnum & 1) == 1)
  500. {
  501. rx_status = CAN_Receive(can_instance->can_x, &can_instance->filter_cfg.filter_mag[i], rx_msg.data, &rx_msg.data_len);
  502. if (rx_status == MSG_OVER_RUN)
  503. {
  504. LOG_W("ID[%X] rx message over run\r\n", can_instance->filter_cfg.filter_mag[i].Id);
  505. }
  506. else if (rx_status == MSG_OBJ_NOT_SET)
  507. {
  508. LOG_W("rx message not set \r\n");
  509. }
  510. else if (rx_status == MSG_RX_FINISH)
  511. {
  512. LOG_W("rx ok \r\n");
  513. pmsg->data[0] = rx_msg.data[0];
  514. pmsg->data[1] = rx_msg.data[1];
  515. pmsg->data[2] = rx_msg.data[2];
  516. pmsg->data[3] = rx_msg.data[3];
  517. pmsg->data[4] = rx_msg.data[4];
  518. pmsg->data[5] = rx_msg.data[5];
  519. pmsg->data[6] = rx_msg.data[6];
  520. pmsg->data[7] = rx_msg.data[7];
  521. pmsg->len = rx_msg.data_len;
  522. if (can_instance->filter_cfg.filter_mag[i].IdType == CAN_EXT_ID)
  523. {
  524. pmsg->id = can_instance->filter_cfg.filter_mag[i].Id;
  525. pmsg->ide = RT_CAN_EXTID;
  526. }
  527. else if (can_instance->filter_cfg.filter_mag[i].IdType == CAN_STD_ID)
  528. {
  529. pmsg->id = can_instance->filter_cfg.filter_mag[i].Id;
  530. pmsg->ide = RT_CAN_EXTID;
  531. }
  532. if (can_instance->filter_cfg.filter_mag[i].FrameType == CAN_DATA_FRAME)
  533. {
  534. pmsg->rtr = RT_CAN_DTR;
  535. }
  536. else if (can_instance->filter_cfg.filter_mag[i].FrameType == CAN_REMOTE_FRAME)
  537. {
  538. pmsg->rtr = RT_CAN_RTR;
  539. }
  540. return RT_EOK;
  541. }
  542. }
  543. msgnum = msgnum >> 1;
  544. if (msgnum == 0)
  545. {
  546. return -1;
  547. }
  548. }
  549. return -1;
  550. }
  551. /* Mapping CAN interfaces */
  552. static const struct rt_can_ops ht32_can_ops =
  553. {
  554. .configure = ht32_can_configure, /* CAN Configuration Functions */
  555. .control = ht32_can_control, /* CAN Control Functions */
  556. .sendmsg = ht32_can_sendmsg, /* CAN Transmit Data */
  557. .recvmsg = ht32_can_recvmsg, /* CAN Receive Data */
  558. };
  559. int rt_hw_can_init(void)
  560. {
  561. struct can_configure config = CANDEFAULTCONFIG;
  562. config.mode = BSP_USING_CAN_MODE;
  563. config.baud_rate = BSP_USING_CAN_BAUD;
  564. config.privmode = RT_CAN_MODE_NOPRIV;
  565. config.ticks = 50;
  566. #ifdef RT_CAN_USING_HDR
  567. config.maxhdr = 14;
  568. #endif
  569. ht32_can_config.device.config = config;
  570. /* Registration of CAN devices */
  571. rt_hw_can_register(&ht32_can_config.device,
  572. ht32_can_config.name,
  573. &ht32_can_ops,
  574. &ht32_can_config);
  575. return RT_EOK;
  576. }
  577. INIT_BOARD_EXPORT(rt_hw_can_init);
  578. void CAN0_IRQHandler(void)
  579. {
  580. CAN_LastErrorCode_TypeDef lec;
  581. rt_interrupt_enter();
  582. /* Recover from Bus off state. */
  583. if (CAN_GetFlagStatus(ht32_can_config.can_x, CAN_FLAG_BOFF))
  584. {
  585. CAN_BusOffRecovery(ht32_can_config.can_x);
  586. }
  587. /* Transmit message finished */
  588. if (CAN_GetFlagStatus(ht32_can_config.can_x, CAN_FLAG_TXOK))
  589. {
  590. rt_hw_can_isr(&ht32_can_config.device, RT_CAN_EVENT_TX_DONE);
  591. CAN_ClearFlag(ht32_can_config.can_x, CAN_FLAG_TXOK);
  592. }
  593. /* Message received. */
  594. if (CAN_GetFlagStatus(ht32_can_config.can_x, CAN_FLAG_RXOK))
  595. {
  596. /* Clear all message objects' interrupt pending flag */
  597. CAN_ClearAllMsgPendingFlag(ht32_can_config.can_x);
  598. rt_hw_can_isr(&ht32_can_config.device, RT_CAN_EVENT_RX_IND);
  599. CAN_ClearFlag(ht32_can_config.can_x, CAN_FLAG_RXOK);
  600. }
  601. lec = CAN_GetLastErrorCode(ht32_can_config.can_x);
  602. if (lec != NO_ERROR)
  603. {
  604. switch (lec)
  605. {
  606. case NO_ERROR:
  607. break;
  608. case STUFF_ERROR:
  609. ht32_can_config.device.status.bitpaderrcnt++;
  610. break;
  611. case FORM_ERROR:
  612. ht32_can_config.device.status.formaterrcnt++;
  613. break;
  614. case ACK_ERROR:
  615. ht32_can_config.device.status.ackerrcnt++;
  616. break;
  617. case BIT1_EROR:
  618. case BIT0_ERROR:
  619. ht32_can_config.device.status.biterrcnt++;
  620. break;
  621. case CRC_ERROR:
  622. ht32_can_config.device.status.crcerrcnt++;
  623. break;
  624. case NO_CHANGE:
  625. break;
  626. }
  627. ht32_can_config.device.status.lasterrtype = lec;
  628. ht32_can_config.device.status.rcverrcnt = CAN_GetReceiveErrorCounter(ht32_can_config.can_x);
  629. ht32_can_config.device.status.snderrcnt = CAN_GetLSBTransmitErrorCounter(ht32_can_config.can_x);
  630. ht32_can_config.device.status.errcode = lec;
  631. }
  632. rt_interrupt_leave();
  633. }
  634. #endif /* BSP_USING_CAN */