drv_canfd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2022-4-27 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_CANFD)
  14. #include <rtdevice.h>
  15. #include <rthw.h>
  16. #include "NuMicro.h"
  17. #include "nu_bitutil.h"
  18. #define LOG_TAG "drv.canfd"
  19. #undef DBG_ENABLE
  20. #define DBG_SECTION_NAME LOG_TAG
  21. #define DBG_LEVEL LOG_LVL_ERROR
  22. #define DBG_COLOR
  23. #include <rtdbg.h>
  24. /* Private Define ---------------------------------------------------------------*/
  25. #define IS_CAN_STDID(STDID) ((STDID) <= 0x7FFU)
  26. #define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
  27. #define IS_CAN_DLC(DLC) ((DLC) <= 8U)
  28. /* Default config for serial_configure structure */
  29. #define NU_CANFD_CONFIG_DEFAULT \
  30. { \
  31. CAN1MBaud, /* 1M bits/s */ \
  32. RT_CANMSG_BOX_SZ, /* message box max size */ \
  33. RT_CANSND_BOX_NUM, /* message box number */ \
  34. RT_CAN_MODE_NORMAL, /* Normal mode */ \
  35. 0, /* privmode */ \
  36. 0, /* reserved */ \
  37. 100, /* Timeout Tick */ \
  38. }
  39. enum
  40. {
  41. CANFD_START = -1,
  42. #if defined(BSP_USING_CANFD0)
  43. CANFD0_IDX,
  44. #endif
  45. #if defined(BSP_USING_CANFD1)
  46. CANFD1_IDX,
  47. #endif
  48. #if defined(BSP_USING_CANFD2)
  49. CANFD2_IDX,
  50. #endif
  51. #if defined(BSP_USING_CANFD3)
  52. CANFD3_IDX,
  53. #endif
  54. CANFD_CNT
  55. };
  56. /* Private Typedef --------------------------------------------------------------*/
  57. struct nu_canfd
  58. {
  59. struct rt_can_device dev;
  60. char *name;
  61. CANFD_T *base;
  62. uint32_t rstidx;
  63. IRQn_Type irqn0;
  64. IRQn_Type irqn1;
  65. uint32_t int_flag;
  66. CANFD_FD_T sCANFD_Config;
  67. };
  68. typedef struct nu_canfd *nu_canfd_t;
  69. /* Private functions ------------------------------------------------------------*/
  70. static rt_err_t nu_canfd_configure(struct rt_can_device *can, struct can_configure *cfg);
  71. static rt_err_t nu_canfd_control(struct rt_can_device *can, int cmd, void *arg);
  72. static int nu_canfd_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno);
  73. static int nu_canfd_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
  74. static void nu_canfd_isr(nu_canfd_t can);
  75. static struct nu_canfd nu_canfd_arr[] =
  76. {
  77. #if defined(BSP_USING_CANFD0)
  78. {
  79. .name = "canfd0",
  80. .base = CANFD0,
  81. .rstidx = CANFD0_RST,
  82. .irqn0 = CANFD00_IRQn,
  83. .irqn1 = CANFD01_IRQn,
  84. },
  85. #endif
  86. #if defined(BSP_USING_CANFD1)
  87. {
  88. .name = "canfd1",
  89. .base = CANFD1,
  90. .rstidx = CANFD1_RST,
  91. .irqn0 = CANFD10_IRQn,
  92. .irqn1 = CANFD11_IRQn,
  93. },
  94. #endif
  95. #if defined(BSP_USING_CANFD2)
  96. {
  97. .name = "canfd2",
  98. .base = CANFD2,
  99. .rstidx = CANFD2_RST,
  100. .irqn0 = CANFD20_IRQn,
  101. .irqn1 = CANFD21_IRQn,
  102. },
  103. #endif
  104. #if defined(BSP_USING_CANFD3)
  105. {
  106. .name = "canfd3",
  107. .base = CANFD3,
  108. .rstidx = CANFD3_RST,
  109. .irqn0 = CANFD30_IRQn,
  110. .irqn1 = CANFD31_IRQn,
  111. },
  112. #endif
  113. }; /* struct nu_can */
  114. /* Public functions ------------------------------------------------------------*/
  115. /* Private variables ------------------------------------------------------------*/
  116. static const struct rt_can_ops nu_canfd_ops =
  117. {
  118. .configure = nu_canfd_configure,
  119. .control = nu_canfd_control,
  120. .sendmsg = nu_canfd_sendmsg,
  121. .recvmsg = nu_canfd_recvmsg,
  122. };
  123. static const struct can_configure nu_canfd_default_config = NU_CANFD_CONFIG_DEFAULT;
  124. /* Interrupt Handle Function ----------------------------------------------------*/
  125. #if defined(BSP_USING_CANFD0)
  126. /* CAN0 interrupt entry */
  127. void CANFD00_IRQHandler(void)
  128. {
  129. /* enter interrupt */
  130. rt_interrupt_enter();
  131. nu_canfd_isr(&nu_canfd_arr[CANFD0_IDX]);
  132. /* leave interrupt */
  133. rt_interrupt_leave();
  134. }
  135. void CANFD01_IRQHandler(void)
  136. {
  137. /* enter interrupt */
  138. rt_interrupt_enter();
  139. nu_canfd_isr(&nu_canfd_arr[CANFD0_IDX]);
  140. /* leave interrupt */
  141. rt_interrupt_leave();
  142. }
  143. #endif
  144. #if defined(BSP_USING_CANFD1)
  145. void CANFD10_IRQHandler(void)
  146. {
  147. /* enter interrupt */
  148. rt_interrupt_enter();
  149. nu_canfd_isr(&nu_canfd_arr[CANFD1_IDX]);
  150. /* leave interrupt */
  151. rt_interrupt_leave();
  152. }
  153. void CANFD11_IRQHandler(void)
  154. {
  155. /* enter interrupt */
  156. rt_interrupt_enter();
  157. nu_canfd_isr(&nu_canfd_arr[CANFD1_IDX]);
  158. /* leave interrupt */
  159. rt_interrupt_leave();
  160. }
  161. #endif
  162. #if defined(BSP_USING_CANFD2)
  163. void CANFD20_IRQHandler(void)
  164. {
  165. /* enter interrupt */
  166. rt_interrupt_enter();
  167. nu_canfd_isr(&nu_canfd_arr[CANFD2_IDX]);
  168. /* leave interrupt */
  169. rt_interrupt_leave();
  170. }
  171. void CANFD21_IRQHandler(void)
  172. {
  173. /* enter interrupt */
  174. rt_interrupt_enter();
  175. nu_canfd_isr(&nu_canfd_arr[CANFD2_IDX]);
  176. /* leave interrupt */
  177. rt_interrupt_leave();
  178. }
  179. #endif
  180. #if defined(BSP_USING_CANFD3)
  181. void CANFD30_IRQHandler(void)
  182. {
  183. /* enter interrupt */
  184. rt_interrupt_enter();
  185. nu_canfd_isr(&nu_canfd_arr[CANFD3_IDX]);
  186. /* leave interrupt */
  187. rt_interrupt_leave();
  188. }
  189. void CANFD31_IRQHandler(void)
  190. {
  191. /* enter interrupt */
  192. rt_interrupt_enter();
  193. nu_canfd_isr(&nu_canfd_arr[CANFD3_IDX]);
  194. /* leave interrupt */
  195. rt_interrupt_leave();
  196. }
  197. #endif
  198. /* Private Variables ------------------------------------------------------------*/
  199. const char *szIR[] =
  200. {
  201. "CANFD_IR_RF0N - Rx FIFO 0 New Message",
  202. "CANFD_IR_RF0W - Rx FIFO 0 Watermark Reached",
  203. "CANFD_IR_RF0F - Rx FIFO 0 Full",
  204. "CANFD_IR_RF0L - Rx FIFO 0 Message Lost",
  205. "CANFD_IR_RF1N - Rx FIFO 1 New Message",
  206. "CANFD_IR_RF1W - Rx FIFO 1 Watermark Reached",
  207. "CANFD_IR_RF1F - Rx FIFO 1 Full",
  208. "CANFD_IR_RF1L - Rx FIFO 1 Message Lost",
  209. "CANFD_IR_HPM - High Priority Message",
  210. "CANFD_IR_TC - Transmission Completed",
  211. "CANFD_IR_TCF - Transmission Cancellation Finished",
  212. "CANFD_IR_TFE - Tx FIFO Empty",
  213. "CANFD_IR_TEFN - Tx Event FIFO New Entry",
  214. "CANFD_IR_TEFW - Tx Event FIFO Watermark Reached",
  215. "CANFD_IR_TEFF - Tx Event FIFO Full",
  216. "CANFD_IR_TEFL - Tx Event FIFO Event Lost",
  217. "CANFD_IR_TSW - Timestamp Wraparound",
  218. "CANFD_IR_MRAF - Message RAM Access Failure",
  219. "CANFD_IR_TOO - Timeout Occurred",
  220. "CANFD_IR_DRX - Message stored to Dedicated Rx Buffer",
  221. "BIT20",
  222. "BIT21",
  223. "CANFD_IR_ELO - Error Logging Overflow",
  224. "CANFD_IR_EP - Error Passive",
  225. "CANFD_IR_EW - Warning Status",
  226. "CANFD_IR_BO - Bus_Off Status",
  227. "CANFD_IR_WDI - Watchdog",
  228. "CANFD_IR_PEA - Protocol Error in Arbitration Phase",
  229. "CANFD_IR_PED - Protocol Error in Data Phase",
  230. "CANFD_IR_ARA - Access to Reserved Address",
  231. "BIT30",
  232. "BIT31"
  233. };
  234. static void dump_interrupt_event(uint32_t u32Status)
  235. {
  236. uint32_t idx;
  237. while ((idx = nu_ctz(u32Status)) < 32) // Count Trailing Zeros ==> Find First One
  238. {
  239. LOG_D("[%s]", szIR[idx]);
  240. u32Status &= ~(1 << idx);
  241. }
  242. }
  243. static void nu_canfd_isr(nu_canfd_t psNuCANFD)
  244. {
  245. /* Get base address of CAN register */
  246. CANFD_T *base = psNuCANFD->base;
  247. /* Get interrupt status */
  248. uint32_t u32Status = base->IR;
  249. CANFD_ClearStatusFlag(base, u32Status);
  250. /* Dump IR event */
  251. dump_interrupt_event(u32Status);
  252. /* Check Status Interrupt Flag (Error status Int and Status change Int) */
  253. /**************************/
  254. /* Status Change interrupt*/
  255. /**************************/
  256. if (u32Status & CANFD_IR_TC_Msk)
  257. {
  258. if (psNuCANFD->int_flag & RT_DEVICE_FLAG_INT_TX)
  259. {
  260. rt_hw_can_isr(&psNuCANFD->dev, RT_CAN_EVENT_TX_DONE);
  261. }
  262. }
  263. if (u32Status & (CANFD_IR_RF0N_Msk | CANFD_IR_RF1N_Msk))
  264. {
  265. if (psNuCANFD->int_flag & RT_DEVICE_FLAG_INT_RX)
  266. {
  267. rt_hw_can_isr(&psNuCANFD->dev, RT_CAN_EVENT_RX_IND);
  268. }
  269. }
  270. if (u32Status & (CANFD_IR_RF0L_Msk | CANFD_IR_RF1L_Msk))
  271. {
  272. rt_hw_can_isr(&psNuCANFD->dev, RT_CAN_EVENT_RXOF_IND);
  273. }
  274. if (u32Status & (CANFD_IR_TEFF_Msk | CANFD_IR_TOO_Msk))
  275. {
  276. rt_hw_can_isr(&psNuCANFD->dev, RT_CAN_EVENT_TX_FAIL);
  277. }
  278. /**************************/
  279. /* Error Status interrupt */
  280. /**************************/
  281. if (u32Status & CANFD_IR_EW_Msk)
  282. {
  283. LOG_E("[%s]EWARN", psNuCANFD->name) ;
  284. }
  285. if (u32Status & CANFD_IR_BO_Msk)
  286. {
  287. LOG_E("[%s]BUSOFF", psNuCANFD->name) ;
  288. /* To release busoff pin */
  289. }
  290. if (u32Status & CANFD_IR_PED_Msk)
  291. {
  292. LOG_E("[%s] LEC: %03x\n", psNuCANFD->name, base->PSR & CANFD_PSR_LEC_Msk) ;
  293. }
  294. }
  295. static void nu_canfd_ie(nu_canfd_t psNuCANFD)
  296. {
  297. uint32_t u32CanFDIE = CANFD_IE_BOE_Msk;
  298. if (psNuCANFD->int_flag & (RT_DEVICE_FLAG_INT_RX))
  299. {
  300. /* Rx FIFO 0 New Message Interrupt */
  301. u32CanFDIE |= (CANFD_IE_RF0NE_Msk | CANFD_IE_RF1NE_Msk);
  302. }
  303. if (psNuCANFD->int_flag & (RT_DEVICE_FLAG_INT_TX))
  304. {
  305. /* Transmission Completed Interrupt */
  306. /* Timeout Occurred Interrupt */
  307. u32CanFDIE |= (CANFD_IE_TCE_Msk | CANFD_IE_TEFNE_Msk);
  308. }
  309. if (psNuCANFD->int_flag & RT_DEVICE_CAN_INT_ERR)
  310. {
  311. /* Bus_Off Status Interrupt */
  312. /* Warning Status Interrupt */
  313. /* Error Passive Interrupt */
  314. /* Error Logging Overflow Interrupt */
  315. /* Protocol Error in Data Phase interrupt Indicator */
  316. u32CanFDIE |= (CANFD_IE_EPE_Msk | CANFD_IE_EWE_Msk | CANFD_IE_ELOE_Msk | CANFD_IE_TOOE_Msk | CANFD_IR_PED_Msk);
  317. }
  318. //u32CanFDIE = 0xffffffff;
  319. CANFD_EnableInt(psNuCANFD->base, u32CanFDIE, 0,
  320. (psNuCANFD->int_flag & (RT_DEVICE_FLAG_INT_TX)) ? CANFD_TXBTIE_TIEn_Msk : 0,
  321. (psNuCANFD->int_flag & (RT_DEVICE_FLAG_INT_TX)) ? CANFD_TXBCIE_CFIEn_Msk : 0);
  322. }
  323. static rt_err_t nu_canfd_configure(struct rt_can_device *can, struct can_configure *cfg)
  324. {
  325. nu_canfd_t psNuCANFD = (nu_canfd_t)can;
  326. CANFD_FD_T *psCANFDConf;
  327. RT_ASSERT(can);
  328. RT_ASSERT(cfg);
  329. psCANFDConf = &psNuCANFD->sCANFD_Config;
  330. /* Get base address of CAN register */
  331. CANFD_T *base = psNuCANFD->base;
  332. CANFD_GetDefaultConfig(psCANFDConf, CANFD_OP_CAN_MODE);
  333. LOG_I("Message Ram Size: %d @%08x ~ %08x", psCANFDConf->u32MRamSize, CANFD_SRAM_BASE_ADDR(base), psCANFDConf->u32MRamSize + CANFD_SRAM_BASE_ADDR(base));
  334. LOG_I("SIDFC: %d @%08x Size:%d", psCANFDConf->sElemSize.u32SIDFC, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32SIDFC_FLSSA, psCANFDConf->sElemSize.u32SIDFC * sizeof(CANFD_STD_FILTER_T));
  335. LOG_I("XIDFC: %d @%08x Size:%d", psCANFDConf->sElemSize.u32XIDFC, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32XIDFC_FLESA, psCANFDConf->sElemSize.u32XIDFC * sizeof(CANFD_EXT_FILTER_T));
  336. LOG_I("RxFifo0: %d @%08x Size:%d", psCANFDConf->sElemSize.u32RxFifo0, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32RXF0C_F0SA, psCANFDConf->sElemSize.u32RxFifo0 * sizeof(CANFD_BUF_T));
  337. LOG_I("RxFifo1: %d @%08x Size:%d", psCANFDConf->sElemSize.u32RxFifo1, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32RXF1C_F1SA, psCANFDConf->sElemSize.u32RxFifo1 * sizeof(CANFD_BUF_T));
  338. LOG_I("RxBuf: %d @%08x Size:%d", psCANFDConf->sElemSize.u32RxBuf, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32RXBC_RBSA, psCANFDConf->sElemSize.u32RxBuf * sizeof(CANFD_BUF_T));
  339. LOG_I("TxEventFifo: %d @%08x Size:%d", psCANFDConf->sElemSize.u32TxEventFifo, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32TXEFC_EFSA, psCANFDConf->sElemSize.u32TxEventFifo * sizeof(CANFD_EXT_FILTER_T));
  340. LOG_I("TxBuf: %d @%08x Size:%d", psCANFDConf->sElemSize.u32TxBuf, CANFD_SRAM_BASE_ADDR(base) + psCANFDConf->sMRamStartAddr.u32TXBC_TBSA, psCANFDConf->sElemSize.u32TxBuf * sizeof(CANFD_BUF_T));
  341. psCANFDConf->sBtConfig.sNormBitRate.u32BitRate = cfg->baud_rate;
  342. psCANFDConf->sBtConfig.sDataBitRate.u32BitRate = 0;
  343. LOG_I("CAN Baud rate: %d bps", cfg->baud_rate);
  344. switch (cfg->mode)
  345. {
  346. case RT_CAN_MODE_NORMAL: // Normal
  347. psCANFDConf->sBtConfig.evTestMode = eCANFD_NORMAL;
  348. break;
  349. case RT_CAN_MODE_LISTEN: // Bus monitor Mode, can't start a transmission
  350. psCANFDConf->sBtConfig.evTestMode = eCANFD_BUS_MONITOR;
  351. break;
  352. case RT_CAN_MODE_LOOPBACK: // Test - Internal loopback
  353. psCANFDConf->sBtConfig.evTestMode = eCANFD_LOOPBACK_INTERNAL;
  354. break;
  355. case RT_CAN_MODE_LOOPBACKANLISTEN:
  356. default:
  357. rt_kprintf("Unsupported Operating mode\n");
  358. goto exit_nu_canfd_configure;
  359. }
  360. /*Set the CAN Bit Rate and Operating mode*/
  361. CANFD_Open(base, psCANFDConf);
  362. /* Set FIFO policy */
  363. #if defined(RT_CAN_USING_HDR)
  364. /* Whitelist filtering */
  365. CANFD_SetGFC(base, eCANFD_REJ_NON_MATCH_FRM, eCANFD_REJ_NON_MATCH_FRM, 0, 0);
  366. #else
  367. /* Blacklist filtering. */
  368. CANFD_SetGFC(base, eCANFD_ACC_NON_MATCH_FRM_RX_FIFO0, eCANFD_ACC_NON_MATCH_FRM_RX_FIFO0, 0, 0);
  369. #endif
  370. /* Enable interrupt */
  371. nu_canfd_ie(psNuCANFD);
  372. //LOG_HEX("canfd", 16, (void *)base, sizeof(CANFD_T));
  373. /* Lock protected registers & Run */
  374. CANFD_RunToNormal(base, TRUE);
  375. return RT_EOK;
  376. exit_nu_canfd_configure:
  377. CANFD_Close(base);
  378. return -(RT_ERROR);
  379. }
  380. static rt_err_t nu_canfd_control(struct rt_can_device *can, int cmd, void *arg)
  381. {
  382. rt_uint32_t argval = (rt_uint32_t)arg;
  383. nu_canfd_t psNuCANFD = (nu_canfd_t)can;
  384. RT_ASSERT(can);
  385. switch (cmd)
  386. {
  387. case RT_DEVICE_CTRL_SET_INT:
  388. psNuCANFD->int_flag |= argval;
  389. return nu_canfd_configure(can, &can->config);
  390. case RT_DEVICE_CTRL_CLR_INT:
  391. psNuCANFD->int_flag &= ~argval;
  392. return nu_canfd_configure(can, &can->config);
  393. #if defined(RT_CAN_USING_HDR)
  394. case RT_CAN_CMD_SET_FILTER:
  395. {
  396. struct rt_can_filter_config *filter_cfg = (struct rt_can_filter_config *)arg;
  397. RT_ASSERT(filter_cfg);
  398. for (int i = 0; i < filter_cfg->count; i++)
  399. {
  400. uint32_t u32FEC = (filter_cfg->items[i].mode == RT_CAN_MODE_PRIV) ? eCANFD_FLTR_ELEM_SET_PRI_STO_FIFO0 : eCANFD_FLTR_ELEM_STO_FIFO0;
  401. /* Set the filter rule */
  402. if (filter_cfg->items[i].ide == RT_CAN_STDID)
  403. {
  404. /* for 11-bit */
  405. CANFD_STD_FILTER_T sStdFilter;
  406. if (i >= CANFD_MAX_11_BIT_FTR_ELEMS) // Check filter entry limitation
  407. return -(RT_ERROR);
  408. sStdFilter.SFID2 = filter_cfg->items[i].mask; /*!<Standard Filter ID 2. */ //mask
  409. sStdFilter.SFID1 = filter_cfg->items[i].id; /*!<Standard Filter ID 1. */ //filter
  410. sStdFilter.SFEC = u32FEC; /*!<Standard Filter Element Configuration */ //001b: Store in Rx FIFO 0 if filter matches
  411. sStdFilter.SFT = eCANFD_SID_FLTR_TYPE_CLASSIC; /*!<Standard Filter Type */ //10b: Classic filter: SFID1 = filter, SFID2 = mask
  412. CANFD_SetSIDFltr(psNuCANFD->base, i, sStdFilter.VALUE);
  413. }
  414. else
  415. {
  416. /* for 29-bit */
  417. CANFD_EXT_FILTER_T sXidFilter;
  418. if (i >= CANFD_MAX_29_BIT_FTR_ELEMS) // Check filter entry limitation
  419. return -(RT_ERROR);
  420. sXidFilter.EFID1 = filter_cfg->items[i].mask; /*!<Extended Filter ID 2. */ //mask
  421. sXidFilter.EFID2 = filter_cfg->items[i].id; /*!<Extended Filter ID 1. */ //filter
  422. sXidFilter.EFEC = u32FEC; /*!<Extended Filter Element Configuration */ //001b: Store in Rx FIFO 0 if filter matches
  423. sXidFilter.EFT = eCANFD_XID_FLTR_TYPE_CLASSIC; /*!<Extended Filter Type */ //10b: Classic filter: SFID1 = filter, SFID2 = mask
  424. CANFD_SetXIDFltr(psNuCANFD->base, i, sXidFilter.LOWVALUE, sXidFilter.HIGHVALUE);
  425. }
  426. } //for (int i = 0; i < filter_cfg->count; i++)
  427. }
  428. break;
  429. #endif
  430. case RT_CAN_CMD_SET_MODE:
  431. if ((argval == RT_CAN_MODE_NORMAL) ||
  432. (argval == RT_CAN_MODE_LISTEN) ||
  433. (argval == RT_CAN_MODE_LOOPBACK) ||
  434. (argval == RT_CAN_MODE_LOOPBACKANLISTEN))
  435. {
  436. if (argval != can->config.mode)
  437. {
  438. can->config.mode = argval;
  439. return nu_canfd_configure(can, &can->config);
  440. }
  441. }
  442. else
  443. {
  444. return -(RT_ERROR);
  445. }
  446. break;
  447. case RT_CAN_CMD_SET_BAUD:
  448. {
  449. if ((argval == CAN1MBaud) ||
  450. (argval == CAN800kBaud) ||
  451. (argval == CAN500kBaud) ||
  452. (argval == CAN250kBaud) ||
  453. (argval == CAN125kBaud) ||
  454. (argval == CAN100kBaud) ||
  455. (argval == CAN50kBaud) ||
  456. (argval == CAN20kBaud) ||
  457. (argval == CAN10kBaud))
  458. {
  459. if (argval != can->config.baud_rate)
  460. {
  461. can->config.baud_rate = argval;
  462. return nu_canfd_configure(can, &can->config);
  463. }
  464. }
  465. else
  466. {
  467. return -(RT_ERROR);
  468. }
  469. }
  470. break;
  471. case RT_CAN_CMD_SET_PRIV:
  472. if (argval != RT_CAN_MODE_PRIV &&
  473. argval != RT_CAN_MODE_NOPRIV)
  474. {
  475. return -(RT_ERROR);
  476. }
  477. if (argval != can->config.privmode)
  478. {
  479. can->config.privmode = argval;
  480. return nu_canfd_configure(can, &can->config);
  481. }
  482. break;
  483. case RT_CAN_CMD_GET_STATUS:
  484. {
  485. rt_uint32_t u32ErrCounter = psNuCANFD->base->ECR;
  486. rt_uint32_t u32ProtocolStatus = psNuCANFD->base->PSR;
  487. RT_ASSERT(arg);
  488. /*Receive Error Counter, return value is with Receive Error Passive.*/
  489. can->status.rcverrcnt = ((u32ErrCounter & CANFD_ECR_REC_Msk) >> CANFD_ECR_REC_Pos);
  490. /*Transmit Error Counter*/
  491. can->status.snderrcnt = ((u32ErrCounter & CANFD_ECR_TEC_Msk) >> CANFD_ECR_TEC_Pos);
  492. /*Last Error Type*/
  493. can->status.lasterrtype = ((u32ProtocolStatus & CANFD_PSR_LEC_Msk) >> CANFD_PSR_LEC_Pos);
  494. /*Status error code*/
  495. can->status.errcode = (u32ProtocolStatus & CANFD_PSR_EW_Msk) ? 1 :
  496. (u32ProtocolStatus & CANFD_PSR_EP_Msk) ? 2 :
  497. (u32ProtocolStatus & CANFD_PSR_BO_Msk) ? 3 :
  498. 0;
  499. rt_memcpy(arg, &can->status, sizeof(struct rt_can_status));
  500. }
  501. break;
  502. default:
  503. return -(RT_EINVAL);
  504. }
  505. return RT_EOK;
  506. }
  507. static int nu_canfd_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  508. {
  509. CANFD_FD_MSG_T sTxMsg;
  510. struct rt_can_msg *pmsg;
  511. nu_canfd_t psNuCANFD = (nu_canfd_t)can;
  512. RT_ASSERT(can);
  513. RT_ASSERT(buf);
  514. pmsg = (struct rt_can_msg *) buf;
  515. if (pmsg->ide == RT_CAN_STDID && IS_CAN_STDID(pmsg->id))
  516. {
  517. /* Standard ID (11 bits)*/
  518. sTxMsg.u32Id = pmsg->id;
  519. sTxMsg.eIdType = eCANFD_SID;
  520. }
  521. else if (pmsg->ide == RT_CAN_EXTID && IS_CAN_EXTID(pmsg->id))
  522. {
  523. /* Extended ID (29 bits)*/
  524. sTxMsg.u32Id = pmsg->id;
  525. sTxMsg.eIdType = eCANFD_XID;
  526. }
  527. else
  528. {
  529. goto exit_nu_canfd_sendmsg;
  530. }
  531. sTxMsg.bBitRateSwitch = 0;
  532. if (pmsg->rtr == RT_CAN_DTR)
  533. {
  534. /* Data frame */
  535. sTxMsg.eFrmType = eCANFD_DATA_FRM;
  536. }
  537. else if (pmsg->rtr == RT_CAN_RTR)
  538. {
  539. /* Remote frame */
  540. sTxMsg.eFrmType = eCANFD_REMOTE_FRM;
  541. }
  542. else
  543. {
  544. goto exit_nu_canfd_sendmsg;
  545. }
  546. /* Check the parameters */
  547. if (IS_CAN_DLC(pmsg->len))
  548. {
  549. sTxMsg.u32DLC = pmsg->len;
  550. }
  551. else
  552. {
  553. goto exit_nu_canfd_sendmsg;
  554. }
  555. if (pmsg->len > 0)
  556. {
  557. rt_memcpy(&sTxMsg.au8Data[0], pmsg->data, pmsg->len);
  558. }
  559. if (!CANFD_TransmitTxMsg(psNuCANFD->base, 0, &sTxMsg))
  560. {
  561. goto exit_nu_canfd_sendmsg;
  562. }
  563. return RT_EOK;
  564. exit_nu_canfd_sendmsg:
  565. return -(RT_ERROR);
  566. }
  567. static int nu_canfd_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
  568. {
  569. CANFD_FD_MSG_T sRxMsg;
  570. struct rt_can_msg *pmsg;
  571. nu_canfd_t psNuCANFD = (nu_canfd_t)can;
  572. RT_ASSERT(can);
  573. RT_ASSERT(buf);
  574. pmsg = (struct rt_can_msg *) buf;
  575. /* get data */
  576. if (CANFD_ReadRxFifoMsg(psNuCANFD->base, 0, &sRxMsg) == FALSE)
  577. {
  578. rt_kprintf("No available RX Msg.\n");
  579. return -(RT_ERROR);
  580. }
  581. #ifdef RT_CAN_USING_HDR
  582. /* Hardware filter messages are valid */
  583. pmsg->hdr = boxno;
  584. can->hdr[pmsg->hdr].connected = 1;
  585. #endif
  586. pmsg->ide = (sRxMsg.eIdType == eCANFD_SID) ? RT_CAN_STDID : RT_CAN_EXTID;
  587. pmsg->rtr = (sRxMsg.eFrmType == eCANFD_DATA_FRM) ? RT_CAN_DTR : RT_CAN_RTR;
  588. pmsg->id = sRxMsg.u32Id;
  589. pmsg->len = sRxMsg.u32DLC;
  590. if (pmsg->len > 0)
  591. rt_memcpy(&pmsg->data[0], &sRxMsg.au8Data[0], pmsg->len);
  592. return RT_EOK;
  593. }
  594. /**
  595. * Hardware CAN Initialization
  596. */
  597. static int rt_hw_canfd_init(void)
  598. {
  599. int i;
  600. rt_err_t ret = RT_EOK;
  601. for (i = (CANFD_START + 1); i < CANFD_CNT; i++)
  602. {
  603. nu_canfd_arr[i].dev.config = nu_canfd_default_config;
  604. #ifdef RT_CAN_USING_HDR
  605. nu_canfd_arr[i].dev.config.maxhdr = RT_CANMSG_BOX_SZ;
  606. #endif
  607. /* Register can device */
  608. ret = rt_hw_can_register(&nu_canfd_arr[i].dev, nu_canfd_arr[i].name, &nu_canfd_ops, NULL);
  609. RT_ASSERT(ret == RT_EOK);
  610. /* Unmask interrupt. */
  611. NVIC_EnableIRQ(nu_canfd_arr[i].irqn0);
  612. NVIC_EnableIRQ(nu_canfd_arr[i].irqn1);
  613. }
  614. return (int)ret;
  615. }
  616. INIT_DEVICE_EXPORT(rt_hw_canfd_init);
  617. #endif //#if defined(BSP_USING_CANFD)