drv_can.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-08-05 Xeon Xu the first version
  9. * 2019-01-22 YLZ port from stm324xx-HAL to bsp stm3210x-HAL
  10. * 2019-02-19 YLZ add support EXTID RTR Frame. modify send, recv functions.
  11. * fix bug.port to BSP [stm32]
  12. */
  13. #include "drv_can.h"
  14. #ifdef RT_USING_CAN
  15. #if defined (SOC_SERIES_STM32F1)
  16. static const struct stm_baud_rate_tab can_baud_rate_tab[] =
  17. {
  18. {CAN1MBaud , (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 3)},
  19. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_3TQ | 5)},
  20. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 6)},
  21. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 12)},
  22. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 24)},
  23. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 30)},
  24. {CAN50kBaud , (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 60)},
  25. {CAN20kBaud , (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)},
  26. {CAN10kBaud , (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}
  27. };
  28. #elif defined (SOC_SERIES_STM32F4)
  29. static const struct stm_baud_rate_tab can_baud_rate_tab[] =
  30. {
  31. {CAN1MBaud , (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)},
  32. {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_4TQ | 4)},
  33. {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 6)},
  34. {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 12)},
  35. {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 24)},
  36. {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 30)},
  37. {CAN50kBaud , (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 60)},
  38. {CAN20kBaud , (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 150)},
  39. {CAN10kBaud , (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 300)}
  40. };
  41. #endif
  42. #define BAUD_DATA(TYPE,NO) \
  43. ((can_baud_rate_tab[NO].confdata & TYPE##MASK))
  44. static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
  45. {
  46. rt_uint32_t len, index, default_index;
  47. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  48. default_index = len;
  49. for(index = 0; index < len; index++)
  50. {
  51. if(can_baud_rate_tab[index].baud_rate == baud)
  52. return index;
  53. if(can_baud_rate_tab[index].baud_rate == 1000UL * 250)
  54. default_index = index;
  55. }
  56. if(default_index != len)
  57. return default_index;
  58. return 0;
  59. }
  60. #ifdef BSP_USING_CAN1
  61. static struct stm32_drv_can drv_can1;
  62. struct rt_can_device dev_can1;
  63. /**
  64. * @brief This function handles CAN1 TX interrupts.
  65. */
  66. void CAN1_TX_IRQHandler(void)
  67. {
  68. rt_interrupt_enter();
  69. CAN_HandleTypeDef *hcan;
  70. hcan = &drv_can1.CanHandle;
  71. if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0))
  72. {
  73. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
  74. {
  75. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_DONE | 0 << 8);
  76. }
  77. else
  78. {
  79. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  80. }
  81. /* Write 0 to Clear transmission status flag RQCPx */
  82. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
  83. }
  84. else if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1))
  85. {
  86. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
  87. {
  88. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_DONE | 1 << 8);
  89. }
  90. else
  91. {
  92. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  93. }
  94. /* Write 0 to Clear transmission status flag RQCPx */
  95. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
  96. }
  97. else if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2))
  98. {
  99. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
  100. {
  101. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_DONE | 2 << 8);
  102. }
  103. else
  104. {
  105. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  106. }
  107. /* Write 0 to Clear transmission status flag RQCPx */
  108. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
  109. }
  110. rt_interrupt_leave();
  111. }
  112. /**
  113. * @brief This function handles CAN1 RX0 interrupts.
  114. */
  115. void CAN1_RX0_IRQHandler(void)
  116. {
  117. rt_interrupt_enter();
  118. CanRxMsgTypeDef* pRxMsg = NULL;
  119. CAN_HandleTypeDef *hcan;
  120. hcan = &drv_can1.CanHandle;
  121. /* check FMP0 and get data */
  122. while (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0) != RESET)
  123. {
  124. /* beigin get data */
  125. /* Set RxMsg pointer */
  126. pRxMsg = hcan->pRxMsg;
  127. /* Get the Id */
  128. pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR;
  129. if (pRxMsg->IDE == CAN_ID_STD)
  130. {
  131. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR >> 21U);
  132. }
  133. else
  134. {
  135. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR >> 3U);
  136. }
  137. pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR;
  138. /* Get the DLC */
  139. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDTR;
  140. /* Get the FIFONumber */
  141. pRxMsg->FIFONumber = CAN_FIFO0;
  142. /* Get the FMI */
  143. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDTR >> 8U);
  144. /* Get the data field */
  145. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR;
  146. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 8U);
  147. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 16U);
  148. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 24U);
  149. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR;
  150. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 8U);
  151. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 16U);
  152. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 24U);
  153. /* Release FIFO0 */
  154. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  155. /* end get data */
  156. /* save to user fifo */
  157. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_RX_IND | 0 << 8);
  158. }
  159. /* Check Overrun flag for FIFO0 */
  160. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FF0) != RESET)
  161. {
  162. /* Clear FIFO0 FULL Flag */
  163. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
  164. }
  165. /* Check Overrun flag for FIFO0 */
  166. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0) != RESET)
  167. {
  168. /* Clear FIFO0 Overrun Flag */
  169. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
  170. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_RXOF_IND | 0 << 8);
  171. }
  172. rt_interrupt_leave();
  173. }
  174. /**
  175. * @brief This function handles CAN1 RX1 interrupts.
  176. */
  177. void CAN1_RX1_IRQHandler(void)
  178. {
  179. rt_interrupt_enter();
  180. CanRxMsgTypeDef* pRxMsg = NULL;
  181. CAN_HandleTypeDef *hcan;
  182. hcan = &drv_can1.CanHandle;
  183. /* check FMP1 and get data */
  184. while (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1) != RESET)
  185. {
  186. /* beigin get data */
  187. /* Set RxMsg pointer */
  188. pRxMsg = hcan->pRx1Msg;
  189. /* Get the Id */
  190. pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR;
  191. if (pRxMsg->IDE == CAN_ID_STD)
  192. {
  193. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR >> 21U);
  194. }
  195. else
  196. {
  197. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR >> 3U);
  198. }
  199. pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR;
  200. /* Get the DLC */
  201. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDTR;
  202. /* Get the FIFONumber */
  203. pRxMsg->FIFONumber = CAN_FIFO1;
  204. /* Get the FMI */
  205. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDTR >> 8U);
  206. /* Get the data field */
  207. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR;
  208. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 8U);
  209. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 16U);
  210. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 24U);
  211. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR;
  212. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 8U);
  213. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 16U);
  214. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 24U);
  215. /* Release FIFO1 */
  216. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  217. /* end get data */
  218. /* save to user fifo */
  219. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_RX_IND | 1 << 8);
  220. }
  221. /* Check Overrun flag for FIFO1 */
  222. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FF1) != RESET)
  223. {
  224. /* Clear FIFO1 FULL Flag */
  225. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
  226. }
  227. /* Check Overrun flag for FIFO1 */
  228. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1) != RESET)
  229. {
  230. /* Clear FIFO1 Overrun Flag */
  231. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
  232. rt_hw_can_isr(&dev_can1, RT_CAN_EVENT_RXOF_IND | 1 << 8);
  233. }
  234. rt_interrupt_leave();
  235. }
  236. /**
  237. * @brief This function handles CAN1 SCE interrupts.
  238. */
  239. void CAN1_SCE_IRQHandler(void)
  240. {
  241. rt_uint32_t errtype;
  242. CAN_HandleTypeDef *hcan;
  243. hcan = &drv_can1.CanHandle;
  244. errtype = hcan->Instance->ESR;
  245. rt_interrupt_enter();
  246. HAL_CAN_IRQHandler(hcan);
  247. if (errtype & 0x70 && dev_can1.status.lasterrtype == (errtype & 0x70))
  248. {
  249. switch ((errtype & 0x70) >> 4)
  250. {
  251. case RT_CAN_BUS_BIT_PAD_ERR:
  252. dev_can1.status.bitpaderrcnt++;
  253. break;
  254. case RT_CAN_BUS_FORMAT_ERR:
  255. dev_can1.status.formaterrcnt++;
  256. break;
  257. case RT_CAN_BUS_ACK_ERR:
  258. dev_can1.status.ackerrcnt++;
  259. break;
  260. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  261. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  262. dev_can1.status.biterrcnt++;
  263. break;
  264. case RT_CAN_BUS_CRC_ERR:
  265. dev_can1.status.crcerrcnt++;
  266. break;
  267. }
  268. dev_can1.status.lasterrtype = errtype & 0x70;
  269. hcan->Instance->ESR &= ~0x70;
  270. }
  271. dev_can1.status.rcverrcnt = errtype >> 24;
  272. dev_can1.status.snderrcnt = (errtype >> 16 & 0xFF);
  273. dev_can1.status.errcode = errtype & 0x07;
  274. hcan->Instance->MSR |= CAN_MSR_ERRI;
  275. rt_interrupt_leave();
  276. }
  277. #endif /* BSP_USING_CAN1 */
  278. #ifdef BSP_USING_CAN2
  279. static struct stm32_drv_can drv_can2;
  280. struct rt_can_device dev_can2;
  281. /**
  282. * @brief This function handles CAN2 TX interrupts.
  283. */
  284. void CAN2_TX_IRQHandler(void)
  285. {
  286. rt_interrupt_enter();
  287. CAN_HandleTypeDef *hcan;
  288. hcan = &drv_can2.CanHandle;
  289. if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0))
  290. {
  291. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
  292. {
  293. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_DONE | 0 << 8);
  294. }
  295. else
  296. {
  297. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_FAIL | 0 << 8);
  298. }
  299. /* Write 0 to Clear transmission status flag RQCPx */
  300. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
  301. }
  302. else if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1))
  303. {
  304. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
  305. {
  306. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_DONE | 1 << 8);
  307. }
  308. else
  309. {
  310. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_FAIL | 1 << 8);
  311. }
  312. /* Write 0 to Clear transmission status flag RQCPx */
  313. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
  314. }
  315. else if (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2))
  316. {
  317. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
  318. {
  319. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_DONE | 2 << 8);
  320. }
  321. else
  322. {
  323. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_TX_FAIL | 2 << 8);
  324. }
  325. /* Write 0 to Clear transmission status flag RQCPx */
  326. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
  327. }
  328. rt_interrupt_leave();
  329. }
  330. /**
  331. * @brief This function handles CAN2 RX0 interrupts.
  332. */
  333. void CAN2_RX0_IRQHandler(void)
  334. {
  335. rt_interrupt_enter();
  336. CanRxMsgTypeDef* pRxMsg = NULL;
  337. CAN_HandleTypeDef *hcan;
  338. hcan = &drv_can2.CanHandle;
  339. /* check FMP0 and get data */
  340. while (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0) != RESET)
  341. {
  342. /* beigin get data */
  343. /* Set RxMsg pointer */
  344. pRxMsg = hcan->pRxMsg;
  345. /* Get the Id */
  346. pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR;
  347. if (pRxMsg->IDE == CAN_ID_STD)
  348. {
  349. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR >> 21U);
  350. }
  351. else
  352. {
  353. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR >> 3U);
  354. }
  355. pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RIR;
  356. /* Get the DLC */
  357. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDTR;
  358. /* Get the FIFONumber */
  359. pRxMsg->FIFONumber = CAN_FIFO0;
  360. /* Get the FMI */
  361. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDTR >> 8U);
  362. /* Get the data field */
  363. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR;
  364. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 8U);
  365. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 16U);
  366. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDLR >> 24U);
  367. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR;
  368. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 8U);
  369. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 16U);
  370. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO0].RDHR >> 24U);
  371. /* Release FIFO0 */
  372. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  373. /* end get data */
  374. /* save to user fifo */
  375. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_RX_IND | 0 << 8);
  376. }
  377. /* Check Overrun flag for FIFO0 */
  378. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FF0) != RESET)
  379. {
  380. /* Clear FIFO0 FULL Flag */
  381. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
  382. }
  383. /* Check Overrun flag for FIFO0 */
  384. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0) != RESET)
  385. {
  386. /* Clear FIFO0 Overrun Flag */
  387. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
  388. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_RXOF_IND | 0 << 8);
  389. }
  390. rt_interrupt_leave();
  391. }
  392. /**
  393. * @brief This function handles CAN2 RX1 interrupts.
  394. */
  395. void CAN2_RX1_IRQHandler(void)
  396. {
  397. rt_interrupt_enter();
  398. CanRxMsgTypeDef* pRxMsg = NULL;
  399. CAN_HandleTypeDef *hcan;
  400. hcan = &drv_can2.CanHandle;
  401. /* check FMP1 and get data */
  402. while (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1) != RESET)
  403. {
  404. /* beigin get data */
  405. /* Set RxMsg pointer */
  406. pRxMsg = hcan->pRx1Msg;
  407. /* Get the Id */
  408. pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR;
  409. if (pRxMsg->IDE == CAN_ID_STD)
  410. {
  411. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR >> 21U);
  412. }
  413. else
  414. {
  415. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR >> 3U);
  416. }
  417. pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RIR;
  418. /* Get the DLC */
  419. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDTR;
  420. /* Get the FIFONumber */
  421. pRxMsg->FIFONumber = CAN_FIFO1;
  422. /* Get the FMI */
  423. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDTR >> 8U);
  424. /* Get the data field */
  425. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR;
  426. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 8U);
  427. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 16U);
  428. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDLR >> 24U);
  429. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR;
  430. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 8U);
  431. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 16U);
  432. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[CAN_FIFO1].RDHR >> 24U);
  433. /* Release FIFO1 */
  434. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  435. /* end get data */
  436. /* save to user fifo */
  437. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_RX_IND | 1 << 8);
  438. }
  439. /* Check Overrun flag for FIFO1 */
  440. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FF1) != RESET)
  441. {
  442. /* Clear FIFO1 FULL Flag */
  443. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
  444. }
  445. /* Check Overrun flag for FIFO1 */
  446. if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1) != RESET && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1) != RESET)
  447. {
  448. /* Clear FIFO1 Overrun Flag */
  449. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
  450. rt_hw_can_isr(&dev_can2, RT_CAN_EVENT_RXOF_IND | 1 << 8);
  451. }
  452. rt_interrupt_leave();
  453. }
  454. /**
  455. * @brief This function handles CAN2 SCE interrupts.
  456. */
  457. void CAN2_SCE_IRQHandler(void)
  458. {
  459. rt_uint32_t errtype;
  460. CAN_HandleTypeDef *hcan;
  461. hcan = &drv_can2.CanHandle;
  462. errtype = hcan->Instance->ESR;
  463. rt_interrupt_enter();
  464. HAL_CAN_IRQHandler(hcan);
  465. if (errtype & 0x70 && dev_can2.status.lasterrtype == (errtype & 0x70))
  466. {
  467. switch ((errtype & 0x70) >> 4)
  468. {
  469. case RT_CAN_BUS_BIT_PAD_ERR:
  470. dev_can2.status.bitpaderrcnt++;
  471. break;
  472. case RT_CAN_BUS_FORMAT_ERR:
  473. dev_can2.status.formaterrcnt++;
  474. break;
  475. case RT_CAN_BUS_ACK_ERR:
  476. dev_can2.status.ackerrcnt++;
  477. break;
  478. case RT_CAN_BUS_IMPLICIT_BIT_ERR:
  479. case RT_CAN_BUS_EXPLICIT_BIT_ERR:
  480. dev_can2.status.biterrcnt++;
  481. break;
  482. case RT_CAN_BUS_CRC_ERR:
  483. dev_can2.status.crcerrcnt++;
  484. break;
  485. }
  486. dev_can2.status.lasterrtype = errtype & 0x70;
  487. hcan->Instance->ESR &= ~0x70;
  488. }
  489. dev_can2.status.rcverrcnt = errtype >> 24;
  490. dev_can2.status.snderrcnt = (errtype >> 16 & 0xFF);
  491. dev_can2.status.errcode = errtype & 0x07;
  492. hcan->Instance->MSR |= CAN_MSR_ERRI;
  493. rt_interrupt_leave();
  494. }
  495. #endif /* BSP_USING_CAN2 */
  496. /**
  497. * @brief Error CAN callback.
  498. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  499. * the configuration information for the specified CAN.
  500. * @retval None
  501. */
  502. void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  503. {
  504. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  505. CAN_IT_EPV |
  506. CAN_IT_BOF |
  507. CAN_IT_LEC |
  508. CAN_IT_ERR |
  509. CAN_IT_FMP0|
  510. CAN_IT_FOV0|
  511. CAN_IT_FMP1|
  512. CAN_IT_FOV1|
  513. CAN_IT_TME);
  514. }
  515. static rt_err_t drv_configure(struct rt_can_device *dev_can,
  516. struct can_configure *cfg)
  517. {
  518. struct stm32_drv_can *drv_can;
  519. rt_uint32_t baud_index;
  520. CAN_InitTypeDef *drv_init;
  521. CAN_FilterConfTypeDef *filterConf;
  522. RT_ASSERT(dev_can);
  523. RT_ASSERT(cfg);
  524. drv_can = (struct stm32_drv_can *)dev_can->parent.user_data;
  525. drv_init = &drv_can->CanHandle.Init;
  526. drv_init->TTCM = DISABLE;
  527. drv_init->ABOM = DISABLE;
  528. drv_init->AWUM = DISABLE;
  529. drv_init->NART = DISABLE;
  530. drv_init->RFLM = DISABLE;
  531. drv_init->TXFP = DISABLE;
  532. switch (cfg->mode)
  533. {
  534. case RT_CAN_MODE_NORMAL:
  535. drv_init->Mode = CAN_MODE_NORMAL;
  536. break;
  537. case RT_CAN_MODE_LISEN:
  538. drv_init->Mode = CAN_MODE_SILENT;
  539. break;
  540. case RT_CAN_MODE_LOOPBACK:
  541. drv_init->Mode = CAN_MODE_LOOPBACK;
  542. break;
  543. case RT_CAN_MODE_LOOPBACKANLISEN:
  544. drv_init->Mode = CAN_MODE_SILENT_LOOPBACK;
  545. break;
  546. }
  547. baud_index = get_can_baud_index(cfg->baud_rate);
  548. drv_init->SJW = BAUD_DATA(SJW, baud_index);
  549. drv_init->BS1 = BAUD_DATA(BS1, baud_index);
  550. drv_init->BS2 = BAUD_DATA(BS2, baud_index);
  551. drv_init->Prescaler = BAUD_DATA(RRESCL, baud_index);
  552. if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
  553. {
  554. return RT_ERROR;
  555. }
  556. /* Filter conf */
  557. filterConf = &drv_can->FilterConfig;
  558. filterConf->FilterNumber = 0;
  559. filterConf->FilterMode = CAN_FILTERMODE_IDMASK;
  560. filterConf->FilterScale = CAN_FILTERSCALE_32BIT;
  561. filterConf->FilterIdHigh = 0x0000;
  562. filterConf->FilterIdLow = 0x0000;
  563. filterConf->FilterMaskIdHigh = 0x0000;
  564. filterConf->FilterMaskIdLow = 0x0000;
  565. filterConf->FilterFIFOAssignment = CAN_FIFO0;
  566. filterConf->FilterActivation = ENABLE;
  567. filterConf->BankNumber = 14;
  568. HAL_CAN_ConfigFilter(&drv_can->CanHandle, filterConf);
  569. return RT_EOK;
  570. }
  571. static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
  572. {
  573. struct stm32_drv_can *drv_can;
  574. rt_uint32_t argval;
  575. drv_can = (struct stm32_drv_can *) can->parent.user_data;
  576. assert_param(drv_can != RT_NULL);
  577. switch (cmd)
  578. {
  579. case RT_DEVICE_CTRL_CLR_INT:
  580. argval = (rt_uint32_t) arg;
  581. if (argval == RT_DEVICE_FLAG_INT_RX)
  582. {
  583. if (CAN1 == drv_can->CanHandle.Instance) {
  584. HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
  585. HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
  586. }
  587. #ifdef CAN2
  588. else
  589. {
  590. HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
  591. HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
  592. }
  593. #endif
  594. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FMP0);
  595. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FF0 );
  596. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FOV0);
  597. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FMP1);
  598. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FF1 );
  599. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_FOV1);
  600. }
  601. else if (argval == RT_DEVICE_FLAG_INT_TX)
  602. {
  603. if (CAN1 == drv_can->CanHandle.Instance)
  604. {
  605. HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
  606. }
  607. #ifdef CAN2
  608. else
  609. {
  610. HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
  611. }
  612. #endif
  613. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_TME);
  614. }
  615. else if (argval == RT_DEVICE_CAN_INT_ERR)
  616. {
  617. if (CAN1 == drv_can->CanHandle.Instance)
  618. {
  619. NVIC_DisableIRQ(CAN1_SCE_IRQn);
  620. }
  621. #ifdef CAN2
  622. else
  623. {
  624. NVIC_DisableIRQ(CAN2_SCE_IRQn);
  625. }
  626. #endif
  627. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_BOF);
  628. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_LEC);
  629. __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERR);
  630. }
  631. break;
  632. case RT_DEVICE_CTRL_SET_INT:
  633. argval = (rt_uint32_t) arg;
  634. if (argval == RT_DEVICE_FLAG_INT_RX)
  635. {
  636. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FMP0);
  637. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FF0);
  638. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FOV0);
  639. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FMP1);
  640. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FF1);
  641. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_FOV1);
  642. if (CAN1 == drv_can->CanHandle.Instance)
  643. {
  644. HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
  645. HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  646. HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
  647. HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
  648. }
  649. #ifdef CAN2
  650. else
  651. {
  652. HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
  653. HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
  654. HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 1, 0);
  655. HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
  656. }
  657. #endif
  658. }
  659. else if (argval == RT_DEVICE_FLAG_INT_TX)
  660. {
  661. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_TME);
  662. if (CAN1 == drv_can->CanHandle.Instance)
  663. {
  664. HAL_NVIC_SetPriority(CAN1_TX_IRQn, 1, 0);
  665. HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
  666. }
  667. #ifdef CAN2
  668. else
  669. {
  670. HAL_NVIC_SetPriority(CAN2_TX_IRQn, 1, 0);
  671. HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
  672. }
  673. #endif
  674. }
  675. else if (argval == RT_DEVICE_CAN_INT_ERR)
  676. {
  677. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_BOF);
  678. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_LEC);
  679. __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERR);
  680. if (CAN1 == drv_can->CanHandle.Instance)
  681. {
  682. HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
  683. HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  684. }
  685. #ifdef CAN2
  686. else
  687. {
  688. HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 1, 0);
  689. HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
  690. }
  691. #endif
  692. }
  693. break;
  694. case RT_CAN_CMD_SET_FILTER:
  695. /* TODO: filter*/
  696. break;
  697. case RT_CAN_CMD_SET_MODE:
  698. argval = (rt_uint32_t) arg;
  699. if (argval != RT_CAN_MODE_NORMAL ||
  700. argval != RT_CAN_MODE_LISEN ||
  701. argval != RT_CAN_MODE_LOOPBACK ||
  702. argval != RT_CAN_MODE_LOOPBACKANLISEN)
  703. {
  704. return RT_ERROR;
  705. }
  706. if (argval != can->config.mode)
  707. {
  708. can->config.mode = argval;
  709. if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
  710. {
  711. return RT_ERROR;
  712. }
  713. }
  714. break;
  715. case RT_CAN_CMD_SET_BAUD:
  716. argval = (rt_uint32_t) arg;
  717. if (argval != CAN1MBaud &&
  718. argval != CAN800kBaud &&
  719. argval != CAN500kBaud &&
  720. argval != CAN250kBaud &&
  721. argval != CAN125kBaud &&
  722. argval != CAN100kBaud &&
  723. argval != CAN50kBaud &&
  724. argval != CAN20kBaud &&
  725. argval != CAN10kBaud)
  726. {
  727. return RT_ERROR;
  728. }
  729. if (argval != can->config.baud_rate)
  730. {
  731. CAN_InitTypeDef *drv_init;
  732. rt_uint32_t baud_index;
  733. can->config.baud_rate = argval;
  734. drv_init = &drv_can->CanHandle.Init;
  735. drv_init->TTCM = DISABLE;
  736. drv_init->ABOM = DISABLE;
  737. drv_init->AWUM = DISABLE;
  738. drv_init->NART = DISABLE;
  739. drv_init->RFLM = DISABLE;
  740. drv_init->TXFP = DISABLE;
  741. baud_index = get_can_baud_index(can->config.baud_rate);
  742. drv_init->SJW = BAUD_DATA(SJW, baud_index);
  743. drv_init->BS1 = BAUD_DATA(BS1, baud_index);
  744. drv_init->BS2 = BAUD_DATA(BS2, baud_index);
  745. drv_init->Prescaler = BAUD_DATA(RRESCL, baud_index);
  746. if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
  747. {
  748. return RT_ERROR;
  749. }
  750. }
  751. break;
  752. case RT_CAN_CMD_SET_PRIV:
  753. argval = (rt_uint32_t) arg;
  754. if (argval != RT_CAN_MODE_PRIV ||
  755. argval != RT_CAN_MODE_NOPRIV)
  756. {
  757. return RT_ERROR;
  758. }
  759. if (argval != can->config.privmode)
  760. {
  761. can->config.privmode = argval;
  762. if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
  763. {
  764. return RT_ERROR;
  765. }
  766. }
  767. break;
  768. case RT_CAN_CMD_GET_STATUS:
  769. {
  770. rt_uint32_t errtype;
  771. errtype = drv_can->CanHandle.Instance->ESR;
  772. can->status.rcverrcnt = errtype >> 24;
  773. can->status.snderrcnt = (errtype >> 16 & 0xFF);
  774. can->status.errcode = errtype & 0x07;
  775. if (arg != &can->status)
  776. {
  777. rt_memcpy(arg, &can->status, sizeof(can->status));
  778. }
  779. }
  780. break;
  781. }
  782. return RT_EOK;
  783. }
  784. static int drv_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
  785. {
  786. CAN_HandleTypeDef *hcan = RT_NULL;
  787. hcan = &((struct stm32_drv_can *) can->parent.user_data)->CanHandle;
  788. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  789. /*check Select mailbox is empty */
  790. switch (boxno)
  791. {
  792. case CAN_TXMAILBOX_0:
  793. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
  794. {
  795. /* Change CAN state */
  796. hcan->State = HAL_CAN_STATE_ERROR;
  797. /* Return function status */
  798. return -RT_ERROR;
  799. }
  800. break;
  801. case CAN_TXMAILBOX_1:
  802. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
  803. {
  804. /* Change CAN state */
  805. hcan->State = HAL_CAN_STATE_ERROR;
  806. /* Return function status */
  807. return -RT_ERROR;
  808. }
  809. break;
  810. case CAN_TXMAILBOX_2:
  811. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
  812. {
  813. /* Change CAN state */
  814. hcan->State = HAL_CAN_STATE_ERROR;
  815. /* Return function status */
  816. return -RT_ERROR;
  817. }
  818. break;
  819. default:
  820. RT_ASSERT(0);
  821. break;
  822. }
  823. /* check id type */
  824. if (RT_CAN_STDID == pmsg->ide)
  825. {
  826. hcan->pTxMsg->IDE = CAN_ID_STD;
  827. hcan->pTxMsg->StdId = pmsg->id;
  828. hcan->pTxMsg->ExtId = 0xFFFFFFFFU;
  829. }
  830. else if (RT_CAN_EXTID == pmsg->ide)
  831. {
  832. hcan->pTxMsg->IDE = CAN_ID_EXT;
  833. hcan->pTxMsg->StdId = 0xFFFFFFFFU;
  834. hcan->pTxMsg->ExtId = pmsg->id;
  835. }
  836. /* check frame type */
  837. if (RT_CAN_DTR == pmsg->rtr)
  838. {
  839. hcan->pTxMsg->RTR = CAN_RTR_DATA;
  840. }
  841. else if (RT_CAN_RTR == pmsg->rtr)
  842. {
  843. hcan->pTxMsg->RTR = CAN_RTR_REMOTE;
  844. }
  845. hcan->pTxMsg->DLC = pmsg->len;
  846. /* copy user data to hcan */
  847. hcan->pTxMsg->Data[0] = pmsg->data[0];
  848. hcan->pTxMsg->Data[1] = pmsg->data[1];
  849. hcan->pTxMsg->Data[2] = pmsg->data[2];
  850. hcan->pTxMsg->Data[3] = pmsg->data[3];
  851. hcan->pTxMsg->Data[4] = pmsg->data[4];
  852. hcan->pTxMsg->Data[5] = pmsg->data[5];
  853. hcan->pTxMsg->Data[6] = pmsg->data[6];
  854. hcan->pTxMsg->Data[7] = pmsg->data[7];
  855. /* clear TIR */
  856. hcan->Instance->sTxMailBox[boxno].TIR &= CAN_TI0R_TXRQ;
  857. /* Set up the Id */
  858. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  859. {
  860. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  861. hcan->Instance->sTxMailBox[boxno].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
  862. hcan->pTxMsg->RTR);
  863. }
  864. else
  865. {
  866. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  867. hcan->Instance->sTxMailBox[boxno].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
  868. hcan->pTxMsg->IDE |
  869. hcan->pTxMsg->RTR);
  870. }
  871. /* Set up the DLC */
  872. hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
  873. hcan->Instance->sTxMailBox[boxno].TDTR &= 0xFFFFFFF0U;
  874. hcan->Instance->sTxMailBox[boxno].TDTR |= hcan->pTxMsg->DLC;
  875. /* Set up the data field */
  876. WRITE_REG(hcan->Instance->sTxMailBox[boxno].TDLR, ((uint32_t)hcan->pTxMsg->Data[3U] << CAN_TDL0R_DATA3_Pos) |
  877. ((uint32_t)hcan->pTxMsg->Data[2U] << CAN_TDL0R_DATA2_Pos) |
  878. ((uint32_t)hcan->pTxMsg->Data[1U] << CAN_TDL0R_DATA1_Pos) |
  879. ((uint32_t)hcan->pTxMsg->Data[0U] << CAN_TDL0R_DATA0_Pos));
  880. WRITE_REG(hcan->Instance->sTxMailBox[boxno].TDHR, ((uint32_t)hcan->pTxMsg->Data[7U] << CAN_TDL0R_DATA3_Pos) |
  881. ((uint32_t)hcan->pTxMsg->Data[6U] << CAN_TDL0R_DATA2_Pos) |
  882. ((uint32_t)hcan->pTxMsg->Data[5U] << CAN_TDL0R_DATA1_Pos) |
  883. ((uint32_t)hcan->pTxMsg->Data[4U] << CAN_TDL0R_DATA0_Pos));
  884. /* Request transmission */
  885. hcan->Instance->sTxMailBox[boxno].TIR |= CAN_TI0R_TXRQ;
  886. return RT_EOK;
  887. }
  888. static int drv_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
  889. {
  890. CAN_HandleTypeDef *hcan;
  891. struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
  892. hcan = &((struct stm32_drv_can *) can->parent.user_data)->CanHandle;
  893. CanRxMsgTypeDef *pRxMsg = RT_NULL;
  894. /* get FIFO */
  895. switch (boxno)
  896. {
  897. case CAN_FIFO0:
  898. pRxMsg = hcan->pRxMsg;
  899. break;
  900. case CAN_FIFO1:
  901. pRxMsg = hcan->pRx1Msg;
  902. break;
  903. default:
  904. RT_ASSERT(0);
  905. break;
  906. }
  907. /* copy data */
  908. /* get id */
  909. if (CAN_ID_STD == pRxMsg->IDE)
  910. {
  911. pmsg->ide = RT_CAN_STDID;
  912. pmsg->id = pRxMsg->StdId;
  913. }
  914. else if (CAN_ID_EXT == pRxMsg->IDE)
  915. {
  916. pmsg->ide = RT_CAN_EXTID;
  917. pmsg->id = pRxMsg->ExtId;
  918. }
  919. /* get type */
  920. if (CAN_RTR_DATA == pRxMsg->RTR)
  921. {
  922. pmsg->rtr = RT_CAN_DTR;
  923. }
  924. else if (CAN_RTR_REMOTE == pRxMsg->RTR)
  925. {
  926. pmsg->rtr = RT_CAN_RTR;
  927. }
  928. /* get len */
  929. pmsg->len = pRxMsg->DLC;
  930. /* get hdr */
  931. pmsg->hdr = pRxMsg->FMI;
  932. /* get data */
  933. pmsg->data[0] = pRxMsg->Data[0];
  934. pmsg->data[1] = pRxMsg->Data[1];
  935. pmsg->data[2] = pRxMsg->Data[2];
  936. pmsg->data[3] = pRxMsg->Data[3];
  937. pmsg->data[4] = pRxMsg->Data[4];
  938. pmsg->data[5] = pRxMsg->Data[5];
  939. pmsg->data[6] = pRxMsg->Data[6];
  940. pmsg->data[7] = pRxMsg->Data[7];
  941. return RT_EOK;
  942. }
  943. static const struct rt_can_ops drv_can_ops =
  944. {
  945. drv_configure,
  946. drv_control,
  947. drv_sendmsg,
  948. drv_recvmsg,
  949. };
  950. int rt_hw_can_init(void)
  951. {
  952. struct stm32_drv_can *drv_can;
  953. struct can_configure config = CANDEFAULTCONFIG;
  954. config.privmode = 0;
  955. config.ticks = 50;
  956. config.sndboxnumber = 3;
  957. config.msgboxsz = 32;
  958. #ifdef RT_CAN_USING_HDR
  959. config.maxhdr = 14;
  960. #ifdef CAN2
  961. config.maxhdr = 28;
  962. #endif
  963. #endif
  964. #ifdef BSP_USING_CAN1
  965. drv_can = &drv_can1;
  966. drv_can->CanHandle.Instance = CAN1;
  967. drv_can->CanHandle.pTxMsg = &drv_can->TxMessage;
  968. drv_can->CanHandle.pRxMsg = &drv_can->RxMessage;
  969. drv_can->CanHandle.pRx1Msg = &drv_can->Rx1Message;
  970. dev_can1.ops = &drv_can_ops;
  971. dev_can1.config = config;
  972. /* register CAN1 device */
  973. rt_hw_can_register(&dev_can1, "can1",
  974. &drv_can_ops,
  975. drv_can);
  976. #endif /* BSP_USING_CAN1 */
  977. #ifdef BSP_USING_CAN2
  978. drv_can = &drv_can2;
  979. drv_can->CanHandle.Instance = CAN2;
  980. drv_can->CanHandle.pTxMsg = &drv_can->TxMessage;
  981. drv_can->CanHandle.pRxMsg = &drv_can->RxMessage;
  982. drv_can->CanHandle.pRx1Msg = &drv_can->Rx1Message;
  983. dev_can2.ops = &drv_can_ops;
  984. dev_can2.config = config;
  985. /* register CAN2 device */
  986. rt_hw_can_register(&dev_can2, "can2",
  987. &drv_can_ops,
  988. drv_can);
  989. #endif /* BSP_USING_CAN2 */
  990. return 0;
  991. }
  992. INIT_BOARD_EXPORT(rt_hw_can_init);
  993. #endif /* RT_USING_CAN */