drv_can.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-01-09 chenbin the first version
  9. */
  10. #include "drv_can.h"
  11. #ifdef BSP_USING_CAN
  12. #include "stdint.h"
  13. #include "n32g45x.h"
  14. #include "n32g45x_can.h"
  15. struct n32g45x_baud_rate_tab
  16. {
  17. uint32_t baud_rate;
  18. uint16_t PRESCALE;
  19. uint8_t RSJW;
  20. uint8_t TBS1;
  21. uint8_t TBS2;
  22. uint8_t notused;
  23. };
  24. #define N32_CAN_BAUD_DEF(rate, rsjw, tbs1, tbs2, prescale) \
  25. { \
  26. .baud_rate = rate, \
  27. .RSJW = rsjw, \
  28. .TBS1 = tbs1, \
  29. .TBS2 = tbs2, \
  30. .PRESCALE = prescale \
  31. }
  32. /* N32G45x can device */
  33. struct n32g45x_can
  34. {
  35. char *name;
  36. CAN_Module *CANx;
  37. CAN_InitType can_init;
  38. CAN_FilterInitType can_filter_init;
  39. struct rt_can_device device; /* inherit from can device */
  40. };
  41. #define LOG_TAG "drv_can"
  42. #include <drv_log.h>
  43. /*
  44. * N32G45x CAN1 CAN2 used APB1 (36MHz)
  45. * baud calculation example: baud = Tclk / ((ss + bs1 + bs2) * brp)
  46. * 36MHz / ((1 + 5 + 3) * 4) = 1MHz
  47. */
  48. #if defined(N32G45X) /* APB1 36MHz(max) */
  49. static const struct n32g45x_baud_rate_tab can_baud_rate_tab[] =
  50. {
  51. N32_CAN_BAUD_DEF(CAN1MBaud, CAN_RSJW_1tq, CAN_TBS1_5tq, CAN_TBS2_3tq, 4),
  52. N32_CAN_BAUD_DEF(CAN800kBaud, CAN_RSJW_1tq, CAN_TBS1_5tq, CAN_TBS2_3tq, 5),
  53. N32_CAN_BAUD_DEF(CAN500kBaud, CAN_RSJW_1tq, CAN_TBS1_5tq, CAN_TBS2_3tq, 8),
  54. N32_CAN_BAUD_DEF(CAN250kBaud, CAN_RSJW_1tq, CAN_TBS1_5tq, CAN_TBS2_3tq, 16),
  55. N32_CAN_BAUD_DEF(CAN125kBaud, CAN_RSJW_1tq, CAN_TBS1_5tq, CAN_TBS2_3tq, 32),
  56. N32_CAN_BAUD_DEF(CAN100kBaud, CAN_RSJW_2tq, CAN_TBS1_8tq, CAN_TBS2_8tq, 20),
  57. N32_CAN_BAUD_DEF(CAN50kBaud, CAN_RSJW_2tq, CAN_TBS1_8tq, CAN_TBS2_8tq, 40),
  58. N32_CAN_BAUD_DEF(CAN20kBaud, CAN_RSJW_2tq, CAN_TBS1_8tq, CAN_TBS2_8tq, 80),
  59. N32_CAN_BAUD_DEF(CAN10kBaud, CAN_RSJW_2tq, CAN_TBS1_8tq, CAN_TBS2_8tq, 160),
  60. };
  61. #endif
  62. #ifdef BSP_USING_CAN1
  63. static struct n32g45x_can drv_can1 =
  64. {
  65. .name = "can1",
  66. .CANx = CAN1,
  67. };
  68. #endif
  69. #ifdef BSP_USING_CAN2
  70. static struct n32g45x_can drv_can2 =
  71. {
  72. .name = "can2",
  73. .CANx = CAN2,
  74. };
  75. #endif
  76. static uint32_t get_can_baud_index(rt_uint32_t baud)
  77. {
  78. uint32_t len, index;
  79. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  80. for (index = 0; index < len; index++)
  81. {
  82. if (can_baud_rate_tab[index].baud_rate == baud)
  83. return index;
  84. }
  85. return 0; /* default baud is CAN1MBaud */
  86. }
  87. static uint8_t get_can_mode_rtt2n32(uint8_t rtt_can_mode)
  88. {
  89. uint8_t mode = CAN_Normal_Mode;
  90. switch (rtt_can_mode)
  91. {
  92. case RT_CAN_MODE_NORMAL:
  93. mode = CAN_Normal_Mode;
  94. break;
  95. case RT_CAN_MODE_LISEN:
  96. mode = CAN_Silent_Mode;
  97. break;
  98. case RT_CAN_MODE_LOOPBACK:
  99. mode = CAN_LoopBack_Mode;
  100. break;
  101. case RT_CAN_MODE_LOOPBACKANLISEN:
  102. mode = CAN_Silent_LoopBack_Mode;
  103. break;
  104. }
  105. return mode;
  106. }
  107. static rt_err_t _can_filter_config(struct n32g45x_can *drv_can)
  108. {
  109. if (drv_can->CANx == CAN1)
  110. {
  111. CAN1_InitFilter(&(drv_can->can_filter_init));
  112. }
  113. #ifdef CAN2
  114. else if (drv_can->CANx == CAN2)
  115. {
  116. CAN2_InitFilter(&(drv_can->can_filter_init));
  117. }
  118. #endif
  119. else
  120. {
  121. rt_kprintf("can filter config error\n");
  122. return -RT_EINVAL;
  123. }
  124. return RT_EOK;
  125. }
  126. static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg)
  127. {
  128. struct n32g45x_can *drv_can;
  129. rt_uint32_t baud_index;
  130. RT_ASSERT(can);
  131. RT_ASSERT(cfg);
  132. drv_can = (struct n32g45x_can *)can->parent.user_data;
  133. RT_ASSERT(drv_can);
  134. /* Configure CAN1 and CAN2 */
  135. if (drv_can->CANx == CAN1)
  136. {
  137. RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN1, ENABLE);
  138. n32_msp_can_init(CAN1);
  139. }
  140. #ifdef CAN2
  141. else if (drv_can->CANx == CAN2)
  142. {
  143. RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN2, ENABLE);
  144. n32_msp_can_init(CAN2);
  145. }
  146. #endif
  147. else
  148. {
  149. rt_kprintf("can init error1\n");
  150. return -RT_EINVAL;
  151. }
  152. /* Struct init*/
  153. CAN_InitStruct(&(drv_can->can_init));
  154. drv_can->can_init.TTCM = DISABLE;
  155. drv_can->can_init.ABOM = DISABLE;
  156. drv_can->can_init.AWKUM = DISABLE;
  157. drv_can->can_init.NART = DISABLE;
  158. drv_can->can_init.RFLM = DISABLE;
  159. drv_can->can_init.TXFP = ENABLE;
  160. //mode
  161. drv_can->can_init.OperatingMode = get_can_mode_rtt2n32(cfg->mode);
  162. //baud
  163. baud_index = get_can_baud_index(cfg->baud_rate);
  164. drv_can->can_init.RSJW = can_baud_rate_tab[baud_index].RSJW;
  165. drv_can->can_init.TBS1 = can_baud_rate_tab[baud_index].TBS1;
  166. drv_can->can_init.TBS2 = can_baud_rate_tab[baud_index].TBS2;
  167. drv_can->can_init.BaudRatePrescaler = can_baud_rate_tab[baud_index].PRESCALE;
  168. /* init can */
  169. if (CAN_Init(drv_can->CANx, &(drv_can->can_init)) != CAN_InitSTS_Success)
  170. {
  171. rt_kprintf("can init error2\n");
  172. return -RT_ERROR;
  173. }
  174. /* default filter config */
  175. _can_filter_config(drv_can);
  176. return RT_EOK;
  177. }
  178. #ifndef CAN1_TX_IRQn
  179. #define CAN1_TX_IRQn USB_HP_CAN1_TX_IRQn
  180. #endif
  181. #ifndef CAN1_RX0_IRQn
  182. #define CAN1_RX0_IRQn USB_LP_CAN1_RX0_IRQn
  183. #endif
  184. static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
  185. {
  186. rt_uint32_t argval;
  187. struct n32g45x_can *drv_can;
  188. struct rt_can_filter_config *filter_cfg;
  189. RT_ASSERT(can != RT_NULL);
  190. drv_can = (struct n32g45x_can *)can->parent.user_data;
  191. RT_ASSERT(drv_can != RT_NULL);
  192. switch (cmd)
  193. {
  194. case RT_DEVICE_CTRL_CLR_INT:
  195. argval = (rt_uint32_t)arg;
  196. if (argval == RT_DEVICE_FLAG_INT_RX)
  197. {
  198. if (CAN1 == drv_can->CANx)
  199. {
  200. NVIC_DisableIRQ(CAN1_RX0_IRQn);
  201. NVIC_DisableIRQ(CAN1_RX1_IRQn);
  202. }
  203. #ifdef CAN2
  204. if (CAN2 == drv_can->CANx)
  205. {
  206. NVIC_DisableIRQ(CAN2_RX0_IRQn);
  207. NVIC_DisableIRQ(CAN2_RX1_IRQn);
  208. }
  209. #endif
  210. CAN_INTConfig(drv_can->CANx, CAN_INT_FMP0, DISABLE); /*!< DATFIFO 0 message pending Interrupt*/
  211. CAN_INTConfig(drv_can->CANx, CAN_INT_FF0, DISABLE); /*!< DATFIFO 0 full Interrupt*/
  212. CAN_INTConfig(drv_can->CANx, CAN_INT_FOV0, DISABLE); /*!< DATFIFO 0 overrun Interrupt*/
  213. CAN_INTConfig(drv_can->CANx, CAN_INT_FMP1, DISABLE); /*!< DATFIFO 1 message pending Interrupt*/
  214. CAN_INTConfig(drv_can->CANx, CAN_INT_FF1, DISABLE); /*!< DATFIFO 1 full Interrupt*/
  215. CAN_INTConfig(drv_can->CANx, CAN_INT_FOV1, DISABLE); /*!< DATFIFO 1 overrun Interrupt*/
  216. }
  217. else if (argval == RT_DEVICE_FLAG_INT_TX)
  218. {
  219. if (CAN1 == drv_can->CANx)
  220. {
  221. NVIC_DisableIRQ(CAN1_TX_IRQn);
  222. }
  223. #ifdef CAN2
  224. if (CAN2 == drv_can->CANx)
  225. {
  226. NVIC_DisableIRQ(CAN2_TX_IRQn);
  227. }
  228. #endif
  229. CAN_INTConfig(drv_can->CANx, CAN_INT_TME, DISABLE); /*!< Transmit mailbox empty Interrupt*/
  230. }
  231. else if (argval == RT_DEVICE_CAN_INT_ERR)
  232. {
  233. if (CAN1 == drv_can->CANx)
  234. {
  235. NVIC_DisableIRQ(CAN1_SCE_IRQn);
  236. }
  237. #ifdef CAN2
  238. if (CAN2 == drv_can->CANx)
  239. {
  240. NVIC_DisableIRQ(CAN2_SCE_IRQn);
  241. }
  242. #endif
  243. CAN_INTConfig(drv_can->CANx, CAN_INT_EWG, DISABLE); /*!< Error warning Interrupt*/
  244. CAN_INTConfig(drv_can->CANx, CAN_INT_EPV, DISABLE); /*!< Error passive Interrupt*/
  245. CAN_INTConfig(drv_can->CANx, CAN_INT_BOF, DISABLE); /*!< Bus-off Interrupt*/
  246. CAN_INTConfig(drv_can->CANx, CAN_INT_LEC, DISABLE); /*!< Last error code Interrupt*/
  247. CAN_INTConfig(drv_can->CANx, CAN_INT_ERR, DISABLE); /*!< Error Interrupt*/
  248. }
  249. break;
  250. case RT_DEVICE_CTRL_SET_INT:
  251. argval = (rt_uint32_t)arg;
  252. if (argval == RT_DEVICE_FLAG_INT_RX)
  253. {
  254. CAN_INTConfig(drv_can->CANx, CAN_INT_FMP0, ENABLE); /*!< DATFIFO 0 message pending Interrupt*/
  255. CAN_INTConfig(drv_can->CANx, CAN_INT_FF0, ENABLE); /*!< DATFIFO 0 full Interrupt*/
  256. CAN_INTConfig(drv_can->CANx, CAN_INT_FOV0, ENABLE); /*!< DATFIFO 0 overrun Interrupt*/
  257. CAN_INTConfig(drv_can->CANx, CAN_INT_FMP1, ENABLE); /*!< DATFIFO 1 message pending Interrupt*/
  258. CAN_INTConfig(drv_can->CANx, CAN_INT_FF1, ENABLE); /*!< DATFIFO 1 full Interrupt*/
  259. CAN_INTConfig(drv_can->CANx, CAN_INT_FOV1, ENABLE); /*!< DATFIFO 1 overrun Interrupt*/
  260. if (CAN1 == drv_can->CANx)
  261. {
  262. NVIC_SetPriority(CAN1_RX0_IRQn, 1);
  263. NVIC_EnableIRQ(CAN1_RX0_IRQn);
  264. NVIC_SetPriority(CAN1_RX1_IRQn, 1);
  265. NVIC_EnableIRQ(CAN1_RX1_IRQn);
  266. }
  267. #ifdef CAN2
  268. if (CAN2 == drv_can->CANx)
  269. {
  270. NVIC_SetPriority(CAN2_RX0_IRQn, 1);
  271. NVIC_EnableIRQ(CAN2_RX0_IRQn);
  272. NVIC_SetPriority(CAN2_RX1_IRQn, 1);
  273. NVIC_EnableIRQ(CAN2_RX1_IRQn);
  274. }
  275. #endif
  276. }
  277. else if (argval == RT_DEVICE_FLAG_INT_TX)
  278. {
  279. CAN_INTConfig(drv_can->CANx, CAN_INT_TME, ENABLE); /*!< Transmit mailbox empty Interrupt*/
  280. if (CAN1 == drv_can->CANx)
  281. {
  282. NVIC_SetPriority(CAN1_TX_IRQn, 1);
  283. NVIC_EnableIRQ(CAN1_TX_IRQn);
  284. }
  285. #ifdef CAN2
  286. if (CAN2 == drv_can->CANx)
  287. {
  288. NVIC_SetPriority(CAN2_TX_IRQn, 1);
  289. NVIC_EnableIRQ(CAN2_TX_IRQn);
  290. }
  291. #endif
  292. }
  293. else if (argval == RT_DEVICE_CAN_INT_ERR)
  294. {
  295. CAN_INTConfig(drv_can->CANx, CAN_INT_EWG, ENABLE); /*!< Error warning Interrupt*/
  296. CAN_INTConfig(drv_can->CANx, CAN_INT_EPV, ENABLE); /*!< Error passive Interrupt*/
  297. CAN_INTConfig(drv_can->CANx, CAN_INT_BOF, ENABLE); /*!< Bus-off Interrupt*/
  298. CAN_INTConfig(drv_can->CANx, CAN_INT_LEC, ENABLE); /*!< Last error code Interrupt*/
  299. CAN_INTConfig(drv_can->CANx, CAN_INT_ERR, ENABLE); /*!< Error Interrupt*/
  300. if (CAN1 == drv_can->CANx)
  301. {
  302. NVIC_SetPriority(CAN1_SCE_IRQn, 1);
  303. NVIC_EnableIRQ(CAN1_SCE_IRQn);
  304. }
  305. #ifdef CAN2
  306. if (CAN2 == drv_can->CANx)
  307. {
  308. NVIC_SetPriority(CAN2_SCE_IRQn, 1);
  309. NVIC_EnableIRQ(CAN2_SCE_IRQn);
  310. }
  311. #endif
  312. }
  313. break;
  314. case RT_CAN_CMD_SET_FILTER:
  315. {
  316. rt_uint32_t id_h = 0;
  317. rt_uint32_t id_l = 0;
  318. rt_uint32_t mask_h = 0;
  319. rt_uint32_t mask_l = 0;
  320. rt_uint32_t mask_l_tail = 0; //CAN_FxR2 bit [2:0]
  321. if (RT_NULL == arg)
  322. {
  323. /* default filter config */
  324. _can_filter_config(drv_can);
  325. }
  326. else
  327. {
  328. filter_cfg = (struct rt_can_filter_config *)arg;
  329. /* get default filter */
  330. for (int i = 0; i < filter_cfg->count; i++)
  331. {
  332. if (filter_cfg->items[i].hdr == -1)
  333. {
  334. drv_can->can_filter_init.Filter_Num = i;
  335. }
  336. else
  337. {
  338. drv_can->can_filter_init.Filter_Num = filter_cfg->items[i].hdr;
  339. }
  340. if (filter_cfg->items[i].mode == 0x00)
  341. {
  342. drv_can->can_filter_init.Filter_Mode = CAN_Filter_IdMaskMode;
  343. }
  344. else if (filter_cfg->items[i].mode == 0x01)
  345. {
  346. drv_can->can_filter_init.Filter_Mode = CAN_Filter_IdListMode;
  347. }
  348. if (filter_cfg->items[i].ide == RT_CAN_STDID)
  349. {
  350. id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
  351. id_l = ((filter_cfg->items[i].id << 18) |
  352. (filter_cfg->items[i].ide << 2) |
  353. (filter_cfg->items[i].rtr << 1)) &
  354. 0xFFFF;
  355. mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
  356. mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
  357. }
  358. else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
  359. {
  360. id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
  361. id_l = ((filter_cfg->items[i].id << 3) |
  362. (filter_cfg->items[i].ide << 2) |
  363. (filter_cfg->items[i].rtr << 1)) &
  364. 0xFFFF;
  365. mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
  366. mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
  367. }
  368. drv_can->can_filter_init.Filter_Scale = CAN_Filter_32bitScale;
  369. drv_can->can_filter_init.Filter_HighId = id_h;
  370. drv_can->can_filter_init.Filter_LowId = id_l;
  371. drv_can->can_filter_init.FilterMask_HighId = mask_h;
  372. drv_can->can_filter_init.FilterMask_LowId = mask_l;
  373. drv_can->can_filter_init.Filter_FIFOAssignment = CAN_FIFO0;
  374. drv_can->can_filter_init.Filter_Act = ENABLE;
  375. /* Filter conf */
  376. _can_filter_config(drv_can);
  377. }
  378. }
  379. break;
  380. }
  381. case RT_CAN_CMD_SET_MODE:
  382. argval = (rt_uint32_t)arg;
  383. if (argval != RT_CAN_MODE_NORMAL &&
  384. argval != RT_CAN_MODE_LISEN &&
  385. argval != RT_CAN_MODE_LOOPBACK &&
  386. argval != RT_CAN_MODE_LOOPBACKANLISEN)
  387. {
  388. return -RT_ERROR;
  389. }
  390. if (argval != drv_can->device.config.mode)
  391. {
  392. drv_can->device.config.mode = argval;
  393. return _can_config(&drv_can->device, &drv_can->device.config);
  394. }
  395. break;
  396. case RT_CAN_CMD_SET_BAUD:
  397. argval = (rt_uint32_t)arg;
  398. if (argval != CAN1MBaud &&
  399. argval != CAN800kBaud &&
  400. argval != CAN500kBaud &&
  401. argval != CAN250kBaud &&
  402. argval != CAN125kBaud &&
  403. argval != CAN100kBaud &&
  404. argval != CAN50kBaud &&
  405. argval != CAN20kBaud &&
  406. argval != CAN10kBaud)
  407. {
  408. return -RT_ERROR;
  409. }
  410. if (argval != drv_can->device.config.baud_rate)
  411. {
  412. drv_can->device.config.baud_rate = argval;
  413. return _can_config(&drv_can->device, &drv_can->device.config);
  414. }
  415. break;
  416. case RT_CAN_CMD_SET_PRIV:
  417. argval = (rt_uint32_t)arg;
  418. if (argval != RT_CAN_MODE_PRIV &&
  419. argval != RT_CAN_MODE_NOPRIV)
  420. {
  421. return -RT_ERROR;
  422. }
  423. if (argval != drv_can->device.config.privmode)
  424. {
  425. drv_can->device.config.privmode = argval;
  426. return _can_config(&drv_can->device, &drv_can->device.config);
  427. }
  428. break;
  429. case RT_CAN_CMD_GET_STATUS:
  430. {
  431. rt_uint32_t errtype;
  432. errtype = drv_can->CANx->ESTS;
  433. drv_can->device.status.rcverrcnt = errtype >> 24;
  434. drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF);
  435. drv_can->device.status.lasterrtype = errtype & 0x70;
  436. drv_can->device.status.errcode = errtype & 0x07;
  437. rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status));
  438. }
  439. break;
  440. }
  441. return RT_EOK;
  442. }
  443. /* CAN Mailbox Transmit Request */
  444. #define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */
  445. static int _can_sendmsg_rtmsg(CAN_Module *CANx, struct rt_can_msg *pmsg, uint32_t mailbox_index)
  446. {
  447. CanTxMessage CAN_TxMessage = {0};
  448. CanTxMessage *TxMessage = &CAN_TxMessage;
  449. /* Check the parameters */
  450. assert_param(IS_CAN_ALL_PERIPH(CANx));
  451. if (RT_CAN_STDID == pmsg->ide)
  452. {
  453. TxMessage->IDE = CAN_Standard_Id;
  454. RT_ASSERT(IS_CAN_STDID(pmsg->id));
  455. TxMessage->StdId = pmsg->id;
  456. }
  457. else
  458. {
  459. TxMessage->IDE = CAN_Extended_Id;
  460. RT_ASSERT(IS_CAN_EXTID(pmsg->id));
  461. TxMessage->ExtId = pmsg->id;
  462. }
  463. if (RT_CAN_DTR == pmsg->rtr)
  464. {
  465. TxMessage->RTR = CAN_RTRQ_DATA;
  466. }
  467. else
  468. {
  469. TxMessage->RTR = CAN_RTRQ_REMOTE;
  470. }
  471. if (mailbox_index != CAN_TxSTS_NoMailBox)
  472. {
  473. /* Set up the Id */
  474. CANx->sTxMailBox[mailbox_index].TMI &= TMIDxR_TXRQ;
  475. if (TxMessage->IDE == CAN_Standard_Id)
  476. {
  477. assert_param(IS_CAN_STDID(TxMessage->StdId));
  478. CANx->sTxMailBox[mailbox_index].TMI |= ((TxMessage->StdId << 21) | TxMessage->RTR);
  479. }
  480. else
  481. {
  482. assert_param(IS_CAN_EXTID(TxMessage->ExtId));
  483. CANx->sTxMailBox[mailbox_index].TMI |= ((TxMessage->ExtId << 3) | TxMessage->IDE | TxMessage->RTR);
  484. }
  485. /* Set up the DLC */
  486. TxMessage->DLC = pmsg->len & 0x0FU;
  487. CANx->sTxMailBox[mailbox_index].TMDT &= (uint32_t)0xFFFFFFF0;
  488. CANx->sTxMailBox[mailbox_index].TMDT |= TxMessage->DLC;
  489. /* Set up the data field */
  490. CANx->sTxMailBox[mailbox_index].TMDH =
  491. (((uint32_t)pmsg->data[7] << 24) |
  492. ((uint32_t)pmsg->data[6] << 16) |
  493. ((uint32_t)pmsg->data[5] << 8) |
  494. ((uint32_t)pmsg->data[4]));
  495. CANx->sTxMailBox[mailbox_index].TMDL =
  496. (((uint32_t)pmsg->data[3] << 24) |
  497. ((uint32_t)pmsg->data[2] << 16) |
  498. ((uint32_t)pmsg->data[1] << 8) |
  499. ((uint32_t)pmsg->data[0]));
  500. /* Request transmission */
  501. CANx->sTxMailBox[mailbox_index].TMI |= TMIDxR_TXRQ;
  502. return RT_EOK;
  503. }
  504. return -RT_ERROR;
  505. }
  506. static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
  507. {
  508. struct n32g45x_can *drv_can;
  509. RT_ASSERT(can != RT_NULL);
  510. RT_ASSERT(buf != RT_NULL);
  511. drv_can = (struct n32g45x_can *)can->parent.user_data;
  512. RT_ASSERT(drv_can != RT_NULL);
  513. /* Select one empty transmit mailbox */
  514. switch (box_num)
  515. {
  516. case 0:
  517. if ((drv_can->CANx->TSTS & CAN_TSTS_TMEM0) != CAN_TSTS_TMEM0)
  518. {
  519. /* Return function status */
  520. return -RT_ERROR;
  521. }
  522. break;
  523. case 1:
  524. if ((drv_can->CANx->TSTS & CAN_TSTS_TMEM1) != CAN_TSTS_TMEM1)
  525. {
  526. /* Return function status */
  527. return -RT_ERROR;
  528. }
  529. break;
  530. case 2:
  531. if ((drv_can->CANx->TSTS & CAN_TSTS_TMEM2) != CAN_TSTS_TMEM2)
  532. {
  533. /* Return function status */
  534. return -RT_ERROR;
  535. }
  536. break;
  537. default:
  538. RT_ASSERT(0);
  539. break;
  540. }
  541. //start send msg
  542. return _can_sendmsg_rtmsg(drv_can->CANx, ((struct rt_can_msg *)buf), box_num);
  543. }
  544. static int _can_recvmsg_rtmsg(CAN_Module *CANx, struct rt_can_msg *pmsg, uint32_t FIFONum)
  545. {
  546. CanRxMessage CAN_RxMessage = {0};
  547. CanRxMessage *RxMessage = &CAN_RxMessage;
  548. /* Check the parameters */
  549. assert_param(IS_CAN_ALL_PERIPH(CANx));
  550. assert_param(IS_CAN_FIFO(FIFONum));
  551. /* Check the Rx FIFO */
  552. if (FIFONum == CAN_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
  553. {
  554. /* Check that the Rx FIFO 0 is not empty */
  555. if ((CANx->RFF0 & CAN_RFF0_FFMP0) == 0U)
  556. {
  557. return -RT_ERROR;
  558. }
  559. }
  560. else /* Rx element is assigned to Rx FIFO 1 */
  561. {
  562. /* Check that the Rx FIFO 1 is not empty */
  563. if ((CANx->RFF1 & CAN_RFF1_FFMP1) == 0U)
  564. {
  565. return -RT_ERROR;
  566. }
  567. }
  568. /* Get the Id */
  569. RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONum].RMI;
  570. if (RxMessage->IDE == CAN_Standard_Id)
  571. {
  572. RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONum].RMI >> 21);
  573. }
  574. else
  575. {
  576. RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONum].RMI >> 3);
  577. }
  578. RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONum].RMI;
  579. /* Get the DLC */
  580. RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONum].RMDT;
  581. /* Get the FMI */
  582. RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDT >> 8);
  583. /* Get the data field */
  584. pmsg->data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONum].RMDL;
  585. pmsg->data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDL >> 8);
  586. pmsg->data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDL >> 16);
  587. pmsg->data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDL >> 24);
  588. pmsg->data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONum].RMDH;
  589. pmsg->data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDH >> 8);
  590. pmsg->data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDH >> 16);
  591. pmsg->data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONum].RMDH >> 24);
  592. /* get len */
  593. pmsg->len = RxMessage->DLC;
  594. /* get id */
  595. if (RxMessage->IDE == CAN_Standard_Id)
  596. {
  597. pmsg->ide = RT_CAN_STDID;
  598. pmsg->id = RxMessage->StdId;
  599. }
  600. else
  601. {
  602. pmsg->ide = RT_CAN_EXTID;
  603. pmsg->id = RxMessage->ExtId;
  604. }
  605. /* get type */
  606. if (CAN_RTRQ_Data == RxMessage->RTR)
  607. {
  608. pmsg->rtr = RT_CAN_DTR;
  609. }
  610. else
  611. {
  612. pmsg->rtr = RT_CAN_RTR;
  613. }
  614. /* get hdr */
  615. if (CANx == CAN1)
  616. {
  617. pmsg->hdr = (RxMessage->FMI + 1) >> 1;
  618. }
  619. #ifdef CAN2
  620. else if (CANx == CAN2)
  621. {
  622. pmsg->hdr = (RxMessage->FMI >> 1) + 14;
  623. }
  624. #endif
  625. /* Release the DATFIFO */
  626. /* Release FIFO0 */
  627. if (FIFONum == CAN_FIFO0)
  628. {
  629. CANx->RFF0 |= CAN_RFF0_RFFOM0;
  630. }
  631. /* Release FIFO1 */
  632. else /* FIFONum == CAN_FIFO1 */
  633. {
  634. CANx->RFF1 |= CAN_RFF1_RFFOM1;
  635. }
  636. return RT_EOK;
  637. }
  638. static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
  639. {
  640. struct n32g45x_can *drv_can;
  641. RT_ASSERT(can != RT_NULL);
  642. RT_ASSERT(buf != RT_NULL);
  643. drv_can = (struct n32g45x_can *)can->parent.user_data;
  644. RT_ASSERT(drv_can != RT_NULL);
  645. /* get data */
  646. return _can_recvmsg_rtmsg(drv_can->CANx, ((struct rt_can_msg *)buf), fifo);
  647. }
  648. static const struct rt_can_ops _can_ops =
  649. {
  650. _can_config,
  651. _can_control,
  652. _can_sendmsg,
  653. _can_recvmsg,
  654. };
  655. static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
  656. {
  657. struct n32g45x_can *drv_can;
  658. RT_ASSERT(can != RT_NULL);
  659. drv_can = (struct n32g45x_can *)can->parent.user_data;
  660. RT_ASSERT(drv_can != RT_NULL);
  661. switch (fifo)
  662. {
  663. case CAN_FIFO0:
  664. /* save to user list */
  665. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFMP0) && CAN_PendingMessage(drv_can->CANx, CAN_FIFO0))
  666. {
  667. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  668. }
  669. /* Check FULL flag for FIFO0 */
  670. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFULL0))
  671. {
  672. /* Clear FIFO0 FULL Flag */
  673. CAN_ClearFlag(drv_can->CANx, CAN_FLAG_FFULL0);
  674. }
  675. /* Check Overrun flag for FIFO0 */
  676. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFOVR0))
  677. {
  678. /* Clear FIFO0 Overrun Flag */
  679. CAN_ClearFlag(drv_can->CANx, CAN_FLAG_FFOVR0);
  680. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  681. }
  682. break;
  683. case CAN_FIFO1:
  684. /* save to user list */
  685. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFMP1) && CAN_PendingMessage(drv_can->CANx, CAN_FIFO1))
  686. {
  687. rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
  688. }
  689. /* Check FULL flag for FIFO1 */
  690. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFULL1))
  691. {
  692. /* Clear FIFO1 FULL Flag */
  693. CAN_ClearFlag(drv_can->CANx, CAN_FLAG_FFULL1);
  694. }
  695. /* Check Overrun flag for FIFO1 */
  696. if (CAN_GetFlagSTS(drv_can->CANx, CAN_FLAG_FFOVR1))
  697. {
  698. /* Clear FIFO1 Overrun Flag */
  699. CAN_ClearFlag(drv_can->CANx, CAN_FLAG_FFOVR1);
  700. rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
  701. }
  702. break;
  703. }
  704. }
  705. #ifdef BSP_USING_CAN1
  706. /**
  707. * @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
  708. */
  709. #define CAN1_TX_IRQHandler USB_HP_CAN1_TX_IRQHandler
  710. void CAN1_TX_IRQHandler(void)
  711. {
  712. rt_interrupt_enter();
  713. if (CAN_GetFlagSTS(drv_can1.CANx, CAN_FLAG_RQCPM0))
  714. {
  715. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | (0x00 << 8));
  716. CAN_ClearFlag(drv_can1.CANx, CAN_FLAG_RQCPM0);
  717. }
  718. if (CAN_GetFlagSTS(drv_can1.CANx, CAN_FLAG_RQCPM1))
  719. {
  720. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | (0x01 << 8));
  721. CAN_ClearFlag(drv_can1.CANx, CAN_FLAG_RQCPM1);
  722. }
  723. if (CAN_GetFlagSTS(drv_can1.CANx, CAN_FLAG_RQCPM2))
  724. {
  725. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_DONE | (0x02 << 8));
  726. CAN_ClearFlag(drv_can1.CANx, CAN_FLAG_RQCPM2);
  727. }
  728. rt_interrupt_leave();
  729. }
  730. /**
  731. * @brief This function handles CAN1 RX0 interrupts.
  732. */
  733. #define CAN1_RX0_IRQHandler USB_LP_CAN1_RX0_IRQHandler
  734. void CAN1_RX0_IRQHandler(void)
  735. {
  736. rt_interrupt_enter();
  737. _can_rx_isr(&drv_can1.device, CAN_FIFO0);
  738. rt_interrupt_leave();
  739. }
  740. /**
  741. * @brief This function handles CAN1 RX1 interrupts.
  742. */
  743. void CAN1_RX1_IRQHandler(void)
  744. {
  745. rt_interrupt_enter();
  746. _can_rx_isr(&drv_can1.device, CAN_FIFO1);
  747. rt_interrupt_leave();
  748. }
  749. /**
  750. * @brief This function handles CAN1 SCE interrupts.
  751. */
  752. void CAN1_SCE_IRQHandler(void)
  753. {
  754. uint32_t errtype;
  755. rt_interrupt_enter();
  756. if (CAN_GetIntStatus(drv_can1.CANx, CAN_INT_ERR))
  757. {
  758. errtype = drv_can1.CANx->ESTS;
  759. // ESTS -> LEC
  760. switch ((errtype & 0x70) >> 4)
  761. {
  762. case RT_CAN_BUS_BIT_PAD_ERR:
  763. break;
  764. case RT_CAN_BUS_FORMAT_ERR:
  765. drv_can1.device.status.formaterrcnt++;
  766. break;
  767. case RT_CAN_BUS_ACK_ERR: /* attention !!! test ack err's unit is transmit unit */
  768. drv_can1.device.status.ackerrcnt++;
  769. if (!READ_BIT(drv_can1.CANx->TSTS, CAN_TSTS_TXOKM0))
  770. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  771. else if (!READ_BIT(drv_can1.CANx->TSTS, CAN_TSTS_TXOKM1))
  772. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  773. else if (!READ_BIT(drv_can1.CANx->TSTS, CAN_TSTS_TXOKM2))
  774. rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  775. break;
  776. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  777. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  778. drv_can1.device.status.biterrcnt++;
  779. break;
  780. case RT_CAN_BUS_CRC_ERR:
  781. drv_can1.device.status.crcerrcnt++;
  782. break;
  783. }
  784. drv_can1.device.status.lasterrtype = errtype & 0x70;
  785. drv_can1.device.status.rcverrcnt = errtype >> 24;
  786. drv_can1.device.status.snderrcnt = (errtype >> 16 & 0xFF);
  787. drv_can1.device.status.errcode = errtype & 0x07;
  788. CAN_ClearINTPendingBit(drv_can1.CANx, CAN_INT_ERR);
  789. }
  790. rt_interrupt_leave();
  791. }
  792. #endif /* BSP_USING_CAN1 */
  793. #ifdef BSP_USING_CAN2
  794. /**
  795. * @brief This function handles CAN2 TX interrupts.
  796. */
  797. void CAN2_TX_IRQHandler(void)
  798. {
  799. rt_interrupt_enter();
  800. if (CAN_GetFlagSTS(drv_can2.CANx, CAN_FLAG_RQCPM0))
  801. {
  802. CAN_ClearFlag(drv_can2.CANx, CAN_FLAG_RQCPM0);
  803. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | (0x00 << 8));
  804. }
  805. if (CAN_GetFlagSTS(drv_can2.CANx, CAN_FLAG_RQCPM1))
  806. {
  807. CAN_ClearFlag(drv_can2.CANx, CAN_FLAG_RQCPM1);
  808. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | (0x01 << 8));
  809. }
  810. if (CAN_GetFlagSTS(drv_can2.CANx, CAN_FLAG_RQCPM2))
  811. {
  812. CAN_ClearFlag(drv_can2.CANx, CAN_FLAG_RQCPM2);
  813. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_DONE | (0x02 << 8));
  814. }
  815. rt_interrupt_leave();
  816. }
  817. /**
  818. * @brief This function handles CAN2 RX0 interrupts.
  819. */
  820. void CAN2_RX0_IRQHandler(void)
  821. {
  822. rt_interrupt_enter();
  823. _can_rx_isr(&drv_can2.device, CAN_FIFO0);
  824. rt_interrupt_leave();
  825. }
  826. /**
  827. * @brief This function handles CAN2 RX1 interrupts.
  828. */
  829. void CAN2_RX1_IRQHandler(void)
  830. {
  831. rt_interrupt_enter();
  832. _can_rx_isr(&drv_can2.device, CAN_FIFO1);
  833. rt_interrupt_leave();
  834. }
  835. /**
  836. * @brief This function handles CAN2 SCE interrupts.
  837. */
  838. void CAN2_SCE_IRQHandler(void)
  839. {
  840. uint32_t errtype;
  841. rt_interrupt_enter();
  842. if (CAN_GetIntStatus(drv_can2.CANx, CAN_INT_ERR))
  843. {
  844. errtype = drv_can2.CANx->ESTS;
  845. // ESTS -> LEC
  846. switch ((errtype & 0x70) >> 4)
  847. {
  848. case RT_CAN_BUS_BIT_PAD_ERR:
  849. break;
  850. case RT_CAN_BUS_FORMAT_ERR:
  851. drv_can2.device.status.formaterrcnt++;
  852. break;
  853. case RT_CAN_BUS_ACK_ERR: /* attention !!! test ack err's unit is transmit unit */
  854. drv_can2.device.status.ackerrcnt++;
  855. if (!READ_BIT(drv_can2.CANx->TSTS, CAN_TSTS_TXOKM0))
  856. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  857. else if (!READ_BIT(drv_can2.CANx->TSTS, CAN_TSTS_TXOKM1))
  858. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  859. else if (!READ_BIT(drv_can2.CANx->TSTS, CAN_TSTS_TXOKM2))
  860. rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  861. break;
  862. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  863. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  864. drv_can2.device.status.biterrcnt++;
  865. break;
  866. case RT_CAN_BUS_CRC_ERR:
  867. drv_can2.device.status.crcerrcnt++;
  868. break;
  869. }
  870. drv_can2.device.status.lasterrtype = errtype & 0x70;
  871. drv_can2.device.status.rcverrcnt = errtype >> 24;
  872. drv_can2.device.status.snderrcnt = (errtype >> 16 & 0xFF);
  873. drv_can2.device.status.errcode = errtype & 0x07;
  874. CAN_ClearINTPendingBit(drv_can2.CANx, CAN_INT_ERR);
  875. }
  876. rt_interrupt_leave();
  877. }
  878. #endif /* BSP_USING_CAN2 */
  879. int rt_hw_can_init(void)
  880. {
  881. struct can_configure config = CANDEFAULTCONFIG;
  882. config.privmode = RT_CAN_MODE_NOPRIV;
  883. config.ticks = 50;
  884. #ifdef RT_CAN_USING_HDR
  885. config.maxhdr = 14;
  886. #ifdef CAN2
  887. config.maxhdr = 28;
  888. #endif
  889. #endif
  890. #ifdef BSP_USING_CAN1
  891. /* config default filter */
  892. drv_can1.can_filter_init.Filter_Num = 0;
  893. drv_can1.can_filter_init.Filter_Mode = CAN_Filter_IdMaskMode;
  894. drv_can1.can_filter_init.Filter_Scale = CAN_Filter_32bitScale;
  895. drv_can1.can_filter_init.Filter_HighId = 0x0000;
  896. drv_can1.can_filter_init.Filter_LowId = 0x0000;
  897. drv_can1.can_filter_init.FilterMask_HighId = 0;
  898. drv_can1.can_filter_init.FilterMask_LowId = 0;
  899. drv_can1.can_filter_init.Filter_FIFOAssignment = CAN_FIFO0;
  900. drv_can1.can_filter_init.Filter_Act = ENABLE;
  901. drv_can1.device.config = config;
  902. /* register CAN1 device */
  903. rt_hw_can_register(&drv_can1.device, drv_can1.name, &_can_ops, &drv_can1);
  904. #endif /* BSP_USING_CAN1 */
  905. #ifdef BSP_USING_CAN2
  906. /* config default filter */
  907. drv_can2.can_filter_init.Filter_Num = 0;
  908. drv_can2.can_filter_init.Filter_Mode = CAN_Filter_IdMaskMode;
  909. drv_can2.can_filter_init.Filter_Scale = CAN_Filter_32bitScale;
  910. drv_can2.can_filter_init.Filter_HighId = 0x0000;
  911. drv_can2.can_filter_init.Filter_LowId = 0x0000;
  912. drv_can2.can_filter_init.FilterMask_HighId = 0;
  913. drv_can2.can_filter_init.FilterMask_LowId = 0;
  914. drv_can2.can_filter_init.Filter_FIFOAssignment = CAN_FIFO0;
  915. drv_can2.can_filter_init.Filter_Act = ENABLE;
  916. drv_can2.device.config = config;
  917. /* register CAN2 device */
  918. rt_hw_can_register(&drv_can2.device, drv_can2.name, &_can_ops, &drv_can2);
  919. #endif /* BSP_USING_CAN2 */
  920. return 0;
  921. }
  922. INIT_BOARD_EXPORT(rt_hw_can_init);
  923. #endif /* BSP_USING_CAN */
  924. /************************** end of file ******************/