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