drv_can.c 37 KB

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