drv_mcan.c 42 KB

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