ch32v30x_can.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : ch32v30x_can.c
  3. * Author : WCH
  4. * Version : V1.0.1
  5. * Date : 2025/04/06
  6. * Description : This file provides all the CAN firmware functions.
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/
  12. #include "ch32v30x_can.h"
  13. #include "ch32v30x_rcc.h"
  14. /* CAN CTLR Register bits */
  15. #define CTLR_DBF ((uint32_t)0x00010000)
  16. /* CAN Mailbox Transmit Request */
  17. #define TMIDxR_TXRQ ((uint32_t)0x00000001)
  18. /* CAN FCTLR Register bits */
  19. #define FCTLR_FINIT ((uint32_t)0x00000001)
  20. /* Time out for INAK bit */
  21. #define INAK_TIMEOUT ((uint32_t)0x0000FFFF)
  22. /* Time out for SLAK bit */
  23. #define SLAK_TIMEOUT ((uint32_t)0x0000FFFF)
  24. /* Flags in TSTATR register */
  25. #define CAN_FLAGS_TSTATR ((uint32_t)0x08000000)
  26. /* Flags in RFIFO1 register */
  27. #define CAN_FLAGS_RFIFO1 ((uint32_t)0x04000000)
  28. /* Flags in RFIFO0 register */
  29. #define CAN_FLAGS_RFIFO0 ((uint32_t)0x02000000)
  30. /* Flags in STATR register */
  31. #define CAN_FLAGS_STATR ((uint32_t)0x01000000)
  32. /* Flags in ERRSR register */
  33. #define CAN_FLAGS_ERRSR ((uint32_t)0x00F00000)
  34. /* Mailboxes definition */
  35. #define CAN_TXMAILBOX_0 ((uint8_t)0x00)
  36. #define CAN_TXMAILBOX_1 ((uint8_t)0x01)
  37. #define CAN_TXMAILBOX_2 ((uint8_t)0x02)
  38. #define CAN_MODE_MASK ((uint32_t)0x00000003)
  39. static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit);
  40. /*********************************************************************
  41. * @fn CAN_DeInit
  42. *
  43. * @brief Deinitializes the CAN peripheral registers to their default reset
  44. * values.
  45. *
  46. * @param CANx - where x can be 1 or 2 to select the CAN peripheral.
  47. *
  48. * @return none
  49. */
  50. void CAN_DeInit(CAN_TypeDef *CANx)
  51. {
  52. if(CANx == CAN1)
  53. {
  54. RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
  55. RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
  56. }
  57. else
  58. {
  59. RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE);
  60. RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE);
  61. }
  62. }
  63. /*********************************************************************
  64. * @fn CAN_Init
  65. *
  66. * @brief Initializes the CAN peripheral according to the specified
  67. * parameters in the CAN_InitStruct.
  68. *
  69. * @param CANx - where x can be 1 to select the CAN peripheral.
  70. * CAN_InitStruct - pointer to a CAN_InitTypeDef structure that
  71. * contains the configuration information for the CAN peripheral.
  72. *
  73. * @return InitStatus - CAN InitStatus state.
  74. * CAN_InitStatus_Failed.
  75. * CAN_InitStatus_Success.
  76. */
  77. uint8_t CAN_Init(CAN_TypeDef *CANx, CAN_InitTypeDef *CAN_InitStruct)
  78. {
  79. uint8_t InitStatus = CAN_InitStatus_Failed;
  80. uint32_t wait_ack = 0x00000000;
  81. uint32_t chipid = DBGMCU_GetCHIPID();
  82. uint32_t chippackid = (chipid >> 4) & 0xf;
  83. if(chippackid >= 4 && chippackid <= 7)
  84. {
  85. if(CAN1 == CANx)
  86. {
  87. (*(__IO uint32_t *)(0x40021010)) |= 0x2000000;
  88. (*(__IO uint32_t *)(0x40021010)) &= ~(0x2000000);
  89. }else if(CAN2 == CANx)
  90. {
  91. (*(__IO uint32_t *)(0x40021010)) |= 0x4000000;
  92. (*(__IO uint32_t *)(0x40021010)) &= ~(0x4000000);
  93. }
  94. CANx->CTLR &= ~0x2;
  95. CANx->CTLR |= 0x1;
  96. while(!(CANx->STATR & 0x1) && (wait_ack != 0x0000FFFF))
  97. {
  98. wait_ack++;
  99. }
  100. if((CANx->STATR & 0x1))
  101. {
  102. CANx->BTIMR = ( uint32_t)0xC1100000| \
  103. ((uint32_t)SystemCoreClock/(((((*(__IO uint32_t *)(0x40021004)) >> 8) & 0x7) < 0x4) ? 1 : (uint32_t)0x2<<(((*(__IO uint32_t *)(0x40021004)) >> 8) & 0x3))/4000000 - 1);
  104. }
  105. else
  106. {
  107. return CAN_InitStatus_Failed;
  108. }
  109. CANx->CTLR &= ~0x1;
  110. wait_ack = 0;
  111. while((CANx->STATR & 0x1) && (wait_ack != 0x0000FFFF))
  112. {
  113. wait_ack++;
  114. }
  115. if((CANx->STATR & 0x1)){
  116. return CAN_InitStatus_Failed;
  117. }
  118. (*(__IO uint32_t *)(0x4000660C)) |= 0x3;
  119. (*(__IO uint32_t *)(0x40006640)) = 0x0;
  120. (*(__IO uint32_t *)(0x40006644)) = 0x0;
  121. (*(__IO uint32_t *)(0x40006648)) = 0x0;
  122. (*(__IO uint32_t *)(0x4000664C)) = 0x0;
  123. (*(__IO uint32_t *)(0x4000661C)) |= 0x3;
  124. (*(__IO uint32_t *)(0x40006600)) &= ~0x1;
  125. CAN_SlaveStartBank(1);
  126. if(CAN1 == CANx)
  127. {
  128. (*(__IO uint32_t *)(0x40006580)) |= 0x3;
  129. while(!((*(__IO uint32_t *)(0x4000640C)) & 0x3));
  130. (*(__IO uint32_t *)(0x4000640C)) = 0x38;
  131. }else if (CAN2 == CANx)
  132. {
  133. (*(__IO uint32_t *)(0x40006980)) |= 0x3;
  134. while(!((*(__IO uint32_t *)(0x4000680C)) & 0x3));
  135. (*(__IO uint32_t *)(0x4000680C)) = 0x38;
  136. }
  137. if(CAN1 == CANx)
  138. {
  139. (*(__IO uint32_t *)(0x40021010)) |= 0x2000000;
  140. (*(__IO uint32_t *)(0x40021010)) &= ~(0x2000000);
  141. }else if(CAN2 == CANx)
  142. {
  143. (*(__IO uint32_t *)(0x40021010)) |= 0x4000000;
  144. (*(__IO uint32_t *)(0x40021010)) &= ~(0x4000000);
  145. }
  146. (*(__IO uint32_t *)(0x40006600)) |= 0x1;
  147. (*(__IO uint32_t *)(0x4000660C)) |= 0x3;
  148. (*(__IO uint32_t *)(0x4000661C)) |= 0x3;
  149. (*(__IO uint32_t *)(0x40006600)) &= ~0x1;
  150. CAN_SlaveStartBank(1);
  151. wait_ack = 0;
  152. }
  153. CANx->CTLR &= (~(uint32_t)CAN_CTLR_SLEEP);
  154. CANx->CTLR |= CAN_CTLR_INRQ;
  155. while(((CANx->STATR & CAN_STATR_INAK) != CAN_STATR_INAK) && (wait_ack != INAK_TIMEOUT))
  156. {
  157. wait_ack++;
  158. }
  159. if((CANx->STATR & CAN_STATR_INAK) != CAN_STATR_INAK)
  160. {
  161. InitStatus = CAN_InitStatus_Failed;
  162. }
  163. else
  164. {
  165. if(CAN_InitStruct->CAN_TTCM == ENABLE)
  166. {
  167. CANx->CTLR |= CAN_CTLR_TTCM;
  168. }
  169. else
  170. {
  171. CANx->CTLR &= ~(uint32_t)CAN_CTLR_TTCM;
  172. }
  173. if(CAN_InitStruct->CAN_ABOM == ENABLE)
  174. {
  175. CANx->CTLR |= CAN_CTLR_ABOM;
  176. }
  177. else
  178. {
  179. CANx->CTLR &= ~(uint32_t)CAN_CTLR_ABOM;
  180. }
  181. if(CAN_InitStruct->CAN_AWUM == ENABLE)
  182. {
  183. CANx->CTLR |= CAN_CTLR_AWUM;
  184. }
  185. else
  186. {
  187. CANx->CTLR &= ~(uint32_t)CAN_CTLR_AWUM;
  188. }
  189. if(CAN_InitStruct->CAN_NART == ENABLE)
  190. {
  191. CANx->CTLR |= CAN_CTLR_NART;
  192. }
  193. else
  194. {
  195. CANx->CTLR &= ~(uint32_t)CAN_CTLR_NART;
  196. }
  197. if(CAN_InitStruct->CAN_RFLM == ENABLE)
  198. {
  199. CANx->CTLR |= CAN_CTLR_RFLM;
  200. }
  201. else
  202. {
  203. CANx->CTLR &= ~(uint32_t)CAN_CTLR_RFLM;
  204. }
  205. if(CAN_InitStruct->CAN_TXFP == ENABLE)
  206. {
  207. CANx->CTLR |= CAN_CTLR_TXFP;
  208. }
  209. else
  210. {
  211. CANx->CTLR &= ~(uint32_t)CAN_CTLR_TXFP;
  212. }
  213. CANx->BTIMR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) |
  214. ((uint32_t)CAN_InitStruct->CAN_SJW << 24) |
  215. ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) |
  216. ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) |
  217. ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1);
  218. CANx->CTLR &= ~(uint32_t)CAN_CTLR_INRQ;
  219. wait_ack = 0;
  220. while(((CANx->STATR & CAN_STATR_INAK) == CAN_STATR_INAK) && (wait_ack != INAK_TIMEOUT))
  221. {
  222. wait_ack++;
  223. }
  224. if((CANx->STATR & CAN_STATR_INAK) == CAN_STATR_INAK)
  225. {
  226. InitStatus = CAN_InitStatus_Failed;
  227. }
  228. else
  229. {
  230. InitStatus = CAN_InitStatus_Success;
  231. }
  232. }
  233. return InitStatus;
  234. }
  235. /*********************************************************************
  236. * @fn CAN_FilterInit
  237. *
  238. * @brief Initializes the CAN peripheral according to the specified
  239. * parameters in the CAN_FilterInitStruct.
  240. *
  241. * @param CAN_FilterInitStruct - pointer to a CAN_FilterInitTypeDef
  242. * structure that contains the configuration information.
  243. *
  244. * @return none
  245. */
  246. void CAN_FilterInit(CAN_FilterInitTypeDef *CAN_FilterInitStruct)
  247. {
  248. uint32_t filter_number_bit_pos = 0;
  249. filter_number_bit_pos = ((uint32_t)1) << CAN_FilterInitStruct->CAN_FilterNumber;
  250. CAN1->FCTLR |= FCTLR_FINIT;
  251. CAN1->FWR &= ~(uint32_t)filter_number_bit_pos;
  252. if(CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)
  253. {
  254. CAN1->FSCFGR &= ~(uint32_t)filter_number_bit_pos;
  255. CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
  256. ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
  257. (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
  258. CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
  259. ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
  260. (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh);
  261. }
  262. if(CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)
  263. {
  264. CAN1->FSCFGR |= filter_number_bit_pos;
  265. CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
  266. ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |
  267. (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
  268. CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
  269. ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
  270. (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow);
  271. }
  272. if(CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)
  273. {
  274. CAN1->FMCFGR &= ~(uint32_t)filter_number_bit_pos;
  275. }
  276. else
  277. {
  278. CAN1->FMCFGR |= (uint32_t)filter_number_bit_pos;
  279. }
  280. if(CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO0)
  281. {
  282. CAN1->FAFIFOR &= ~(uint32_t)filter_number_bit_pos;
  283. }
  284. if(CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO1)
  285. {
  286. CAN1->FAFIFOR |= (uint32_t)filter_number_bit_pos;
  287. }
  288. if(CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)
  289. {
  290. CAN1->FWR |= filter_number_bit_pos;
  291. }
  292. CAN1->FCTLR &= ~FCTLR_FINIT;
  293. }
  294. /*********************************************************************
  295. * @fn CAN_StructInit
  296. *
  297. * @brief Fills each CAN_InitStruct member with its default value.
  298. *
  299. * @param CAN_InitStruct - pointer to a CAN_InitTypeDef structure which
  300. * will be initialized.
  301. *
  302. * @return none
  303. */
  304. void CAN_StructInit(CAN_InitTypeDef *CAN_InitStruct)
  305. {
  306. CAN_InitStruct->CAN_TTCM = DISABLE;
  307. CAN_InitStruct->CAN_ABOM = DISABLE;
  308. CAN_InitStruct->CAN_AWUM = DISABLE;
  309. CAN_InitStruct->CAN_NART = DISABLE;
  310. CAN_InitStruct->CAN_RFLM = DISABLE;
  311. CAN_InitStruct->CAN_TXFP = DISABLE;
  312. CAN_InitStruct->CAN_Mode = CAN_Mode_Normal;
  313. CAN_InitStruct->CAN_SJW = CAN_SJW_1tq;
  314. CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq;
  315. CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq;
  316. CAN_InitStruct->CAN_Prescaler = 1;
  317. }
  318. /*********************************************************************
  319. * @fn CAN_SlaveStartBank
  320. *
  321. * @brief This function applies only to CH32 Connectivity line devices.
  322. *
  323. * @param CAN_BankNumber - Select the start slave bank filter from 1..27.
  324. *
  325. * @return none
  326. */
  327. void CAN_SlaveStartBank(uint8_t CAN_BankNumber)
  328. {
  329. CAN1->FCTLR |= FCTLR_FINIT;
  330. CAN1->FCTLR &= (uint32_t)0xFFFFC0F1;
  331. CAN1->FCTLR |= (uint32_t)(CAN_BankNumber) << 8;
  332. CAN1->FCTLR &= ~FCTLR_FINIT;
  333. }
  334. /*********************************************************************
  335. * @fn CAN_DBGFreeze
  336. *
  337. * @brief Enables or disables the DBG Freeze for CAN.
  338. *
  339. * @param CANx - where x can be 1 to select the CAN peripheral.
  340. * NewState - ENABLE or DISABLE.
  341. *
  342. * @return none
  343. */
  344. void CAN_DBGFreeze(CAN_TypeDef *CANx, FunctionalState NewState)
  345. {
  346. if(NewState != DISABLE)
  347. {
  348. CANx->CTLR |= CTLR_DBF;
  349. }
  350. else
  351. {
  352. CANx->CTLR &= ~CTLR_DBF;
  353. }
  354. }
  355. /*********************************************************************
  356. * @fn CAN_TTComModeCmd
  357. *
  358. * @brief Enables or disabes the CAN Time TriggerOperation communication mode.
  359. *
  360. * @param CANx - where x can be 1 to select the CAN peripheral.
  361. * NewState - ENABLE or DISABLE.
  362. * Note-
  363. * DLC must be programmed as 8 in order Time Stamp (2 bytes) to be
  364. * sent over the CAN bus.
  365. *
  366. * @return none
  367. */
  368. void CAN_TTComModeCmd(CAN_TypeDef *CANx, FunctionalState NewState)
  369. {
  370. if(NewState != DISABLE)
  371. {
  372. CANx->CTLR |= CAN_CTLR_TTCM;
  373. CANx->sTxMailBox[0].TXMDTR |= ((uint32_t)CAN_TXMDT0R_TGT);
  374. CANx->sTxMailBox[1].TXMDTR |= ((uint32_t)CAN_TXMDT1R_TGT);
  375. CANx->sTxMailBox[2].TXMDTR |= ((uint32_t)CAN_TXMDT2R_TGT);
  376. }
  377. else
  378. {
  379. CANx->CTLR &= (uint32_t)(~(uint32_t)CAN_CTLR_TTCM);
  380. CANx->sTxMailBox[0].TXMDTR &= ((uint32_t)~CAN_TXMDT0R_TGT);
  381. CANx->sTxMailBox[1].TXMDTR &= ((uint32_t)~CAN_TXMDT1R_TGT);
  382. CANx->sTxMailBox[2].TXMDTR &= ((uint32_t)~CAN_TXMDT2R_TGT);
  383. }
  384. }
  385. /*********************************************************************
  386. * @fn CAN_Transmit
  387. *
  388. * @brief Initiates the transmission of a message.
  389. *
  390. * @param CANx - where x can be 1 to select the CAN peripheral.
  391. * TxMessage - pointer to a structure which contains CAN Id, CAN
  392. * DLC and CAN data.
  393. *
  394. * @return transmit_mailbox - The number of the mailbox that is used for
  395. * transmission or CAN_TxStatus_NoMailBox if there is no empty mailbox.
  396. */
  397. uint8_t CAN_Transmit(CAN_TypeDef *CANx, CanTxMsg *TxMessage)
  398. {
  399. uint8_t transmit_mailbox = 0;
  400. if((CANx->TSTATR & CAN_TSTATR_TME0) == CAN_TSTATR_TME0)
  401. {
  402. transmit_mailbox = 0;
  403. }
  404. else if((CANx->TSTATR & CAN_TSTATR_TME1) == CAN_TSTATR_TME1)
  405. {
  406. transmit_mailbox = 1;
  407. }
  408. else if((CANx->TSTATR & CAN_TSTATR_TME2) == CAN_TSTATR_TME2)
  409. {
  410. transmit_mailbox = 2;
  411. }
  412. else
  413. {
  414. transmit_mailbox = CAN_TxStatus_NoMailBox;
  415. }
  416. if(transmit_mailbox != CAN_TxStatus_NoMailBox)
  417. {
  418. CANx->sTxMailBox[transmit_mailbox].TXMIR &= TMIDxR_TXRQ;
  419. if(TxMessage->IDE == CAN_Id_Standard)
  420. {
  421. CANx->sTxMailBox[transmit_mailbox].TXMIR |= ((TxMessage->StdId << 21) |
  422. TxMessage->RTR);
  423. }
  424. else
  425. {
  426. CANx->sTxMailBox[transmit_mailbox].TXMIR |= ((TxMessage->ExtId << 3) |
  427. TxMessage->IDE |
  428. TxMessage->RTR);
  429. }
  430. TxMessage->DLC &= (uint8_t)0x0000000F;
  431. CANx->sTxMailBox[transmit_mailbox].TXMDTR &= (uint32_t)0xFFFFFFF0;
  432. CANx->sTxMailBox[transmit_mailbox].TXMDTR |= TxMessage->DLC;
  433. CANx->sTxMailBox[transmit_mailbox].TXMDLR = (((uint32_t)TxMessage->Data[3] << 24) |
  434. ((uint32_t)TxMessage->Data[2] << 16) |
  435. ((uint32_t)TxMessage->Data[1] << 8) |
  436. ((uint32_t)TxMessage->Data[0]));
  437. CANx->sTxMailBox[transmit_mailbox].TXMDHR = (((uint32_t)TxMessage->Data[7] << 24) |
  438. ((uint32_t)TxMessage->Data[6] << 16) |
  439. ((uint32_t)TxMessage->Data[5] << 8) |
  440. ((uint32_t)TxMessage->Data[4]));
  441. CANx->sTxMailBox[transmit_mailbox].TXMIR |= TMIDxR_TXRQ;
  442. }
  443. return transmit_mailbox;
  444. }
  445. /*********************************************************************
  446. * @fn CAN_TransmitStatus
  447. *
  448. * @brief Checks the transmission of a message.
  449. *
  450. * @param CANx - where x can be 1 to select the CAN peripheral.
  451. * TransmitMailbox - the number of the mailbox that is used for
  452. * transmission.
  453. *
  454. * @return state -
  455. * CAN_TxStatus_Ok.
  456. * CAN_TxStatus_Failed.
  457. */
  458. uint8_t CAN_TransmitStatus(CAN_TypeDef *CANx, uint8_t TransmitMailbox)
  459. {
  460. uint32_t state = 0;
  461. switch(TransmitMailbox)
  462. {
  463. case(CAN_TXMAILBOX_0):
  464. state = CANx->TSTATR & (CAN_TSTATR_RQCP0 | CAN_TSTATR_TXOK0 | CAN_TSTATR_TME0);
  465. break;
  466. case(CAN_TXMAILBOX_1):
  467. state = CANx->TSTATR & (CAN_TSTATR_RQCP1 | CAN_TSTATR_TXOK1 | CAN_TSTATR_TME1);
  468. break;
  469. case(CAN_TXMAILBOX_2):
  470. state = CANx->TSTATR & (CAN_TSTATR_RQCP2 | CAN_TSTATR_TXOK2 | CAN_TSTATR_TME2);
  471. break;
  472. default:
  473. state = CAN_TxStatus_Failed;
  474. break;
  475. }
  476. switch(state)
  477. {
  478. case(0x0):
  479. state = CAN_TxStatus_Pending;
  480. break;
  481. case(CAN_TSTATR_RQCP0 | CAN_TSTATR_TME0):
  482. state = CAN_TxStatus_Failed;
  483. break;
  484. case(CAN_TSTATR_RQCP1 | CAN_TSTATR_TME1):
  485. state = CAN_TxStatus_Failed;
  486. break;
  487. case(CAN_TSTATR_RQCP2 | CAN_TSTATR_TME2):
  488. state = CAN_TxStatus_Failed;
  489. break;
  490. case(CAN_TSTATR_RQCP0 | CAN_TSTATR_TXOK0 | CAN_TSTATR_TME0):
  491. state = CAN_TxStatus_Ok;
  492. break;
  493. case(CAN_TSTATR_RQCP1 | CAN_TSTATR_TXOK1 | CAN_TSTATR_TME1):
  494. state = CAN_TxStatus_Ok;
  495. break;
  496. case(CAN_TSTATR_RQCP2 | CAN_TSTATR_TXOK2 | CAN_TSTATR_TME2):
  497. state = CAN_TxStatus_Ok;
  498. break;
  499. default:
  500. state = CAN_TxStatus_Failed;
  501. break;
  502. }
  503. return (uint8_t)state;
  504. }
  505. /*********************************************************************
  506. * @fn CAN_CancelTransmit
  507. *
  508. * @brief Cancels a transmit request.
  509. *
  510. * @param CANx - where x can be 1 to select the CAN peripheral.
  511. * Mailbox - Mailbox number.
  512. * CAN_TXMAILBOX_0.
  513. * CAN_TXMAILBOX_1.
  514. * CAN_TXMAILBOX_2.
  515. *
  516. * @return none
  517. */
  518. void CAN_CancelTransmit(CAN_TypeDef *CANx, uint8_t Mailbox)
  519. {
  520. switch(Mailbox)
  521. {
  522. case(CAN_TXMAILBOX_0):
  523. CANx->TSTATR |= CAN_TSTATR_ABRQ0;
  524. break;
  525. case(CAN_TXMAILBOX_1):
  526. CANx->TSTATR |= CAN_TSTATR_ABRQ1;
  527. break;
  528. case(CAN_TXMAILBOX_2):
  529. CANx->TSTATR |= CAN_TSTATR_ABRQ2;
  530. break;
  531. default:
  532. break;
  533. }
  534. }
  535. /*********************************************************************
  536. * @fn CAN_Receive
  537. *
  538. * @brief Receives a message.
  539. *
  540. * @param CANx - where x can be 1 to select the CAN peripheral.
  541. * FIFONumber - Receive FIFO number.
  542. * CAN_FIFO0.
  543. * CAN_FIFO1.
  544. * RxMessage - pointer to a structure receive message which contains
  545. * CAN Id, CAN DLC, CAN datas and FMI number.
  546. *
  547. * @return none
  548. */
  549. void CAN_Receive(CAN_TypeDef *CANx, uint8_t FIFONumber, CanRxMsg *RxMessage)
  550. {
  551. RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RXMIR;
  552. if(RxMessage->IDE == CAN_Id_Standard)
  553. {
  554. RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RXMIR >> 21);
  555. }
  556. else
  557. {
  558. RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RXMIR >> 3);
  559. }
  560. RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RXMIR;
  561. RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RXMDTR;
  562. RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDTR >> 8);
  563. RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RXMDLR;
  564. RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDLR >> 8);
  565. RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDLR >> 16);
  566. RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDLR >> 24);
  567. RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RXMDHR;
  568. RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDHR >> 8);
  569. RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDHR >> 16);
  570. RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RXMDHR >> 24);
  571. if(FIFONumber == CAN_FIFO0)
  572. {
  573. CANx->RFIFO0 |= CAN_RFIFO0_RFOM0;
  574. }
  575. else
  576. {
  577. CANx->RFIFO1 |= CAN_RFIFO1_RFOM1;
  578. }
  579. }
  580. /*********************************************************************
  581. * @fn CAN_FIFORelease
  582. *
  583. * @brief Releases the specified FIFO.
  584. *
  585. * @param CANx - where x can be 1 to select the CAN peripheral.
  586. * FIFONumber - Receive FIFO number.
  587. * CAN_FIFO0.
  588. * CAN_FIFO1.
  589. *
  590. * @return none
  591. */
  592. void CAN_FIFORelease(CAN_TypeDef *CANx, uint8_t FIFONumber)
  593. {
  594. if(FIFONumber == CAN_FIFO0)
  595. {
  596. CANx->RFIFO0 |= CAN_RFIFO0_RFOM0;
  597. }
  598. else
  599. {
  600. CANx->RFIFO1 |= CAN_RFIFO1_RFOM1;
  601. }
  602. }
  603. /*********************************************************************
  604. * @fn CAN_MessagePending
  605. *
  606. * @brief Returns the number of pending messages.
  607. *
  608. * @param CANx - where x can be 1 to select the CAN peripheral.
  609. * FIFONumber - Receive FIFO number.
  610. * CAN_FIFO0.
  611. * CAN_FIFO1.
  612. *
  613. * @return message_pending: which is the number of pending message.
  614. */
  615. uint8_t CAN_MessagePending(CAN_TypeDef *CANx, uint8_t FIFONumber)
  616. {
  617. uint8_t message_pending = 0;
  618. if(FIFONumber == CAN_FIFO0)
  619. {
  620. message_pending = (uint8_t)(CANx->RFIFO0 & (uint32_t)0x03);
  621. }
  622. else if(FIFONumber == CAN_FIFO1)
  623. {
  624. message_pending = (uint8_t)(CANx->RFIFO1 & (uint32_t)0x03);
  625. }
  626. else
  627. {
  628. message_pending = 0;
  629. }
  630. return message_pending;
  631. }
  632. /*********************************************************************
  633. * @fn CAN_OperatingModeRequest
  634. *
  635. * @brief Select the CAN Operation mode.
  636. *
  637. * @param CANx - where x can be 1 to select the CAN peripheral.
  638. * CAN_OperatingMode - CAN Operating Mode.
  639. * CAN_OperatingMode_Initialization.
  640. * CAN_OperatingMode_Normal.
  641. * CAN_OperatingMode_Sleep.
  642. *
  643. * @return status -
  644. * CAN_ModeStatus_Failed - CAN failed entering the specific mode.
  645. * CAN_ModeStatus_Success - CAN Succeed entering the specific mode.
  646. */
  647. uint8_t CAN_OperatingModeRequest(CAN_TypeDef *CANx, uint8_t CAN_OperatingMode)
  648. {
  649. uint8_t status = CAN_ModeStatus_Failed;
  650. uint32_t timeout = INAK_TIMEOUT;
  651. if(CAN_OperatingMode == CAN_OperatingMode_Initialization)
  652. {
  653. CANx->CTLR = (uint32_t)((CANx->CTLR & (uint32_t)(~(uint32_t)CAN_CTLR_SLEEP)) | CAN_CTLR_INRQ);
  654. while(((CANx->STATR & CAN_MODE_MASK) != CAN_STATR_INAK) && (timeout != 0))
  655. {
  656. timeout--;
  657. }
  658. if((CANx->STATR & CAN_MODE_MASK) != CAN_STATR_INAK)
  659. {
  660. status = CAN_ModeStatus_Failed;
  661. }
  662. else
  663. {
  664. status = CAN_ModeStatus_Success;
  665. }
  666. }
  667. else if(CAN_OperatingMode == CAN_OperatingMode_Normal)
  668. {
  669. CANx->CTLR &= (uint32_t)(~(CAN_CTLR_SLEEP | CAN_CTLR_INRQ));
  670. while(((CANx->STATR & CAN_MODE_MASK) != 0) && (timeout != 0))
  671. {
  672. timeout--;
  673. }
  674. if((CANx->STATR & CAN_MODE_MASK) != 0)
  675. {
  676. status = CAN_ModeStatus_Failed;
  677. }
  678. else
  679. {
  680. status = CAN_ModeStatus_Success;
  681. }
  682. }
  683. else if(CAN_OperatingMode == CAN_OperatingMode_Sleep)
  684. {
  685. CANx->CTLR = (uint32_t)((CANx->CTLR & (uint32_t)(~(uint32_t)CAN_CTLR_INRQ)) | CAN_CTLR_SLEEP);
  686. while(((CANx->STATR & CAN_MODE_MASK) != CAN_STATR_SLAK) && (timeout != 0))
  687. {
  688. timeout--;
  689. }
  690. if((CANx->STATR & CAN_MODE_MASK) != CAN_STATR_SLAK)
  691. {
  692. status = CAN_ModeStatus_Failed;
  693. }
  694. else
  695. {
  696. status = CAN_ModeStatus_Success;
  697. }
  698. }
  699. else
  700. {
  701. status = CAN_ModeStatus_Failed;
  702. }
  703. return (uint8_t)status;
  704. }
  705. /*********************************************************************
  706. * @fn CAN_Sleep
  707. *
  708. * @brief Enters the low power mode.
  709. *
  710. * @param CANx - where x can be 1 to select the CAN peripheral.
  711. *
  712. * @return sleepstatus -
  713. * CAN_Sleep_Ok.
  714. * CAN_Sleep_Failed.
  715. */
  716. uint8_t CAN_Sleep(CAN_TypeDef *CANx)
  717. {
  718. uint8_t sleepstatus = CAN_Sleep_Failed;
  719. CANx->CTLR = (((CANx->CTLR) & (uint32_t)(~(uint32_t)CAN_CTLR_INRQ)) | CAN_CTLR_SLEEP);
  720. if((CANx->STATR & (CAN_STATR_SLAK | CAN_STATR_INAK)) == CAN_STATR_SLAK)
  721. {
  722. sleepstatus = CAN_Sleep_Ok;
  723. }
  724. return (uint8_t)sleepstatus;
  725. }
  726. /*********************************************************************
  727. * @fn CAN_WakeUp
  728. *
  729. * @brief Wakes the CAN up.
  730. *
  731. * @param CANx - where x can be 1 to select the CAN peripheral.
  732. *
  733. * @return wakeupstatus -
  734. * CAN_WakeUp_Ok.
  735. * CAN_WakeUp_Failed.
  736. */
  737. uint8_t CAN_WakeUp(CAN_TypeDef *CANx)
  738. {
  739. uint32_t wait_slak = SLAK_TIMEOUT;
  740. uint8_t wakeupstatus = CAN_WakeUp_Failed;
  741. CANx->CTLR &= ~(uint32_t)CAN_CTLR_SLEEP;
  742. while(((CANx->STATR & CAN_STATR_SLAK) == CAN_STATR_SLAK) && (wait_slak != 0x00))
  743. {
  744. wait_slak--;
  745. }
  746. if((CANx->STATR & CAN_STATR_SLAK) != CAN_STATR_SLAK)
  747. {
  748. wakeupstatus = CAN_WakeUp_Ok;
  749. }
  750. return (uint8_t)wakeupstatus;
  751. }
  752. /*********************************************************************
  753. * @fn CAN_GetLastErrorCode
  754. *
  755. * @brief Returns the CANx's last error code (LEC).
  756. *
  757. * @param CANx - where x can be 1 to select the CAN peripheral.
  758. *
  759. * @return errorcode - specifies the Error code.
  760. * CAN_ErrorCode_NoErr - No Error.
  761. * CAN_ErrorCode_StuffErr - Stuff Error.
  762. * CAN_ErrorCode_FormErr - Form Error.
  763. * CAN_ErrorCode_ACKErr - Acknowledgment Error.
  764. * CAN_ErrorCode_BitRecessiveErr - Bit Recessive Error.
  765. * CAN_ErrorCode_BitDominantErr - Bit Dominant Error.
  766. * CAN_ErrorCode_CRCErr - CRC Error.
  767. * CAN_ErrorCode_SoftwareSetErr - Software Set Error.
  768. */
  769. uint8_t CAN_GetLastErrorCode(CAN_TypeDef *CANx)
  770. {
  771. uint8_t errorcode = 0;
  772. errorcode = (((uint8_t)CANx->ERRSR) & (uint8_t)CAN_ERRSR_LEC);
  773. return errorcode;
  774. }
  775. /*********************************************************************
  776. * @fn CAN_GetReceiveErrorCounter
  777. *
  778. * @brief Returns the CANx Receive Error Counter (REC).
  779. *
  780. * @param CANx - where x can be 1 to select the CAN peripheral.
  781. * Note-
  782. * In case of an error during reception, this counter is incremented
  783. * by 1 or by 8 depending on the error condition as defined by the CAN
  784. * standard. After every successful reception, the counter is
  785. * decremented by 1 or reset to 120 if its value was higher than 128.
  786. * When the counter value exceeds 127, the CAN controller enters the
  787. * error passive state.
  788. * @return counter - CAN Receive Error Counter.
  789. */
  790. uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef *CANx)
  791. {
  792. uint8_t counter = 0;
  793. counter = (uint8_t)((CANx->ERRSR & CAN_ERRSR_REC) >> 24);
  794. return counter;
  795. }
  796. /*********************************************************************
  797. * @fn CAN_GetLSBTransmitErrorCounter
  798. *
  799. * @brief Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
  800. *
  801. * @param CANx - where x can be 1 to select the CAN peripheral.
  802. *
  803. * @return counter - LSB of the 9-bit CAN Transmit Error Counter.
  804. */
  805. uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef *CANx)
  806. {
  807. uint8_t counter = 0;
  808. counter = (uint8_t)((CANx->ERRSR & CAN_ERRSR_TEC) >> 16);
  809. return counter;
  810. }
  811. /*********************************************************************
  812. * @fn CAN_ITConfig
  813. *
  814. * @brief Enables or disables the specified CANx interrupts.
  815. *
  816. * @param CANx - where x can be 1 to select the CAN peripheral.
  817. * CAN_IT - specifies the CAN interrupt sources to be enabled or disabled.
  818. * CAN_IT_TME.
  819. * CAN_IT_FMP0.
  820. * CAN_IT_FF0.
  821. * CAN_IT_FOV0.
  822. * CAN_IT_FMP1.
  823. * CAN_IT_FF1.
  824. * CAN_IT_FOV1.
  825. * CAN_IT_EWG.
  826. * CAN_IT_EPV.
  827. * CAN_IT_LEC.
  828. * CAN_IT_ERR.
  829. * CAN_IT_WKU.
  830. * CAN_IT_SLK.
  831. * NewState - ENABLE or DISABLE.
  832. *
  833. * @return counter - LSB of the 9-bit CAN Transmit Error Counter.
  834. */
  835. void CAN_ITConfig(CAN_TypeDef *CANx, uint32_t CAN_IT, FunctionalState NewState)
  836. {
  837. if(NewState != DISABLE)
  838. {
  839. CANx->INTENR |= CAN_IT;
  840. }
  841. else
  842. {
  843. CANx->INTENR &= ~CAN_IT;
  844. }
  845. }
  846. /*********************************************************************
  847. * @fn CAN_GetFlagStatus
  848. *
  849. * @brief Checks whether the specified CAN flag is set or not.
  850. *
  851. * @param CANx - where x can be 1 to select the CAN peripheral.
  852. * CAN_FLAG - specifies the flag to check.
  853. * CAN_FLAG_EWG.
  854. * CAN_FLAG_EPV.
  855. * CAN_FLAG_BOF.
  856. * CAN_FLAG_RQCP0.
  857. * CAN_FLAG_RQCP1.
  858. * CAN_FLAG_RQCP2.
  859. * CAN_FLAG_FMP1.
  860. * CAN_FLAG_FF1.
  861. * CAN_FLAG_FOV1.
  862. * CAN_FLAG_FMP0.
  863. * CAN_FLAG_FF0.
  864. * CAN_FLAG_FOV0.
  865. * CAN_FLAG_WKU.
  866. * CAN_FLAG_SLAK.
  867. * CAN_FLAG_LEC.
  868. * NewState - ENABLE or DISABLE.
  869. *
  870. * @return FlagStatus - SET or RESET.
  871. */
  872. FlagStatus CAN_GetFlagStatus(CAN_TypeDef *CANx, uint32_t CAN_FLAG)
  873. {
  874. FlagStatus bitstatus = RESET;
  875. if((CAN_FLAG & CAN_FLAGS_ERRSR) != (uint32_t)RESET)
  876. {
  877. if((CANx->ERRSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
  878. {
  879. bitstatus = SET;
  880. }
  881. else
  882. {
  883. bitstatus = RESET;
  884. }
  885. }
  886. else if((CAN_FLAG & CAN_FLAGS_STATR) != (uint32_t)RESET)
  887. {
  888. if((CANx->STATR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
  889. {
  890. bitstatus = SET;
  891. }
  892. else
  893. {
  894. bitstatus = RESET;
  895. }
  896. }
  897. else if((CAN_FLAG & CAN_FLAGS_TSTATR) != (uint32_t)RESET)
  898. {
  899. if((CANx->TSTATR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
  900. {
  901. bitstatus = SET;
  902. }
  903. else
  904. {
  905. bitstatus = RESET;
  906. }
  907. }
  908. else if((CAN_FLAG & CAN_FLAGS_RFIFO0) != (uint32_t)RESET)
  909. {
  910. if((CANx->RFIFO0 & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
  911. {
  912. bitstatus = SET;
  913. }
  914. else
  915. {
  916. bitstatus = RESET;
  917. }
  918. }
  919. else
  920. {
  921. if((uint32_t)(CANx->RFIFO1 & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
  922. {
  923. bitstatus = SET;
  924. }
  925. else
  926. {
  927. bitstatus = RESET;
  928. }
  929. }
  930. return bitstatus;
  931. }
  932. /*********************************************************************
  933. * @fn CAN_ClearFlag
  934. *
  935. * @brief Clears the CAN's pending flags.
  936. *
  937. * @param CANx - where x can be 1 to select the CAN peripheral.
  938. * CAN_FLAG - specifies the flag to clear.
  939. * CAN_FLAG_RQCP0.
  940. * CAN_FLAG_RQCP1.
  941. * CAN_FLAG_RQCP2.
  942. * CAN_FLAG_FF1.
  943. * CAN_FLAG_FOV1.
  944. * CAN_FLAG_FF0.
  945. * CAN_FLAG_FOV0.
  946. * CAN_FLAG_WKU.
  947. * CAN_FLAG_SLAK.
  948. * CAN_FLAG_LEC.
  949. *
  950. * @return none
  951. */
  952. void CAN_ClearFlag(CAN_TypeDef *CANx, uint32_t CAN_FLAG)
  953. {
  954. uint32_t flagtmp = 0;
  955. if(CAN_FLAG == CAN_FLAG_LEC)
  956. {
  957. CANx->ERRSR = (uint32_t)RESET;
  958. }
  959. else
  960. {
  961. flagtmp = CAN_FLAG & 0x000FFFFF;
  962. if((CAN_FLAG & CAN_FLAGS_RFIFO0) != (uint32_t)RESET)
  963. {
  964. CANx->RFIFO0 = (uint32_t)(flagtmp);
  965. }
  966. else if((CAN_FLAG & CAN_FLAGS_RFIFO1) != (uint32_t)RESET)
  967. {
  968. CANx->RFIFO1 = (uint32_t)(flagtmp);
  969. }
  970. else if((CAN_FLAG & CAN_FLAGS_TSTATR) != (uint32_t)RESET)
  971. {
  972. CANx->TSTATR = (uint32_t)(flagtmp);
  973. }
  974. else
  975. {
  976. CANx->STATR = (uint32_t)(flagtmp);
  977. }
  978. }
  979. }
  980. /*********************************************************************
  981. * @fn CAN_GetITStatus
  982. *
  983. * @brief Checks whether the specified CANx interrupt has occurred or not.
  984. *
  985. * @param CANx - where x can be 1 to select the CAN peripheral.
  986. * CAN_IT - specifies the CAN interrupt source to check.
  987. * CAN_IT_TME.
  988. * CAN_IT_FMP0.
  989. * CAN_IT_FF0.
  990. * CAN_IT_FOV0.
  991. * CAN_IT_FMP1.
  992. * CAN_IT_FF1.
  993. * CAN_IT_FOV1.
  994. * CAN_IT_WKU.
  995. * CAN_IT_SLK.
  996. * CAN_IT_EWG.
  997. * CAN_IT_EPV.
  998. * CAN_IT_BOF.
  999. * CAN_IT_LEC.
  1000. * CAN_IT_ERR.
  1001. *
  1002. * @return ITStatus - SET or RESET.
  1003. */
  1004. ITStatus CAN_GetITStatus(CAN_TypeDef *CANx, uint32_t CAN_IT)
  1005. {
  1006. ITStatus itstatus = RESET;
  1007. if((CANx->INTENR & CAN_IT) != RESET)
  1008. {
  1009. switch(CAN_IT)
  1010. {
  1011. case CAN_IT_TME:
  1012. itstatus = CheckITStatus(CANx->TSTATR, CAN_TSTATR_RQCP0 | CAN_TSTATR_RQCP1 | CAN_TSTATR_RQCP2);
  1013. break;
  1014. case CAN_IT_FMP0:
  1015. itstatus = CheckITStatus(CANx->RFIFO0, CAN_RFIFO0_FMP0);
  1016. break;
  1017. case CAN_IT_FF0:
  1018. itstatus = CheckITStatus(CANx->RFIFO0, CAN_RFIFO0_FULL0);
  1019. break;
  1020. case CAN_IT_FOV0:
  1021. itstatus = CheckITStatus(CANx->RFIFO0, CAN_RFIFO0_FOVR0);
  1022. break;
  1023. case CAN_IT_FMP1:
  1024. itstatus = CheckITStatus(CANx->RFIFO1, CAN_RFIFO1_FMP1);
  1025. break;
  1026. case CAN_IT_FF1:
  1027. itstatus = CheckITStatus(CANx->RFIFO1, CAN_RFIFO1_FULL1);
  1028. break;
  1029. case CAN_IT_FOV1:
  1030. itstatus = CheckITStatus(CANx->RFIFO1, CAN_RFIFO1_FOVR1);
  1031. break;
  1032. case CAN_IT_WKU:
  1033. itstatus = CheckITStatus(CANx->STATR, CAN_STATR_WKUI);
  1034. break;
  1035. case CAN_IT_SLK:
  1036. itstatus = CheckITStatus(CANx->STATR, CAN_STATR_SLAKI);
  1037. break;
  1038. case CAN_IT_EWG:
  1039. itstatus = CheckITStatus(CANx->ERRSR, CAN_ERRSR_EWGF);
  1040. break;
  1041. case CAN_IT_EPV:
  1042. itstatus = CheckITStatus(CANx->ERRSR, CAN_ERRSR_EPVF);
  1043. break;
  1044. case CAN_IT_BOF:
  1045. itstatus = CheckITStatus(CANx->ERRSR, CAN_ERRSR_BOFF);
  1046. break;
  1047. case CAN_IT_LEC:
  1048. itstatus = CheckITStatus(CANx->ERRSR, CAN_ERRSR_LEC);
  1049. break;
  1050. case CAN_IT_ERR:
  1051. itstatus = CheckITStatus(CANx->STATR, CAN_STATR_ERRI);
  1052. break;
  1053. default:
  1054. itstatus = RESET;
  1055. break;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. itstatus = RESET;
  1061. }
  1062. return itstatus;
  1063. }
  1064. /*********************************************************************
  1065. * @fn CAN_ClearITPendingBit
  1066. *
  1067. * @brief Clears the CANx's interrupt pending bits.
  1068. *
  1069. * @param CANx - where x can be 1 to select the CAN peripheral.
  1070. * CAN_IT - specifies the interrupt pending bit to clear.
  1071. * CAN_IT_TME.
  1072. * CAN_IT_FF0.
  1073. * CAN_IT_FOV0.
  1074. * CAN_IT_FF1.
  1075. * CAN_IT_FOV1.
  1076. * CAN_IT_WKU.
  1077. * CAN_IT_SLK.
  1078. * CAN_IT_EWG.
  1079. * CAN_IT_EPV.
  1080. * CAN_IT_BOF.
  1081. * CAN_IT_LEC.
  1082. * CAN_IT_ERR.
  1083. *
  1084. * @return none
  1085. */
  1086. void CAN_ClearITPendingBit(CAN_TypeDef *CANx, uint32_t CAN_IT)
  1087. {
  1088. switch(CAN_IT)
  1089. {
  1090. case CAN_IT_TME:
  1091. CANx->TSTATR = CAN_TSTATR_RQCP0 | CAN_TSTATR_RQCP1 | CAN_TSTATR_RQCP2;
  1092. break;
  1093. case CAN_IT_FF0:
  1094. CANx->RFIFO0 = CAN_RFIFO0_FULL0;
  1095. break;
  1096. case CAN_IT_FOV0:
  1097. CANx->RFIFO0 = CAN_RFIFO0_FOVR0;
  1098. break;
  1099. case CAN_IT_FF1:
  1100. CANx->RFIFO1 = CAN_RFIFO1_FULL1;
  1101. break;
  1102. case CAN_IT_FOV1:
  1103. CANx->RFIFO1 = CAN_RFIFO1_FOVR1;
  1104. break;
  1105. case CAN_IT_WKU:
  1106. CANx->STATR = CAN_STATR_WKUI;
  1107. break;
  1108. case CAN_IT_SLK:
  1109. CANx->STATR = CAN_STATR_SLAKI;
  1110. break;
  1111. case CAN_IT_EWG:
  1112. CANx->STATR = CAN_STATR_ERRI;
  1113. break;
  1114. case CAN_IT_EPV:
  1115. CANx->STATR = CAN_STATR_ERRI;
  1116. break;
  1117. case CAN_IT_BOF:
  1118. CANx->STATR = CAN_STATR_ERRI;
  1119. break;
  1120. case CAN_IT_LEC:
  1121. CANx->ERRSR = RESET;
  1122. CANx->STATR = CAN_STATR_ERRI;
  1123. break;
  1124. case CAN_IT_ERR:
  1125. CANx->ERRSR = RESET;
  1126. CANx->STATR = CAN_STATR_ERRI;
  1127. break;
  1128. default:
  1129. break;
  1130. }
  1131. }
  1132. /*********************************************************************
  1133. * @fn CheckITStatus
  1134. *
  1135. * @brief Checks whether the CAN interrupt has occurred or not.
  1136. *
  1137. * @param CAN_Reg - specifies the CAN interrupt register to check
  1138. * It_Bit - specifies the interrupt source bit to check.
  1139. *
  1140. * @return ITStatus - SET or RESET.
  1141. */
  1142. static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit)
  1143. {
  1144. ITStatus pendingbitstatus = RESET;
  1145. if((CAN_Reg & It_Bit) != (uint32_t)RESET)
  1146. {
  1147. pendingbitstatus = SET;
  1148. }
  1149. else
  1150. {
  1151. pendingbitstatus = RESET;
  1152. }
  1153. return pendingbitstatus;
  1154. }