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