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