1 /*
2  * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author               Notes
8  * 2024-xx-xx     CDT                  first version
9  */
10 
11 #include "drv_mcan.h"
12 #include <drv_config.h>
13 #include <board_config.h>
14 
15 #if defined(BSP_USING_MCAN)
16 #define LOG_TAG    "drv_mcan"
17 
18 /****************************************************************************************
19 * Type definitions for MCAN RT driver
20 ****************************************************************************************/
21 typedef struct hc32_mcan_config_struct
22 {
23     char *name;                         /* MCAN instance name */
24     CM_MCAN_TypeDef *instance;          /* MCAN instance */
25     stc_mcan_init_t init_para;          /* MCAN initialisation parameters */
26 
27     uint32_t int0_sel;
28     struct hc32_irq_config int0_cfg;    /* MCAN interrupt line 0 configuration */
29     uint32_t int1_sel;
30     struct hc32_irq_config int1_cfg;    /* MCAN interrupt line 1 configuration */
31 #if defined(HC32F4A8)
32     func_ptr_t irq_callback0;
33     func_ptr_t irq_callback1;
34 #endif
35 } hc32_mcan_config_t;
36 
37 typedef struct hc32_mcan_driver_struct
38 {
39     hc32_mcan_config_t mcan;            /* MCAN configuration */
40     struct rt_can_device can_device;    /* inherit from rt can device */
41     uint32_t tx_box_num;                /* current tx box number */
42 } hc32_mcan_driver_t;
43 
44 typedef struct mcan_baud_rate_struct
45 {
46     rt_uint32_t baud_rate;
47     rt_uint32_t baud_rate_fd;
48     stc_mcan_bit_time_config_t ll_bt;
49 } mcan_baud_rate_t;
50 
51 /****************************************************************************************
52 * Parameter validity check
53 ****************************************************************************************/
54 #if defined(BSP_USING_MCAN1) || defined(BSP_USING_MCAN2)
55 #define IS_RT_CAN_WORK_MODE(mode)           ((mode) <= RT_CAN_MODE_LOOPBACKANLISTEN)
56 #define IS_RT_CAN_PRIV_MODE(mode)           (((mode) == RT_CAN_MODE_PRIV) || ((mode) == RT_CAN_MODE_NOPRIV))
57 #define IS_MCAN_FD_MODE(mode)               (((mode) >= MCAN_FD_ARG_MIN) && ((mode) <= MCAN_FD_ARG_MAX))
58 
59 #define IS_MCAN_CC_BAUD_RATE(baud)          ((baud) == (CAN10kBaud)  || \
60                                              (baud) == (CAN20kBaud)  || \
61                                              (baud) == (CAN50kBaud)  || \
62                                              (baud) == (CAN100kBaud) || \
63                                              (baud) == (CAN125kBaud) || \
64                                              (baud) == (CAN250kBaud) || \
65                                              (baud) == (CAN500kBaud) || \
66                                              (baud) == (CAN800kBaud) || \
67                                              (baud) == (CAN1MBaud))
68 
69 #define IS_MCAN_NOMINAL_BAUD_RATE(baud)     ((baud) == (CAN500kBaud) || \
70                                              (baud) == (CAN1MBaud))
71 
72 #define IS_MCAN_DATA_BAUD_RATE(baud)        ((baud) == (CANFD_DATA_BAUD_1M) || \
73                                              (baud) == (CANFD_DATA_BAUD_2M) || \
74                                              (baud) == (CANFD_DATA_BAUD_4M) || \
75                                              (baud) == (CANFD_DATA_BAUD_5M) || \
76                                              (baud) == (CANFD_DATA_BAUD_8M))
77 
78 #define IS_CAN_VALID_ID(ide, id)            ((((ide) == 0) && ((id) <= MCAN_STD_ID_MASK)) || \
79                                              (((ide) == 1) && ((id) <= MCAN_EXT_ID_MASK)))
80 
81 /****************************************************************************************
82 * Interrupt definitions
83 ****************************************************************************************/
84 #define MCAN_RX_INT                         (MCAN_INT_RX_FIFO0_NEW_MSG | MCAN_INT_RX_FIFO1_NEW_MSG | MCAN_INT_RX_BUF_NEW_MSG)
85 #define MCAN_TX_INT                         (MCAN_INT_TX_CPLT)
86 #define MCAN_ERR_INT                        (MCAN_INT_ARB_PHASE_ERROR | MCAN_INT_DATA_PHASE_ERROR | MCAN_INT_ERR_LOG_OVF | \
87                                              MCAN_INT_ERR_PASSIVE | MCAN_INT_ERR_WARNING | MCAN_INT_BUS_OFF)
88 #define MCAN_INT0_SEL                       (MCAN_RX_INT)
89 #define MCAN_INT1_SEL                       (MCAN_TX_INT | MCAN_ERR_INT)
90 
91 /****************************************************************************************
92 * Baud rate(bit timing) configuration based on 80MHz clock
93 ****************************************************************************************/
94 #ifdef RT_CAN_USING_CANFD
95 static const mcan_baud_rate_t m_mcan_fd_baud_rate[] =
96 {
97     {CAN500kBaud, CANFD_DATA_BAUD_1M, MCAN_FD_CFG_500K_1M},
98     {CAN500kBaud, CANFD_DATA_BAUD_2M, MCAN_FD_CFG_500K_2M},
99     {CAN500kBaud, CANFD_DATA_BAUD_4M, MCAN_FD_CFG_500K_4M},
100     {CAN500kBaud, CANFD_DATA_BAUD_5M, MCAN_FD_CFG_500K_5M},
101     {CAN500kBaud, CANFD_DATA_BAUD_8M, MCAN_FD_CFG_500K_8M},
102     {CAN1MBaud, CANFD_DATA_BAUD_1M, MCAN_FD_CFG_1M_1M},
103     {CAN1MBaud, CANFD_DATA_BAUD_2M, MCAN_FD_CFG_1M_2M},
104     {CAN1MBaud, CANFD_DATA_BAUD_4M, MCAN_FD_CFG_1M_4M},
105     {CAN1MBaud, CANFD_DATA_BAUD_5M, MCAN_FD_CFG_1M_5M},
106     {CAN1MBaud, CANFD_DATA_BAUD_8M, MCAN_FD_CFG_1M_8M},
107 };
108 #else
109 static const mcan_baud_rate_t m_mcan_cc_baud_rate[] =
110 {
111     {CAN1MBaud,   0, MCAN_CC_CFG_1M},
112     {CAN800kBaud, 0, MCAN_CC_CFG_800K},
113     {CAN500kBaud, 0, MCAN_CC_CFG_500K},
114     {CAN250kBaud, 0, MCAN_CC_CFG_250K},
115     {CAN125kBaud, 0, MCAN_CC_CFG_125K},
116     {CAN100kBaud, 0, MCAN_CC_CFG_100K},
117     {CAN50kBaud,  0, MCAN_CC_CFG_50K},
118     {CAN20kBaud,  0, MCAN_CC_CFG_20K},
119     {CAN10kBaud,  0, MCAN_CC_CFG_10K},
120 };
121 #endif
122 
123 /****************************************************************************************
124 * Constants
125 ****************************************************************************************/
126 static const uint8_t m_mcan_data_size[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
127 
128 static const rt_uint32_t m_mcan_tx_priv_mode[] = {MCAN_TX_FIFO_MD, MCAN_TX_QUEUE_MD};
129 
130 static const rt_uint32_t m_mcan_work_mode[] = {MCAN_MD_NORMAL, MCAN_MD_BUS_MON, MCAN_MD_EXTERN_LOOPBACK, MCAN_MD_RESTRICTED_OP};
131 
132 #ifdef RT_CAN_USING_CANFD
133 static const rt_uint32_t m_mcan_fd_mode[] = {MCAN_FRAME_CLASSIC, MCAN_FRAME_ISO_FD_NO_BRS, MCAN_FRAME_ISO_FD_BRS, \
134                                              MCAN_FRAME_NON_ISO_FD_NO_BRS, MCAN_FRAME_NON_ISO_FD_BRS
135                                             };
136 #endif
137 
138 /****************************************************************************************
139 * Driver instance list
140 ****************************************************************************************/
141 enum
142 {
143 #ifdef BSP_USING_MCAN1
144     MCAN1_INDEX,
145 #endif
146 #ifdef BSP_USING_MCAN2
147     MCAN2_INDEX,
148 #endif
149     MCAN_DEV_CNT,
150 };
151 
152 static hc32_mcan_driver_t m_mcan_driver_list[] =
153 {
154 #ifdef BSP_USING_MCAN1
155     {
156         {
157             .name = MCAN1_NAME,
158             .instance = CM_MCAN1,
159             .init_para = {.stcBitTime = MCAN1_BAUD_RATE_CFG},
160             .int0_sel = MCAN_INT0_SEL,
161             .int0_cfg = {BSP_MCAN1_INT0_IRQ_NUM, BSP_MCAN1_INT0_IRQ_PRIO, INT_SRC_MCAN1_INT0},
162             .int1_sel = MCAN_INT1_SEL,
163             .int1_cfg = {BSP_MCAN1_INT1_IRQ_NUM, BSP_MCAN1_INT0_IRQ_PRIO, INT_SRC_MCAN1_INT1},
164         }
165     },
166 #endif
167 #ifdef BSP_USING_MCAN2
168     {
169         {
170             .name = MCAN2_NAME,
171             .instance = CM_MCAN2,
172             .init_para = {.stcBitTime = MCAN2_BAUD_RATE_CFG},
173             .int0_sel = MCAN_INT0_SEL,
174             .int0_cfg = {BSP_MCAN2_INT0_IRQ_NUM, BSP_MCAN2_INT0_IRQ_PRIO, INT_SRC_MCAN2_INT0},
175             .int1_sel = MCAN_INT1_SEL,
176             .int1_cfg = {BSP_MCAN2_INT1_IRQ_NUM, BSP_MCAN2_INT1_IRQ_PRIO, INT_SRC_MCAN2_INT1},
177         }
178     },
179 #endif
180 };
181 
182 #ifdef BSP_USING_MCAN1
183     static stc_mcan_filter_t m_mcan1_std_filters[MCAN1_STD_FILTER_NUM];
184     static stc_mcan_filter_t m_mcan1_ext_filters[MCAN1_EXT_FILTER_NUM];
185 #endif
186 
187 #ifdef BSP_USING_MCAN2
188     static stc_mcan_filter_t m_mcan2_std_filters[MCAN2_STD_FILTER_NUM];
189     static stc_mcan_filter_t m_mcan2_ext_filters[MCAN2_EXT_FILTER_NUM];
190 #endif
191 
192 /****************************************************************************************
193 * Driver operations
194 ****************************************************************************************/
195 /**
196  * @brief Configure CAN controller
197  * @param [in/out] can CAN device pointer
198  * @param [in] cfg CAN configuration pointer
199  * @retval RT_EOK for valid configuration
200  * @retval -RT_ERROR for invalid configuration
201  */
202 static rt_err_t mcan_configure(struct rt_can_device *device, struct can_configure *cfg);
203 
204 /**
205  * @brief Control/Get CAN state
206  *        including:interrupt, mode, priority, baudrate, filter, status
207  * @param [in/out] can CAN device pointer
208  * @param [in] cmd Control command
209  * @param [in/out] arg Argument pointer
210  * @retval RT_EOK for valid control command and arg
211  * @retval -RT_ERROR for invalid control command or arg
212  */
213 static rt_err_t mcan_control(struct rt_can_device *device, int cmd, void *arg);
214 
215 /**
216  * @brief Send out CAN message
217  * @param [in] can CAN device pointer
218  * @param [in] buf CAN message buffer
219  * @param [in] boxno Mailbox number, it is not used in this porting
220  * @retval RT_EOK No error
221  * @retval -RT_ETIMEOUT timeout happened
222  * @retval -RT_EFULL Transmission buffer is full
223  */
224 static rt_ssize_t mcan_sendmsg(struct rt_can_device *device, const void *buf, rt_uint32_t boxno);
225 
226 /**
227  * @brief Receive message from CAN
228  * @param [in] can CAN device pointer
229  * @param [out] buf CAN receive buffer
230  * @param [in] boxno Mailbox Number, it is not used in this porting
231  * @retval RT_EOK no error
232  * @retval -RT_ERROR Error happened during reading receive FIFO
233  * @retval -RT_EMPTY no data in receive FIFO
234  */
235 static rt_ssize_t mcan_recvmsg(struct rt_can_device *device, void *buf, rt_uint32_t boxno);
236 
237 #ifdef RT_CAN_USING_CANFD
238     static void mcan_copy_bt_to_cfg(struct can_configure *cfg, const stc_mcan_bit_time_config_t *ll_bt);
239 #endif
240 
241 static const struct rt_can_ops m_mcan_ops =
242 {
243     mcan_configure,
244     mcan_control,
245     mcan_sendmsg,
246     mcan_recvmsg,
247 };
248 
249 /****************************************************************************************
250 * mcan configure
251 ****************************************************************************************/
mcan_configure(struct rt_can_device * device,struct can_configure * cfg)252 static rt_err_t mcan_configure(struct rt_can_device *device, struct can_configure *cfg)
253 {
254     rt_uint32_t i, len;
255     rt_err_t rt_ret = RT_EOK;
256     hc32_mcan_driver_t *driver;
257     hc32_mcan_config_t *hard;
258     stc_mcan_filter_t *std_filters, *ext_filters;
259 
260     RT_ASSERT(device);
261     RT_ASSERT(cfg);
262     driver = (hc32_mcan_driver_t *)device->parent.user_data;
263     RT_ASSERT(driver);
264     hard = &driver->mcan;
265 
266     RT_ASSERT(IS_RT_CAN_WORK_MODE(cfg->mode));
267     RT_ASSERT(IS_RT_CAN_PRIV_MODE(cfg->privmode));
268 
269     hard->init_para.u32Mode = m_mcan_work_mode[cfg->mode];
270     hard->init_para.u32FrameFormat = MCAN_FRAME_CLASSIC;
271     hard->init_para.stcMsgRam.u32TxFifoQueueMode = m_mcan_tx_priv_mode[cfg->privmode];
272 #ifdef RT_CAN_USING_CANFD
273     RT_ASSERT(IS_MCAN_FD_MODE(cfg->enable_canfd));
274     hard->init_para.u32FrameFormat = m_mcan_fd_mode[cfg->enable_canfd];
275     if (cfg->use_bit_timing)
276     {
277         hard->init_para.stcBitTime.u32NominalPrescaler = cfg->can_timing.prescaler;
278         hard->init_para.stcBitTime.u32NominalTimeSeg1 = cfg->can_timing.num_seg1;
279         hard->init_para.stcBitTime.u32NominalTimeSeg2 = cfg->can_timing.num_seg2;
280         hard->init_para.stcBitTime.u32NominalSyncJumpWidth = cfg->can_timing.num_sjw;
281         if (cfg->use_bit_timing >= 2)
282         {
283             hard->init_para.stcBitTime.u32DataPrescaler = cfg->canfd_timing.prescaler;
284             hard->init_para.stcBitTime.u32DataTimeSeg1 = cfg->canfd_timing.num_seg1;
285             hard->init_para.stcBitTime.u32DataTimeSeg2 = cfg->canfd_timing.num_seg2;
286             hard->init_para.stcBitTime.u32DataSyncJumpWidth = cfg->canfd_timing.num_sjw;
287             hard->init_para.stcBitTime.u32SspOffset = cfg->canfd_timing.num_sspoff;
288         }
289         cfg->use_bit_timing = 0;
290     }
291     else
292     {
293         RT_ASSERT(IS_MCAN_NOMINAL_BAUD_RATE(cfg->baud_rate));
294         RT_ASSERT(IS_MCAN_DATA_BAUD_RATE(cfg->baud_rate_fd));
295 
296         len = sizeof(m_mcan_fd_baud_rate) / sizeof(m_mcan_fd_baud_rate[0]);
297         for (i = 0; i < len; i++)
298         {
299             if ((cfg->baud_rate == m_mcan_fd_baud_rate[i].baud_rate) && \
300                     (cfg->baud_rate_fd == m_mcan_fd_baud_rate[i].baud_rate_fd))
301             {
302                 hard->init_para.stcBitTime = m_mcan_fd_baud_rate[i].ll_bt;
303                 mcan_copy_bt_to_cfg(cfg, &m_mcan_fd_baud_rate[i].ll_bt);
304                 break;
305             }
306         }
307         if (i >= len)
308         {
309             rt_ret = -RT_ERROR;
310         }
311     }
312 #else
313     RT_ASSERT(IS_MCAN_CC_BAUD_RATE(cfg->baud_rate));
314     len = sizeof(m_mcan_cc_baud_rate) / sizeof(m_mcan_cc_baud_rate[0]);
315     for (i = 0; i < len; i++)
316     {
317         if (cfg->baud_rate == m_mcan_cc_baud_rate[i].baud_rate)
318         {
319             hard->init_para.stcBitTime = m_mcan_cc_baud_rate[i].ll_bt;
320             break;
321         }
322     }
323     if (i >= len)
324     {
325         rt_ret = -RT_ERROR;
326     }
327 #endif
328     if (rt_ret == RT_EOK)
329     {
330         std_filters = hard->init_para.stcFilter.pstcStdFilterList;
331         ext_filters = hard->init_para.stcFilter.pstcExtFilterList;
332         hard->init_para.stcFilter.pstcStdFilterList = NULL;
333         hard->init_para.stcFilter.pstcExtFilterList = NULL;
334         if (MCAN_Init(hard->instance, &hard->init_para) != LL_OK)
335         {
336             hard->init_para.stcFilter.pstcStdFilterList = std_filters;
337             hard->init_para.stcFilter.pstcExtFilterList = ext_filters;
338             return -RT_ERROR;
339         }
340     }
341 
342     hard->init_para.stcFilter.pstcStdFilterList = std_filters;
343     hard->init_para.stcFilter.pstcExtFilterList = ext_filters;
344     for (i = 0; i < hard->init_para.stcMsgRam.u32StdFilterNum; i++)
345     {
346         if (MCAN_FilterConfig(hard->instance, &hard->init_para.stcFilter.pstcStdFilterList[i]) != LL_OK)
347         {
348             return -RT_ERROR;
349         }
350     }
351 
352     for (i = 0; i < hard->init_para.stcMsgRam.u32ExtFilterNum; i++)
353     {
354         if (MCAN_FilterConfig(hard->instance, &hard->init_para.stcFilter.pstcExtFilterList[i]) != LL_OK)
355         {
356             return -RT_ERROR;
357         }
358     }
359 
360     struct can_configure pre_config = driver->can_device.config;
361     rt_memcpy(&driver->can_device.config, cfg, sizeof(struct can_configure));
362     /* restore unmodifiable member */
363     if ((driver->can_device.parent.open_flag & RT_DEVICE_OFLAG_OPEN) == RT_DEVICE_OFLAG_OPEN)
364     {
365         driver->can_device.config.msgboxsz = pre_config.msgboxsz;
366         driver->can_device.config.ticks = pre_config.ticks;
367     }
368 #ifdef RT_CAN_USING_HDR
369     driver->can_device.config.maxhdr = pre_config.maxhdr;
370 #endif
371     driver->can_device.config.sndboxnumber = pre_config.sndboxnumber;
372 
373     MCAN_Start(hard->instance);
374 
375     return RT_EOK;
376 }
377 
378 /****************************************************************************************
379 * mcan control
380 ****************************************************************************************/
mcan_control_set_int(hc32_mcan_driver_t * driver,int cmd,void * arg)381 static void mcan_control_set_int(hc32_mcan_driver_t *driver, int cmd, void *arg)
382 {
383     en_functional_state_t new_state = DISABLE;
384     rt_uint32_t int_flag = (rt_uint32_t)arg;
385     hc32_mcan_config_t *hard = &driver->mcan;
386     rt_uint32_t tmp;
387 
388     if (cmd == RT_DEVICE_CTRL_SET_INT)
389     {
390         new_state = ENABLE;
391     }
392     switch (int_flag)
393     {
394     case RT_DEVICE_FLAG_INT_RX:
395         if (MCAN_RX_INT & hard->int0_sel)
396         {
397             MCAN_IntCmd(hard->instance, MCAN_RX_INT & hard->int0_sel, MCAN_INT_LINE0, new_state);
398         }
399         if (MCAN_RX_INT & hard->int1_sel)
400         {
401             MCAN_IntCmd(hard->instance, MCAN_RX_INT & hard->int1_sel, MCAN_INT_LINE1, new_state);
402         }
403         break;
404     case RT_DEVICE_FLAG_INT_TX:
405         tmp = hard->init_para.stcMsgRam.u32TxBufferNum + hard->init_para.stcMsgRam.u32TxFifoQueueNum;
406         if (tmp >= 32)
407         {
408             tmp = 0xFFFFFFFF;
409         }
410         else
411         {
412             tmp = (1UL << tmp) - 1;
413         }
414         MCAN_TxBufferNotificationCmd(hard->instance, tmp, MCAN_INT_TX_CPLT, ENABLE);
415 
416         if (MCAN_TX_INT & hard->int0_sel)
417         {
418             MCAN_IntCmd(hard->instance, MCAN_TX_INT & hard->int0_sel, MCAN_INT_LINE0, new_state);
419         }
420         if (MCAN_TX_INT & hard->int1_sel)
421         {
422             MCAN_IntCmd(hard->instance, MCAN_TX_INT & hard->int1_sel, MCAN_INT_LINE1, new_state);
423         }
424         break;
425     case RT_DEVICE_CAN_INT_ERR:
426         if (MCAN_ERR_INT & hard->int0_sel)
427         {
428             MCAN_IntCmd(hard->instance, MCAN_ERR_INT & hard->int0_sel, MCAN_INT_LINE0, new_state);
429         }
430         if (MCAN_ERR_INT & hard->int1_sel)
431         {
432             MCAN_IntCmd(hard->instance, MCAN_ERR_INT & hard->int1_sel, MCAN_INT_LINE1, new_state);
433         }
434         break;
435     default:
436         break;
437     }
438 }
439 
mcan_control_set_filter(hc32_mcan_driver_t * driver,int cmd,void * arg)440 static rt_err_t mcan_control_set_filter(hc32_mcan_driver_t *driver, int cmd, void *arg)
441 {
442     rt_uint8_t sf_default_idx = 0, ef_default_idx = 0;
443     stc_mcan_filter_t ll_filter;
444     hc32_mcan_config_t *hard = &driver->mcan;
445     struct rt_can_filter_config *device_filter = (struct rt_can_filter_config *)arg;
446 
447     for (int i = 0; i < device_filter->count; i++)
448     {
449         RT_ASSERT(IS_CAN_VALID_ID(device_filter->items[i].ide, device_filter->items[i].id));
450         RT_ASSERT((device_filter->items[i].rxfifo == CAN_RX_FIFO0) || (device_filter->items[i].rxfifo == CAN_RX_FIFO1));
451         if (device_filter->items[i].rxfifo == CAN_RX_FIFO1)
452         {
453             RT_ASSERT(hard->init_para.stcMsgRam.u32RxFifo1Num > 0);
454         }
455 
456         /* rt filter mode: 0 - list; 1 - mask  */
457         static const rt_uint32_t mcan_filter_type[] = {MCAN_FILTER_RANGE, MCAN_FILTER_MASK};
458         static const rt_uint32_t mcan_filter_config[] = {MCAN_FILTER_TO_RX_FIFO0, MCAN_FILTER_TO_RX_FIFO1};
459         /* rt CAN filter to MCAN LL driver filter */
460         ll_filter.u32IdType       = device_filter->items[i].ide;
461         ll_filter.u32FilterType   = mcan_filter_type[device_filter->items[i].mode];
462         ll_filter.u32FilterConfig = mcan_filter_config[device_filter->items[i].rxfifo];
463         ll_filter.u32FilterId1    = device_filter->items[i].id;
464         ll_filter.u32FilterId2    = device_filter->items[i].mask;
465 
466         if (device_filter->items[i].ide == RT_CAN_STDID)
467         {
468             ll_filter.u32FilterId1 &= MCAN_STD_ID_MASK;
469             ll_filter.u32FilterId2 &= MCAN_STD_ID_MASK;
470             if (device_filter->items[i].hdr_bank == -1)
471             {
472                 ll_filter.u32FilterIndex = sf_default_idx;
473                 sf_default_idx++;
474             }
475             else
476             {
477                 ll_filter.u32FilterIndex = device_filter->items[i].hdr_bank;
478             }
479             RT_ASSERT(ll_filter.u32FilterIndex < hard->init_para.stcMsgRam.u32StdFilterNum);
480             hard->init_para.stcFilter.pstcStdFilterList[ll_filter.u32FilterIndex] = ll_filter;
481         }
482         else
483         {
484             ll_filter.u32FilterId1 &= MCAN_EXT_ID_MASK;
485             ll_filter.u32FilterId2 &= MCAN_EXT_ID_MASK;
486             if (device_filter->items[i].hdr_bank == -1)
487             {
488                 ll_filter.u32FilterIndex = ef_default_idx;
489                 ef_default_idx++;
490             }
491             else
492             {
493                 ll_filter.u32FilterIndex = device_filter->items[i].hdr_bank;
494             }
495             RT_ASSERT(ll_filter.u32FilterIndex < hard->init_para.stcMsgRam.u32ExtFilterNum);
496             hard->init_para.stcFilter.pstcExtFilterList[ll_filter.u32FilterIndex] = ll_filter;
497         }
498     }
499 
500     return RT_EOK;
501 }
502 
mcan_control_set_mode(hc32_mcan_driver_t * driver,int cmd,void * arg,struct can_configure * cfg)503 static rt_err_t mcan_control_set_mode(hc32_mcan_driver_t *driver, int cmd, void *arg, struct can_configure *cfg)
504 {
505     rt_uint32_t argval = (rt_uint32_t)arg;
506 
507     (void)cmd;
508     RT_ASSERT(IS_RT_CAN_WORK_MODE(argval));
509     if (!IS_RT_CAN_WORK_MODE(argval))
510     {
511         return -RT_ERROR;
512     }
513     if (argval == driver->can_device.config.mode)
514     {
515         return RT_EOK;
516     }
517     cfg->mode = argval;
518     return RT_EOK;
519 }
520 
mcan_control_set_priv(hc32_mcan_driver_t * driver,int cmd,void * arg,struct can_configure * cfg)521 static rt_err_t mcan_control_set_priv(hc32_mcan_driver_t *driver, int cmd, void *arg, struct can_configure *cfg)
522 {
523     rt_uint32_t argval = (rt_uint32_t)arg;
524 
525     (void)cmd;
526     RT_ASSERT(IS_RT_CAN_PRIV_MODE(argval));
527     if (!IS_RT_CAN_PRIV_MODE(argval))
528     {
529         return -RT_ERROR;
530     }
531     if (argval == driver->can_device.config.privmode)
532     {
533         return RT_EOK;
534     }
535     cfg->privmode = argval;
536     return RT_EOK;
537 }
538 
539 #ifdef RT_CAN_USING_CANFD
mcan_copy_bt_to_cfg(struct can_configure * cfg,const stc_mcan_bit_time_config_t * ll_bt)540 static void mcan_copy_bt_to_cfg(struct can_configure *cfg, const stc_mcan_bit_time_config_t *ll_bt)
541 {
542     cfg->can_timing.prescaler = ll_bt->u32NominalPrescaler;
543     cfg->can_timing.num_seg1 = ll_bt->u32NominalTimeSeg1;
544     cfg->can_timing.num_seg2 = ll_bt->u32NominalTimeSeg2;
545     cfg->can_timing.num_sjw = ll_bt->u32NominalSyncJumpWidth;
546 
547     cfg->canfd_timing.prescaler = ll_bt->u32DataPrescaler;
548     cfg->canfd_timing.num_seg1 = ll_bt->u32DataTimeSeg1;
549     cfg->canfd_timing.num_seg2 = ll_bt->u32DataTimeSeg2;
550     cfg->canfd_timing.num_sjw = ll_bt->u32DataSyncJumpWidth;
551     cfg->canfd_timing.num_sspoff = ll_bt->u32SspOffset;
552 }
553 #endif
554 
mcan_control_set_fd(hc32_mcan_driver_t * driver,int cmd,void * arg,struct can_configure * cfg)555 static rt_err_t mcan_control_set_fd(hc32_mcan_driver_t *driver, int cmd, void *arg, struct can_configure *cfg)
556 {
557     rt_uint32_t i, len;
558     rt_uint32_t argval = (rt_uint32_t)arg;
559 #ifdef RT_CAN_USING_CANFD
560     struct rt_can_bit_timing_config *timing_configs = NULL;
561 #endif
562     switch (cmd)
563     {
564 #ifdef RT_CAN_USING_CANFD
565     case RT_CAN_CMD_SET_BAUD:
566     default:
567         RT_ASSERT(IS_MCAN_NOMINAL_BAUD_RATE(argval));
568         if (!IS_MCAN_NOMINAL_BAUD_RATE(argval))
569         {
570             return -RT_ERROR;
571         }
572         if (driver->can_device.config.baud_rate == argval)
573         {
574             return RT_EOK;
575         }
576         len = sizeof(m_mcan_fd_baud_rate) / sizeof(m_mcan_fd_baud_rate[0]);
577         for (i = 0; i < len; i++)
578         {
579             if ((argval == m_mcan_fd_baud_rate[i].baud_rate) && \
580                     (driver->can_device.config.baud_rate_fd == m_mcan_fd_baud_rate[i].baud_rate_fd))
581             {
582                 cfg->baud_rate = argval;
583                 cfg->baud_rate_fd = driver->can_device.config.baud_rate_fd;
584                 mcan_copy_bt_to_cfg(cfg, &m_mcan_fd_baud_rate[i].ll_bt);
585                 return RT_EOK;
586             }
587         }
588         return -RT_ERROR;
589 
590     case RT_CAN_CMD_SET_BAUD_FD:
591         RT_ASSERT(IS_MCAN_DATA_BAUD_RATE(argval));
592         if (!IS_MCAN_DATA_BAUD_RATE(argval))
593         {
594             return -RT_ERROR;
595         }
596         if (driver->can_device.config.baud_rate_fd == argval)
597         {
598             return RT_EOK;
599         }
600         len = sizeof(m_mcan_fd_baud_rate) / sizeof(m_mcan_fd_baud_rate[0]);
601         for (i = 0; i < len; i++)
602         {
603             if ((argval == m_mcan_fd_baud_rate[i].baud_rate_fd) && \
604                     (driver->can_device.config.baud_rate == m_mcan_fd_baud_rate[i].baud_rate))
605             {
606                 cfg->baud_rate_fd = argval;
607                 cfg->baud_rate = driver->can_device.config.baud_rate;
608                 mcan_copy_bt_to_cfg(cfg, &m_mcan_fd_baud_rate[i].ll_bt);
609                 return RT_EOK;
610             }
611         }
612         return -RT_ERROR;
613 
614     case RT_CAN_CMD_SET_BITTIMING:
615         timing_configs = (struct rt_can_bit_timing_config *)arg;
616         RT_ASSERT(timing_configs != RT_NULL);
617         RT_ASSERT(timing_configs->count == 1 || timing_configs->count == 2);
618         if ((timing_configs == NULL) || ((timing_configs->count != 1) && (timing_configs->count != 2)))
619         {
620             return -RT_ERROR;
621         }
622         cfg->can_timing = timing_configs->items[0];
623         if (timing_configs->count == 2)
624         {
625             cfg->canfd_timing = timing_configs->items[1];
626         }
627         cfg->use_bit_timing = timing_configs->count;
628         return RT_EOK;
629 
630     case RT_CAN_CMD_SET_CANFD:
631         RT_ASSERT(IS_MCAN_FD_MODE(argval));
632         if (!IS_MCAN_FD_MODE(argval))
633         {
634             return -RT_ERROR;
635         }
636         if (argval == driver->can_device.config.enable_canfd)
637         {
638             return RT_EOK;
639         }
640         cfg->enable_canfd = argval;
641         return RT_EOK;
642 #else
643     case RT_CAN_CMD_SET_BAUD:
644         RT_ASSERT(IS_MCAN_CC_BAUD_RATE(argval));
645         if (!IS_MCAN_CC_BAUD_RATE(argval))
646         {
647             return -RT_ERROR;
648         }
649         if (argval == driver->can_device.config.baud_rate)
650         {
651             return RT_EOK;
652         }
653 
654         len = sizeof(m_mcan_cc_baud_rate) / sizeof(m_mcan_cc_baud_rate[0]);
655         for (i = 0; i < len; i++)
656         {
657             if (argval == m_mcan_cc_baud_rate[i].baud_rate)
658             {
659                 cfg->baud_rate = argval;
660                 return RT_EOK;
661             }
662         }
663         return -RT_ERROR;
664     default:
665         return -RT_ERROR;
666 #endif
667     }
668 }
669 
mcan_control_get_status(hc32_mcan_driver_t * driver,int cmd,void * arg)670 static void mcan_control_get_status(hc32_mcan_driver_t *driver, int cmd, void *arg)
671 {
672     stc_mcan_protocol_status_t mcan_st;
673     stc_mcan_error_counter_t mcan_err;
674     struct rt_can_status *rt_can_stat = (struct rt_can_status *)arg;
675 
676     MCAN_GetProtocolStatus(driver->mcan.instance, &mcan_st);
677     MCAN_GetErrorCounter(driver->mcan.instance, &mcan_err);
678     rt_can_stat->rcverrcnt = mcan_err.u8RxErrorCount;
679     rt_can_stat->snderrcnt = mcan_err.u8TxErrorCount;
680     rt_can_stat->lasterrtype = mcan_st.u8LastErrorCode;
681     rt_can_stat->errcode = mcan_st.u8LastErrorCode;
682 }
683 
mcan_control(struct rt_can_device * device,int cmd,void * arg)684 static rt_err_t mcan_control(struct rt_can_device *device, int cmd, void *arg)
685 {
686     rt_err_t rt_ret = -RT_ERROR;
687     struct can_configure new_cfg;
688     hc32_mcan_driver_t *driver;
689     RT_ASSERT(device);
690     driver = (hc32_mcan_driver_t *)device->parent.user_data;
691     RT_ASSERT(driver);
692 
693     new_cfg = device->config;
694 
695     switch (cmd)
696     {
697     case RT_DEVICE_CTRL_SET_INT:
698     case RT_DEVICE_CTRL_CLR_INT:
699         mcan_control_set_int(driver, cmd, arg);
700         return RT_EOK;
701 
702 #if defined(RT_CAN_USING_HDR)
703     case RT_CAN_CMD_SET_FILTER:
704         rt_ret = mcan_control_set_filter(driver, cmd, arg);
705         break;
706 #endif
707     case RT_CAN_CMD_SET_MODE:
708         rt_ret = mcan_control_set_mode(driver, cmd, arg, &new_cfg);
709         break;
710 
711     case RT_CAN_CMD_SET_PRIV:
712         rt_ret = mcan_control_set_priv(driver, cmd, arg, &new_cfg);
713         break;
714 
715     case RT_CAN_CMD_SET_BAUD:
716 #ifdef RT_CAN_USING_CANFD
717     case RT_CAN_CMD_SET_CANFD:
718     case RT_CAN_CMD_SET_BAUD_FD:
719     case RT_CAN_CMD_SET_BITTIMING:
720 #endif
721         rt_ret = mcan_control_set_fd(driver, cmd, arg, &new_cfg);
722         break;
723 
724     case RT_CAN_CMD_GET_STATUS:
725         mcan_control_get_status(driver, cmd, arg);
726         return RT_EOK;
727 
728     default:
729         return -RT_EINVAL;
730     }
731 
732     if (rt_ret == RT_EOK)
733     {
734         rt_ret = mcan_configure(device, &new_cfg);
735     }
736 
737     return rt_ret;
738 }
739 
740 /****************************************************************************************
741 * mcan send message
742 ****************************************************************************************/
mcan_sendmsg(struct rt_can_device * device,const void * buf,rt_uint32_t boxno)743 static rt_ssize_t mcan_sendmsg(struct rt_can_device *device, const void *buf, rt_uint32_t boxno)
744 {
745     hc32_mcan_driver_t *driver;
746     hc32_mcan_config_t *hard;
747     stc_mcan_tx_msg_t ll_tx_msg = {0};
748     struct rt_can_msg *tx_msg;
749 
750     RT_ASSERT(device);
751     driver = (hc32_mcan_driver_t *)device->parent.user_data;
752     RT_ASSERT(driver);
753     hard = &driver->mcan;
754 
755     driver->tx_box_num = boxno;
756 
757     RT_ASSERT(buf);
758     tx_msg = (struct rt_can_msg *)buf;
759 
760     /* Parameter validity check */
761     RT_ASSERT(IS_CAN_VALID_ID(tx_msg->ide, tx_msg->id));
762 #ifdef RT_CAN_USING_CANFD
763     RT_ASSERT(tx_msg->len <= MCAN_DLC64);
764 #else
765     RT_ASSERT(tx_msg->len <= MCAN_DLC8);
766 #endif
767 
768     /* rt CAN Tx message to MCAN LL driver Tx message */
769     ll_tx_msg.ID  = tx_msg->id;
770     ll_tx_msg.IDE = tx_msg->ide;
771     ll_tx_msg.RTR = tx_msg->rtr;
772     ll_tx_msg.DLC = tx_msg->len;
773 #ifdef RT_CAN_USING_CANFD
774     ll_tx_msg.FDF = tx_msg->fd_frame;
775     ll_tx_msg.BRS = tx_msg->brs;
776 #endif
777 
778     rt_memcpy(ll_tx_msg.au8Data, tx_msg->data, m_mcan_data_size[ll_tx_msg.DLC]);
779     if (MCAN_AddMsgToTxFifoQueue(hard->instance, &ll_tx_msg) != LL_OK)
780     {
781         return -RT_ERROR;
782     }
783     return RT_EOK;
784 }
785 
786 /****************************************************************************************
787 * mcan receive message
788 ****************************************************************************************/
mcan_recvmsg(struct rt_can_device * device,void * buf,rt_uint32_t boxno)789 static rt_ssize_t mcan_recvmsg(struct rt_can_device *device, void *buf, rt_uint32_t boxno)
790 {
791     hc32_mcan_driver_t *driver;
792     hc32_mcan_config_t *hard;
793     stc_mcan_rx_msg_t ll_rx_msg = {0};
794     struct rt_can_msg *rx_msg;
795     rt_uint32_t rx_location;
796 
797     RT_ASSERT(device);
798     driver = (hc32_mcan_driver_t *)device->parent.user_data;
799     RT_ASSERT(driver);
800     hard = &driver->mcan;
801 
802     RT_ASSERT(buf);
803     rx_msg = (struct rt_can_msg *)buf;
804 
805     if (boxno == CAN_RX_FIFO0)
806     {
807         rx_location = MCAN_RX_FIFO0;
808     }
809     else if (boxno == CAN_RX_FIFO1)
810     {
811         rx_location = MCAN_RX_FIFO1;
812     }
813     else
814     {
815         rx_location = boxno;
816     }
817     if (MCAN_GetRxMsg(hard->instance, rx_location, &ll_rx_msg) != LL_OK)
818     {
819         rt_kprintf("No available message in the specified RX location.\n");
820         return -(RT_ERROR);
821     }
822 
823     /* MCAN LL driver Rx message to rt CAN Rx message */
824     rx_msg->id   = ll_rx_msg.ID;
825     rx_msg->ide  = ll_rx_msg.IDE;
826     rx_msg->rtr  = ll_rx_msg.RTR;
827     rx_msg->len  = ll_rx_msg.u32DataSize;
828     rx_msg->priv = 0;
829 #ifdef RT_CAN_USING_HDR
830     /* Hardware filter messages are valid */
831     rx_msg->hdr_index = ll_rx_msg.u32FilterIndex;
832     device->hdr[rx_msg->hdr_index].connected = 1;
833 #endif
834 
835 #ifdef RT_CAN_USING_CANFD
836     rx_msg->fd_frame = ll_rx_msg.FDF;
837     rx_msg->brs      = ll_rx_msg.BRS;
838 #endif
839 
840     if (rx_msg->len > 0)
841     {
842         rt_memcpy(&rx_msg->data[0], &ll_rx_msg.au8Data[0], rx_msg->len);
843     }
844 
845     return RT_EOK;
846 }
847 
848 /****************************************************************************************
849 * mcan isr
850 ****************************************************************************************/
mcan_get_rx_buffer_num(rt_uint32_t new_data)851 static rt_uint32_t mcan_get_rx_buffer_num(rt_uint32_t new_data)
852 {
853     rt_uint32_t num = 0;
854     while (new_data)
855     {
856         new_data = new_data & (new_data - 1);
857         num++;
858     }
859     return num++;
860 }
861 
mcan_isr(hc32_mcan_driver_t * driver,uint32_t int_sel)862 rt_inline void mcan_isr(hc32_mcan_driver_t *driver, uint32_t int_sel)
863 {
864     struct rt_can_device *device = &driver->can_device;
865     CM_MCAN_TypeDef *MCANx = driver->mcan.instance;
866     uint32_t ir_status = MCANx->IR;
867     uint32_t psr = MCANx->PSR;
868     uint32_t ndat1 = MCANx->NDAT1;
869     uint32_t ndat2 = MCANx->NDAT2;
870     int rx_buf_index;
871 
872     MCAN_ClearStatus(MCANx, ir_status & int_sel);
873 
874     /* Check normal status flag */
875     /* Transmission completed */
876     if (ir_status & MCAN_FLAG_TX_CPLT)
877     {
878         rt_hw_can_isr(device, RT_CAN_EVENT_TX_DONE | (driver->tx_box_num << 8U));
879     }
880 
881     /* Rx FIFO0 new message */
882     if (ir_status & MCAN_FLAG_RX_FIFO0_NEW_MSG)
883     {
884         if (MCAN_GetRxFifoFillLevel(MCANx, MCAN_RX_FIFO0) <= 1)
885         {
886             MCAN_ClearStatus(MCANx, MCAN_FLAG_RX_FIFO0_NEW_MSG);
887         }
888         rt_hw_can_isr(device, RT_CAN_EVENT_RX_IND | (MCAN_RX_FIFO0 << 8));
889     }
890 
891     /* Rx FIFO1 new message */
892     if (ir_status & MCAN_FLAG_RX_FIFO1_NEW_MSG)
893     {
894         if (MCAN_GetRxFifoFillLevel(MCANx, MCAN_RX_FIFO1) <= 1)
895         {
896             MCAN_ClearStatus(MCANx, MCAN_FLAG_RX_FIFO1_NEW_MSG);
897         }
898         rt_hw_can_isr(device, RT_CAN_EVENT_RX_IND | (MCAN_RX_FIFO1 << 8));
899     }
900 
901     /* Rx Buffer new message */
902     if (ir_status & MCAN_FLAG_RX_BUF_NEW_MSG)
903     {
904         /* Set an invalid index. Then find out the first Rx buffer that received new message. */
905         rx_buf_index = -1;
906         if (ndat1 > 0)
907         {
908             rx_buf_index = __CLZ(__RBIT(ndat1));
909         }
910         else if (ndat2 > 0)
911         {
912             rx_buf_index = __CLZ(__RBIT(ndat2)) + 32;
913         }
914         else
915         {
916             /* rsvd */
917         }
918         ndat1 = mcan_get_rx_buffer_num(ndat1);
919         ndat2 = mcan_get_rx_buffer_num(ndat2);
920         if ((ndat1 + ndat2) <= 1)
921         {
922             MCAN_ClearStatus(MCANx, MCAN_FLAG_RX_BUF_NEW_MSG);
923         }
924         rt_hw_can_isr(device, RT_CAN_EVENT_RX_IND | (rx_buf_index << 8));
925     }
926 
927     /* Rx FIFO0 lost message, handle as rx overflow */
928     if (ir_status & MCAN_FLAG_RX_FIFO0_MSG_LOST)
929     {
930         rt_hw_can_isr(device, RT_CAN_EVENT_RXOF_IND | (MCAN_RX_FIFO0 << 8));
931     }
932 
933     /* Rx FIFO1 lost message, handle as rx overflow */
934     if (ir_status & MCAN_FLAG_RX_FIFO1_MSG_LOST)
935     {
936         rt_hw_can_isr(device, RT_CAN_EVENT_RXOF_IND | (MCAN_RX_FIFO1 << 8));
937     }
938 
939     /* Error occurred during transmitting. Handle as tx failure. */
940     if ((psr & MCAN_PSR_ACT) == MCAN_PSR_ACT)
941     {
942 #if defined(RT_CAN_USING_CANFD)
943         if (ir_status & (MCAN_FLAG_ARB_PHASE_ERROR | MCAN_FLAG_DATA_PHASE_ERROR))
944         {
945             rt_hw_can_isr(device, RT_CAN_EVENT_TX_FAIL | (driver->tx_box_num << 8U));
946         }
947 #else
948         if (ir_status & MCAN_FLAG_ARB_PHASE_ERROR)
949         {
950             rt_hw_can_isr(device, RT_CAN_EVENT_TX_FAIL | (driver->tx_box_num << 8U));
951         }
952 #endif
953     }
954 
955     /* Check bus-off status flag */
956     if (psr & MCAN_PSR_BO)
957     {
958         /* The node is in bus-off state. */
959         /* If the device goes Bus_Off, it will set CCCR.INIT of its own accord, stopping all bus activities.
960            The application should clear CCCR.INIT, then the device can resume normal operation.
961            Once CCCR.INIT has been cleared by the CPU, the device will then wait for 129 occurrences of
962            Bus Idle(129 * 11 consecutive recessive bits) before resuming normal operation. */
963         MCAN_Start(MCANx);
964     }
965 }
966 
967 /****************************************************************************************
968 * mcan irq handler
969 ****************************************************************************************/
970 #if defined(HC32F448) || defined(HC32F4A8)
971 #if defined(BSP_USING_MCAN1)
MCAN1_INT0_Handler(void)972 void MCAN1_INT0_Handler(void)
973 {
974     /* enter interrupt */
975     rt_interrupt_enter();
976 
977     mcan_isr(&m_mcan_driver_list[MCAN1_INDEX], m_mcan_driver_list[MCAN1_INDEX].mcan.int0_sel);
978 
979     /* leave interrupt */
980     rt_interrupt_leave();
981 }
982 
MCAN1_INT1_Handler(void)983 void MCAN1_INT1_Handler(void)
984 {
985     /* enter interrupt */
986     rt_interrupt_enter();
987 
988     mcan_isr(&m_mcan_driver_list[MCAN1_INDEX], m_mcan_driver_list[MCAN1_INDEX].mcan.int1_sel);
989 
990     /* leave interrupt */
991     rt_interrupt_leave();
992 }
993 #endif /* #if defined(BSP_USING_MCAN1) */
994 
995 #if defined(BSP_USING_MCAN2)
MCAN2_INT0_Handler(void)996 void MCAN2_INT0_Handler(void)
997 {
998     /* enter interrupt */
999     rt_interrupt_enter();
1000 
1001     mcan_isr(&m_mcan_driver_list[MCAN2_INDEX], m_mcan_driver_list[MCAN2_INDEX].mcan.int0_sel);
1002 
1003     /* leave interrupt */
1004     rt_interrupt_leave();
1005 }
1006 
MCAN2_INT1_Handler(void)1007 void MCAN2_INT1_Handler(void)
1008 {
1009     /* enter interrupt */
1010     rt_interrupt_enter();
1011 
1012     mcan_isr(&m_mcan_driver_list[MCAN2_INDEX], m_mcan_driver_list[MCAN2_INDEX].mcan.int1_sel);
1013 
1014     /* leave interrupt */
1015     rt_interrupt_leave();
1016 }
1017 #endif /* #if defined(BSP_USING_MCAN2) */
1018 #endif
1019 
1020 /****************************************************************************************
1021 * mcan initialization configurations
1022 ****************************************************************************************/
mcan_irq_config(hc32_mcan_config_t * hard)1023 static void mcan_irq_config(hc32_mcan_config_t *hard)
1024 {
1025 #if defined(HC32F448)
1026     if (hard->int0_sel != 0)
1027     {
1028         INTC_IntSrcCmd(hard->int0_cfg.int_src, ENABLE);
1029 
1030         NVIC_ClearPendingIRQ(hard->int0_cfg.irq_num);
1031         NVIC_SetPriority(hard->int0_cfg.irq_num, hard->int0_cfg.irq_prio);
1032         NVIC_EnableIRQ(hard->int0_cfg.irq_num);
1033     }
1034 
1035     if (hard->int1_sel != 0)
1036     {
1037         INTC_IntSrcCmd(hard->int1_cfg.int_src, ENABLE);
1038 
1039         NVIC_ClearPendingIRQ(hard->int1_cfg.irq_num);
1040         NVIC_SetPriority(hard->int1_cfg.irq_num, hard->int1_cfg.irq_prio);
1041         NVIC_EnableIRQ(hard->int1_cfg.irq_num);
1042     }
1043 #elif defined(HC32F4A8)
1044     if (hard->int0_sel != 0)
1045     {
1046         hc32_install_irq_handler(&hard->int0_cfg, hard->irq_callback0, RT_TRUE);
1047     }
1048     if (hard->int1_sel != 0)
1049     {
1050         hc32_install_irq_handler(&hard->int1_cfg, hard->irq_callback1, RT_TRUE);
1051     }
1052 #endif
1053 }
1054 
mcan_enable_periph_clock(void)1055 static void mcan_enable_periph_clock(void)
1056 {
1057 #if defined(HC32F448) || defined(HC32F4A8)
1058 #if defined(BSP_USING_MCAN1)
1059     FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_MCAN1, ENABLE);
1060 #endif
1061 #if defined(BSP_USING_MCAN2)
1062     FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_MCAN2, ENABLE);
1063 #endif
1064 #endif
1065 
1066 #if defined(HC32F334)
1067 #if defined(BSP_USING_MCAN1) || defined(BSP_USING_MCAN2)
1068     FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_MCAN1 | FCG1_PERIPH_MCAN2, ENABLE);
1069 #endif
1070 #endif
1071 }
1072 
mcan_set_init_para(void)1073 static void mcan_set_init_para(void)
1074 {
1075     struct rt_can_device *device;
1076     stc_mcan_init_t *hard_init;
1077 
1078 #if defined(BSP_USING_MCAN1)
1079     device = &m_mcan_driver_list[MCAN1_INDEX].can_device;
1080     hard_init = &m_mcan_driver_list[MCAN1_INDEX].mcan.init_para;
1081     device->config.mode = MCAN1_WORK_MODE;
1082     device->config.privmode = MCAN1_TX_PRIV_MODE;
1083     device->config.baud_rate = MCAN1_NOMINAL_BAUD_RATE;
1084 #if defined(RT_CAN_USING_HDR)
1085     device->config.maxhdr = MCAN_TOTAL_FILTER_NUM;
1086 #endif
1087 #if defined(RT_CAN_USING_CANFD)
1088     device->config.baud_rate_fd = MCAN1_DATA_BAUD_RATE;
1089     device->config.enable_canfd = MCAN1_FD_SEL;
1090     hard_init->u32FrameFormat = m_mcan_fd_mode[MCAN1_FD_SEL];
1091 #else
1092     hard_init->u32FrameFormat = MCAN_FRAME_CLASSIC;
1093 #endif
1094     hard_init->u32Mode              = m_mcan_work_mode[device->config.mode];
1095     hard_init->u32AutoRetx          = MCAN_AUTO_RETX_ENABLE;
1096     hard_init->u32TxPause           = MCAN_TX_PAUSE_DISABLE;
1097     hard_init->u32ProtocolException = MCAN_PROTOCOL_EXP_ENABLE;
1098     /* Message RAM */
1099     hard_init->stcMsgRam.u32AddrOffset        = 0U;
1100     hard_init->stcMsgRam.u32StdFilterNum      = MCAN1_STD_FILTER_NUM;
1101     hard_init->stcMsgRam.u32ExtFilterNum      = MCAN1_EXT_FILTER_NUM;
1102     hard_init->stcMsgRam.u32RxFifo0Num        = MCAN1_RX_FIFO0_NUM;
1103     hard_init->stcMsgRam.u32RxFifo0DataSize   = MCAN1_RX_FIFO0_DATA_FIELD_SIZE;
1104     hard_init->stcMsgRam.u32RxFifo1Num        = 0U;
1105     hard_init->stcMsgRam.u32RxFifo1DataSize   = 0U;
1106     hard_init->stcMsgRam.u32RxBufferNum       = 0U;
1107     hard_init->stcMsgRam.u32RxBufferDataSize  = 0U;
1108     hard_init->stcMsgRam.u32TxEventNum        = 0U;
1109     hard_init->stcMsgRam.u32TxBufferNum       = 0U;
1110     hard_init->stcMsgRam.u32TxFifoQueueNum    = MCAN1_TX_FIFO_NUM;
1111     hard_init->stcMsgRam.u32TxFifoQueueMode   = m_mcan_tx_priv_mode[device->config.privmode];
1112     hard_init->stcMsgRam.u32TxDataSize        = MCAN1_TX_FIFO_DATA_FIELD_SIZE;
1113     /* Acceptance filter */
1114     hard_init->stcFilter.pstcStdFilterList     = m_mcan1_std_filters;
1115     hard_init->stcFilter.pstcExtFilterList     = m_mcan1_ext_filters;
1116     hard_init->stcFilter.u32StdFilterConfigNum = hard_init->stcMsgRam.u32StdFilterNum;
1117     hard_init->stcFilter.u32ExtFilterConfigNum = hard_init->stcMsgRam.u32ExtFilterNum;
1118 #endif
1119 
1120 #if defined(BSP_USING_MCAN2)
1121     device = &m_mcan_driver_list[MCAN2_INDEX].can_device;
1122     hard_init = &m_mcan_driver_list[MCAN2_INDEX].mcan.init_para;
1123     device->config.mode = MCAN2_WORK_MODE;
1124     device->config.privmode = MCAN2_TX_PRIV_MODE;
1125     device->config.baud_rate = MCAN2_NOMINAL_BAUD_RATE;
1126 #if defined(RT_CAN_USING_HDR)
1127     device->config.maxhdr = MCAN_TOTAL_FILTER_NUM;
1128 #endif
1129 #if defined(RT_CAN_USING_CANFD)
1130     device->config.baud_rate_fd = MCAN2_DATA_BAUD_RATE;
1131     device->config.enable_canfd = MCAN2_FD_SEL;
1132     hard_init->u32FrameFormat = m_mcan_fd_mode[MCAN2_FD_SEL];
1133 #else
1134     hard_init->u32FrameFormat = MCAN_FRAME_CLASSIC;
1135 #endif
1136     hard_init->u32Mode              = m_mcan_work_mode[device->config.mode];
1137     hard_init->u32AutoRetx          = MCAN_AUTO_RETX_ENABLE;
1138     hard_init->u32TxPause           = MCAN_TX_PAUSE_DISABLE;
1139     hard_init->u32ProtocolException = MCAN_PROTOCOL_EXP_ENABLE;
1140     /* Message RAM */
1141     hard_init->stcMsgRam.u32AddrOffset        = 0U;
1142     hard_init->stcMsgRam.u32StdFilterNum      = MCAN2_STD_FILTER_NUM;
1143     hard_init->stcMsgRam.u32ExtFilterNum      = MCAN2_EXT_FILTER_NUM;
1144     hard_init->stcMsgRam.u32RxFifo0Num        = MCAN2_RX_FIFO0_NUM;
1145     hard_init->stcMsgRam.u32RxFifo0DataSize   = MCAN2_RX_FIFO0_DATA_FIELD_SIZE;
1146     hard_init->stcMsgRam.u32RxFifo1Num        = 0U;
1147     hard_init->stcMsgRam.u32RxFifo1DataSize   = 0U;
1148     hard_init->stcMsgRam.u32RxBufferNum       = 0U;
1149     hard_init->stcMsgRam.u32RxBufferDataSize  = 0U;
1150     hard_init->stcMsgRam.u32TxEventNum        = 0U;
1151     hard_init->stcMsgRam.u32TxBufferNum       = 0U;
1152     hard_init->stcMsgRam.u32TxFifoQueueNum    = MCAN2_TX_FIFO_NUM;
1153     hard_init->stcMsgRam.u32TxFifoQueueMode   = m_mcan_tx_priv_mode[device->config.privmode];
1154     hard_init->stcMsgRam.u32TxDataSize        = MCAN2_TX_FIFO_DATA_FIELD_SIZE;
1155     /* Acceptance filter */
1156     hard_init->stcFilter.pstcStdFilterList     = m_mcan2_std_filters;
1157     hard_init->stcFilter.pstcExtFilterList     = m_mcan2_ext_filters;
1158     hard_init->stcFilter.u32StdFilterConfigNum = hard_init->stcMsgRam.u32StdFilterNum;
1159     hard_init->stcFilter.u32ExtFilterConfigNum = hard_init->stcMsgRam.u32ExtFilterNum;
1160 #endif
1161 }
1162 
init_can_cfg(hc32_mcan_driver_t * driver)1163 static void init_can_cfg(hc32_mcan_driver_t *driver)
1164 {
1165     struct can_configure can_cfg = CANDEFAULTCONFIG;
1166 
1167     can_cfg.privmode = RT_CAN_MODE_NOPRIV;
1168     can_cfg.ticks = 50;
1169 #ifdef RT_CAN_USING_HDR
1170     can_cfg.maxhdr = MCAN_TOTAL_FILTER_NUM;
1171 #endif
1172 #ifdef RT_CAN_USING_CANFD
1173     can_cfg.baud_rate_fd = CANFD_DATA_BAUD_4M;
1174     can_cfg.enable_canfd = MCAN_FD_SEL;
1175 #endif
1176     can_cfg.sndboxnumber = MCAN_TX_FIFO_NUM;
1177     driver->can_device.config = can_cfg;
1178 }
1179 
1180 #if defined(HC32F4A8)
1181 /**
1182  * @brief  This function gets mcan irq handle.
1183  * @param  None
1184  * @retval None
1185  */
mcan_get_irq_callback(void)1186 static void mcan_get_irq_callback(void)
1187 {
1188 #ifdef BSP_USING_MCAN1
1189     m_mcan_driver_list[MCAN1_INDEX].mcan.irq_callback0 = MCAN1_INT0_Handler;
1190     m_mcan_driver_list[MCAN1_INDEX].mcan.irq_callback1 = MCAN1_INT1_Handler;
1191 #endif
1192 #ifdef BSP_USING_MCAN2
1193     m_mcan_driver_list[MCAN2_INDEX].mcan.irq_callback0 = MCAN2_INT0_Handler;
1194     m_mcan_driver_list[MCAN2_INDEX].mcan.irq_callback1 = MCAN2_INT1_Handler;
1195 #endif
1196 }
1197 #endif
1198 
1199 extern rt_err_t rt_hw_board_mcan_init(CM_MCAN_TypeDef *MCANx);
1200 extern void CanPhyEnable(void);
rt_hw_mcan_init(void)1201 static rt_err_t rt_hw_mcan_init(void)
1202 {
1203     rt_uint32_t i, filter;
1204     rt_uint32_t tx_boxnum;
1205     hc32_mcan_config_t *hard;
1206 
1207     mcan_enable_periph_clock();
1208     mcan_set_init_para();
1209 #if defined(HC32F4A8)
1210     mcan_get_irq_callback();
1211 #endif
1212     for (i = 0; i < MCAN_DEV_CNT; i++)
1213     {
1214         hard = &m_mcan_driver_list[i].mcan;
1215 
1216         for (filter = 0; filter < hard->init_para.stcMsgRam.u32StdFilterNum; filter++)
1217         {
1218             hard->init_para.stcFilter.pstcStdFilterList[filter].u32IdType = MCAN_STD_ID;
1219         }
1220         for (filter = 0; filter < hard->init_para.stcMsgRam.u32ExtFilterNum; filter++)
1221         {
1222             hard->init_para.stcFilter.pstcExtFilterList[filter].u32IdType = MCAN_EXT_ID;
1223         }
1224 
1225         /* MCAN IRQ configuration */
1226         mcan_irq_config(hard);
1227 
1228         MCAN_Init(hard->instance, &hard->init_para);
1229 
1230         tx_boxnum = hard->init_para.stcMsgRam.u32TxBufferNum + hard->init_para.stcMsgRam.u32TxFifoQueueNum;
1231         if (tx_boxnum >= 32)
1232         {
1233             tx_boxnum = 0xFFFFFFFF;
1234         }
1235         else
1236         {
1237             tx_boxnum = (1UL << tx_boxnum) - 1;
1238         }
1239 
1240         MCAN_TxBufferNotificationCmd(hard->instance, tx_boxnum, MCAN_INT_TX_CPLT, ENABLE);
1241         MCAN_IntCmd(hard->instance, hard->int0_sel, MCAN_INT_LINE0, ENABLE);
1242         MCAN_IntCmd(hard->instance, hard->int1_sel, MCAN_INT_LINE1, ENABLE);
1243 
1244         if (i > 0)
1245         {
1246             hard->init_para.stcMsgRam.u32AddrOffset = \
1247                     m_mcan_driver_list[i - 1].mcan.init_para.stcMsgRam.u32AddrOffset + \
1248                     m_mcan_driver_list[i - 1].mcan.init_para.stcMsgRam.u32AllocatedSize;
1249         }
1250 
1251         init_can_cfg(&m_mcan_driver_list[i]);
1252 
1253         /* GPIO initialization */
1254         rt_hw_board_mcan_init(hard->instance);
1255 
1256         /* Register CAN device */
1257         rt_hw_can_register(&m_mcan_driver_list[i].can_device,
1258                            hard->name,
1259                            &m_mcan_ops,
1260                            &m_mcan_driver_list[i]);
1261     }
1262 
1263     /* Onboard CAN transceiver enable */
1264     CanPhyEnable();
1265 
1266     return RT_EOK;
1267 }
1268 
1269 INIT_DEVICE_EXPORT(rt_hw_mcan_init);
1270 #endif
1271 
1272 #endif /* BSP_USING_MCAN */
1273 
1274 /************************** end of file ******************/
1275 
1276