stm32f4xx_hal_can.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_can.c
  4. * @author MCD Application Team
  5. * @brief This file provides firmware functions to manage the following
  6. * functionalities of the Controller Area Network (CAN) peripheral:
  7. * + Initialization and de-initialization functions
  8. * + IO operation functions
  9. * + Peripheral Control functions
  10. * + Peripheral State and Error functions
  11. *
  12. @verbatim
  13. ==============================================================================
  14. ##### User NOTE #####
  15. ==============================================================================
  16. [..]
  17. (#) This HAL CAN driver is deprecated, it contains some CAN Tx/Rx FIFO management limitations.
  18. Another HAL CAN driver version has been designed with new API's, to fix these limitations.
  19. ==============================================================================
  20. ##### How to use this driver #####
  21. ==============================================================================
  22. [..]
  23. (#) Enable the CAN controller interface clock using
  24. __HAL_RCC_CAN1_CLK_ENABLE() for CAN1, __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
  25. and __HAL_RCC_CAN3_CLK_ENABLE() for CAN3
  26. -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
  27. (#) CAN pins configuration
  28. (++) Enable the clock for the CAN GPIOs using the following function:
  29. __GPIOx_CLK_ENABLE()
  30. (++) Connect and configure the involved CAN pins to AF9 using the
  31. following function HAL_GPIO_Init()
  32. (#) Initialize and configure the CAN using CAN_Init() function.
  33. (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
  34. (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
  35. (#) Receive a CAN frame using HAL_CAN_Receive() function.
  36. (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
  37. *** Polling mode IO operation ***
  38. =================================
  39. [..]
  40. (+) Start the CAN peripheral transmission and wait the end of this operation
  41. using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
  42. according to his end application
  43. (+) Start the CAN peripheral reception and wait the end of this operation
  44. using HAL_CAN_Receive(), at this stage user can specify the value of timeout
  45. according to his end application
  46. *** Interrupt mode IO operation ***
  47. ===================================
  48. [..]
  49. (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
  50. (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
  51. (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
  52. (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
  53. add his own code by customization of function pointer HAL_CAN_TxCpltCallback
  54. (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
  55. add his own code by customization of function pointer HAL_CAN_ErrorCallback
  56. *** CAN HAL driver macros list ***
  57. =============================================
  58. [..]
  59. Below the list of most used macros in CAN HAL driver.
  60. (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
  61. (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
  62. (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
  63. (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
  64. (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
  65. [..]
  66. (@) You can refer to the CAN Legacy HAL driver header file for more useful macros
  67. @endverbatim
  68. ******************************************************************************
  69. * @attention
  70. *
  71. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  72. *
  73. * Redistribution and use in source and binary forms, with or without modification,
  74. * are permitted provided that the following conditions are met:
  75. * 1. Redistributions of source code must retain the above copyright notice,
  76. * this list of conditions and the following disclaimer.
  77. * 2. Redistributions in binary form must reproduce the above copyright notice,
  78. * this list of conditions and the following disclaimer in the documentation
  79. * and/or other materials provided with the distribution.
  80. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  81. * may be used to endorse or promote products derived from this software
  82. * without specific prior written permission.
  83. *
  84. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  85. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  87. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  88. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  89. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  90. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  91. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  92. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  93. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  94. *
  95. ******************************************************************************
  96. */
  97. /* Includes ------------------------------------------------------------------*/
  98. #include "stm32f4xx_hal.h"
  99. /** @addtogroup STM32F4xx_HAL_Driver
  100. * @{
  101. */
  102. /** @defgroup CAN CAN
  103. * @brief CAN driver modules
  104. * @{
  105. */
  106. #ifdef HAL_CAN_LEGACY_MODULE_ENABLED
  107. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
  108. defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
  109. defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
  110. defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||\
  111. defined(STM32F423xx)
  112. #ifdef HAL_CAN_MODULE_ENABLED
  113. /* Select HAL CAN module in stm32f4xx_hal_conf.h file:
  114. (#) HAL_CAN_MODULE_ENABLED for new HAL CAN driver fixing FIFO limitations
  115. (#) HAL_CAN_LEGACY_MODULE_ENABLED for legacy HAL CAN driver */
  116. #error 'The HAL CAN driver cannot be used with its legacy, Please ensure to enable only one HAL CAN module at once in stm32f4xx_hal_conf.h file'
  117. #endif /* HAL_CAN_MODULE_ENABLED */
  118. #warning 'Legacy HAL CAN driver is enabled! It can be used with known limitations, refer to the release notes. However it is recommended to use rather the new HAL CAN driver'
  119. /* Private typedef -----------------------------------------------------------*/
  120. /* Private define ------------------------------------------------------------*/
  121. /** @addtogroup CAN_Private_Constants
  122. * @{
  123. */
  124. #define CAN_TIMEOUT_VALUE 10U
  125. /**
  126. * @}
  127. */
  128. /* Private macro -------------------------------------------------------------*/
  129. /* Private variables ---------------------------------------------------------*/
  130. /* Private function prototypes -----------------------------------------------*/
  131. /** @addtogroup CAN_Private_Functions
  132. * @{
  133. */
  134. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
  135. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
  136. /**
  137. * @}
  138. */
  139. /* Exported functions --------------------------------------------------------*/
  140. /** @defgroup CAN_Exported_Functions CAN Exported Functions
  141. * @{
  142. */
  143. /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
  144. * @brief Initialization and Configuration functions
  145. *
  146. @verbatim
  147. ==============================================================================
  148. ##### Initialization and de-initialization functions #####
  149. ==============================================================================
  150. [..] This section provides functions allowing to:
  151. (+) Initialize and configure the CAN.
  152. (+) De-initialize the CAN.
  153. @endverbatim
  154. * @{
  155. */
  156. /**
  157. * @brief Initializes the CAN peripheral according to the specified
  158. * parameters in the CAN_InitStruct.
  159. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  160. * the configuration information for the specified CAN.
  161. * @retval HAL status
  162. */
  163. HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
  164. {
  165. uint32_t InitStatus = CAN_INITSTATUS_FAILED;
  166. uint32_t tickstart = 0U;
  167. /* Check CAN handle */
  168. if(hcan == NULL)
  169. {
  170. return HAL_ERROR;
  171. }
  172. /* Check the parameters */
  173. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  174. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
  175. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
  176. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
  177. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
  178. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
  179. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
  180. assert_param(IS_CAN_MODE(hcan->Init.Mode));
  181. assert_param(IS_CAN_SJW(hcan->Init.SJW));
  182. assert_param(IS_CAN_BS1(hcan->Init.BS1));
  183. assert_param(IS_CAN_BS2(hcan->Init.BS2));
  184. assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
  185. if(hcan->State == HAL_CAN_STATE_RESET)
  186. {
  187. /* Allocate lock resource and initialize it */
  188. hcan->Lock = HAL_UNLOCKED;
  189. /* Init the low level hardware */
  190. HAL_CAN_MspInit(hcan);
  191. }
  192. /* Initialize the CAN state*/
  193. hcan->State = HAL_CAN_STATE_BUSY;
  194. /* Exit from sleep mode */
  195. hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
  196. /* Request initialisation */
  197. hcan->Instance->MCR |= CAN_MCR_INRQ ;
  198. /* Get tick */
  199. tickstart = HAL_GetTick();
  200. /* Wait the acknowledge */
  201. while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
  202. {
  203. if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
  204. {
  205. hcan->State= HAL_CAN_STATE_TIMEOUT;
  206. /* Process unlocked */
  207. __HAL_UNLOCK(hcan);
  208. return HAL_TIMEOUT;
  209. }
  210. }
  211. /* Check acknowledge */
  212. if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
  213. {
  214. /* Set the time triggered communication mode */
  215. if (hcan->Init.TTCM == ENABLE)
  216. {
  217. hcan->Instance->MCR |= CAN_MCR_TTCM;
  218. }
  219. else
  220. {
  221. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
  222. }
  223. /* Set the automatic bus-off management */
  224. if (hcan->Init.ABOM == ENABLE)
  225. {
  226. hcan->Instance->MCR |= CAN_MCR_ABOM;
  227. }
  228. else
  229. {
  230. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
  231. }
  232. /* Set the automatic wake-up mode */
  233. if (hcan->Init.AWUM == ENABLE)
  234. {
  235. hcan->Instance->MCR |= CAN_MCR_AWUM;
  236. }
  237. else
  238. {
  239. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
  240. }
  241. /* Set the no automatic retransmission */
  242. if (hcan->Init.NART == ENABLE)
  243. {
  244. hcan->Instance->MCR |= CAN_MCR_NART;
  245. }
  246. else
  247. {
  248. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
  249. }
  250. /* Set the receive FIFO locked mode */
  251. if (hcan->Init.RFLM == ENABLE)
  252. {
  253. hcan->Instance->MCR |= CAN_MCR_RFLM;
  254. }
  255. else
  256. {
  257. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
  258. }
  259. /* Set the transmit FIFO priority */
  260. if (hcan->Init.TXFP == ENABLE)
  261. {
  262. hcan->Instance->MCR |= CAN_MCR_TXFP;
  263. }
  264. else
  265. {
  266. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
  267. }
  268. /* Set the bit timing register */
  269. hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
  270. ((uint32_t)hcan->Init.SJW) | \
  271. ((uint32_t)hcan->Init.BS1) | \
  272. ((uint32_t)hcan->Init.BS2) | \
  273. ((uint32_t)hcan->Init.Prescaler - 1U);
  274. /* Request leave initialisation */
  275. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
  276. /* Get tick */
  277. tickstart = HAL_GetTick();
  278. /* Wait the acknowledge */
  279. while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
  280. {
  281. if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
  282. {
  283. hcan->State= HAL_CAN_STATE_TIMEOUT;
  284. /* Process unlocked */
  285. __HAL_UNLOCK(hcan);
  286. return HAL_TIMEOUT;
  287. }
  288. }
  289. /* Check acknowledged */
  290. if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
  291. {
  292. InitStatus = CAN_INITSTATUS_SUCCESS;
  293. }
  294. }
  295. if(InitStatus == CAN_INITSTATUS_SUCCESS)
  296. {
  297. /* Set CAN error code to none */
  298. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  299. /* Initialize the CAN state */
  300. hcan->State = HAL_CAN_STATE_READY;
  301. /* Return function status */
  302. return HAL_OK;
  303. }
  304. else
  305. {
  306. /* Initialize the CAN state */
  307. hcan->State = HAL_CAN_STATE_ERROR;
  308. /* Return function status */
  309. return HAL_ERROR;
  310. }
  311. }
  312. /**
  313. * @brief Configures the CAN reception filter according to the specified
  314. * parameters in the CAN_FilterInitStruct.
  315. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  316. * the configuration information for the specified CAN.
  317. * @param sFilterConfig pointer to a CAN_FilterConfTypeDef structure that
  318. * contains the filter configuration information.
  319. * @retval None
  320. */
  321. HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
  322. {
  323. uint32_t filternbrbitpos = 0U;
  324. CAN_TypeDef *can_ip;
  325. /* Prevent unused argument(s) compilation warning */
  326. UNUSED(hcan);
  327. /* Check the parameters */
  328. assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
  329. assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
  330. assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
  331. assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
  332. assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
  333. assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
  334. filternbrbitpos = 1U << sFilterConfig->FilterNumber;
  335. #if defined (CAN3)
  336. /* Check the CAN instance */
  337. if(hcan->Instance == CAN3)
  338. {
  339. can_ip = CAN3;
  340. }
  341. else
  342. {
  343. can_ip = CAN1;
  344. }
  345. #else
  346. can_ip = CAN1;
  347. #endif
  348. /* Initialisation mode for the filter */
  349. can_ip->FMR |= (uint32_t)CAN_FMR_FINIT;
  350. #if defined (CAN2)
  351. /* Select the start slave bank */
  352. can_ip->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
  353. can_ip->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8U);
  354. #endif
  355. /* Filter Deactivation */
  356. can_ip->FA1R &= ~(uint32_t)filternbrbitpos;
  357. /* Filter Scale */
  358. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
  359. {
  360. /* 16-bit scale for the filter */
  361. can_ip->FS1R &= ~(uint32_t)filternbrbitpos;
  362. /* First 16-bit identifier and First 16-bit mask */
  363. /* Or First 16-bit identifier and Second 16-bit identifier */
  364. can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  365. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
  366. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
  367. /* Second 16-bit identifier and Second 16-bit mask */
  368. /* Or Third 16-bit identifier and Fourth 16-bit identifier */
  369. can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  370. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
  371. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
  372. }
  373. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
  374. {
  375. /* 32-bit scale for the filter */
  376. can_ip->FS1R |= filternbrbitpos;
  377. /* 32-bit identifier or First 32-bit identifier */
  378. can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  379. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
  380. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
  381. /* 32-bit mask or Second 32-bit identifier */
  382. can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  383. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
  384. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
  385. }
  386. /* Filter Mode */
  387. if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
  388. {
  389. /*Id/Mask mode for the filter*/
  390. can_ip->FM1R &= ~(uint32_t)filternbrbitpos;
  391. }
  392. else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  393. {
  394. /*Identifier list mode for the filter*/
  395. can_ip->FM1R |= (uint32_t)filternbrbitpos;
  396. }
  397. /* Filter FIFO assignment */
  398. if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
  399. {
  400. /* FIFO 0 assignation for the filter */
  401. can_ip->FFA1R &= ~(uint32_t)filternbrbitpos;
  402. }
  403. if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
  404. {
  405. /* FIFO 1 assignation for the filter */
  406. can_ip->FFA1R |= (uint32_t)filternbrbitpos;
  407. }
  408. /* Filter activation */
  409. if (sFilterConfig->FilterActivation == ENABLE)
  410. {
  411. can_ip->FA1R |= filternbrbitpos;
  412. }
  413. /* Leave the initialisation mode for the filter */
  414. can_ip->FMR &= ~((uint32_t)CAN_FMR_FINIT);
  415. /* Return function status */
  416. return HAL_OK;
  417. }
  418. /**
  419. * @brief Deinitializes the CANx peripheral registers to their default reset values.
  420. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  421. * the configuration information for the specified CAN.
  422. * @retval HAL status
  423. */
  424. HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
  425. {
  426. /* Check CAN handle */
  427. if(hcan == NULL)
  428. {
  429. return HAL_ERROR;
  430. }
  431. /* Check the parameters */
  432. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  433. /* Change CAN state */
  434. hcan->State = HAL_CAN_STATE_BUSY;
  435. /* DeInit the low level hardware */
  436. HAL_CAN_MspDeInit(hcan);
  437. /* Change CAN state */
  438. hcan->State = HAL_CAN_STATE_RESET;
  439. /* Release Lock */
  440. __HAL_UNLOCK(hcan);
  441. /* Return function status */
  442. return HAL_OK;
  443. }
  444. /**
  445. * @brief Initializes the CAN MSP.
  446. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  447. * the configuration information for the specified CAN.
  448. * @retval None
  449. */
  450. __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
  451. {
  452. /* Prevent unused argument(s) compilation warning */
  453. UNUSED(hcan);
  454. /* NOTE : This function Should not be modified, when the callback is needed,
  455. the HAL_CAN_MspInit could be implemented in the user file
  456. */
  457. }
  458. /**
  459. * @brief DeInitializes the CAN MSP.
  460. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  461. * the configuration information for the specified CAN.
  462. * @retval None
  463. */
  464. __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
  465. {
  466. /* Prevent unused argument(s) compilation warning */
  467. UNUSED(hcan);
  468. /* NOTE : This function Should not be modified, when the callback is needed,
  469. the HAL_CAN_MspDeInit could be implemented in the user file
  470. */
  471. }
  472. /**
  473. * @}
  474. */
  475. /** @defgroup CAN_Exported_Functions_Group2 IO operation functions
  476. * @brief IO operation functions
  477. *
  478. @verbatim
  479. ==============================================================================
  480. ##### IO operation functions #####
  481. ==============================================================================
  482. [..] This section provides functions allowing to:
  483. (+) Transmit a CAN frame message.
  484. (+) Receive a CAN frame message.
  485. (+) Enter CAN peripheral in sleep mode.
  486. (+) Wake up the CAN peripheral from sleep mode.
  487. @endverbatim
  488. * @{
  489. */
  490. /**
  491. * @brief Initiates and transmits a CAN frame message.
  492. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  493. * the configuration information for the specified CAN.
  494. * @param Timeout Specify Timeout value
  495. * @retval HAL status
  496. */
  497. HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
  498. {
  499. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  500. uint32_t tickstart = 0U;
  501. /* Check the parameters */
  502. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  503. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  504. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  505. if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
  506. ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
  507. ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
  508. {
  509. /* Process locked */
  510. __HAL_LOCK(hcan);
  511. /* Change CAN state */
  512. switch(hcan->State)
  513. {
  514. case(HAL_CAN_STATE_BUSY_RX0):
  515. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  516. break;
  517. case(HAL_CAN_STATE_BUSY_RX1):
  518. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  519. break;
  520. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  521. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  522. break;
  523. default: /* HAL_CAN_STATE_READY */
  524. hcan->State = HAL_CAN_STATE_BUSY_TX;
  525. break;
  526. }
  527. /* Select one empty transmit mailbox */
  528. if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
  529. {
  530. transmitmailbox = CAN_TXMAILBOX_0;
  531. }
  532. else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
  533. {
  534. transmitmailbox = CAN_TXMAILBOX_1;
  535. }
  536. else
  537. {
  538. transmitmailbox = CAN_TXMAILBOX_2;
  539. }
  540. /* Set up the Id */
  541. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  542. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  543. {
  544. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  545. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
  546. hcan->pTxMsg->RTR);
  547. }
  548. else
  549. {
  550. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  551. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
  552. hcan->pTxMsg->IDE | \
  553. hcan->pTxMsg->RTR);
  554. }
  555. /* Set up the DLC */
  556. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  557. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
  558. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  559. /* Set up the data field */
  560. hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
  561. ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
  562. ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
  563. ((uint32_t)hcan->pTxMsg->Data[0U]));
  564. hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
  565. ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
  566. ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
  567. ((uint32_t)hcan->pTxMsg->Data[4U]));
  568. /* Request transmission */
  569. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  570. /* Get tick */
  571. tickstart = HAL_GetTick();
  572. /* Check End of transmission flag */
  573. while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  574. {
  575. /* Check for the Timeout */
  576. if(Timeout != HAL_MAX_DELAY)
  577. {
  578. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  579. {
  580. hcan->State = HAL_CAN_STATE_TIMEOUT;
  581. __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
  582. /* Process unlocked */
  583. __HAL_UNLOCK(hcan);
  584. return HAL_TIMEOUT;
  585. }
  586. }
  587. }
  588. /* Change CAN state */
  589. switch(hcan->State)
  590. {
  591. case(HAL_CAN_STATE_BUSY_TX_RX0):
  592. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  593. break;
  594. case(HAL_CAN_STATE_BUSY_TX_RX1):
  595. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  596. break;
  597. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  598. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  599. break;
  600. default: /* HAL_CAN_STATE_BUSY_TX */
  601. hcan->State = HAL_CAN_STATE_READY;
  602. break;
  603. }
  604. /* Process unlocked */
  605. __HAL_UNLOCK(hcan);
  606. /* Return function status */
  607. return HAL_OK;
  608. }
  609. else
  610. {
  611. /* Change CAN state */
  612. hcan->State = HAL_CAN_STATE_ERROR;
  613. /* Return function status */
  614. return HAL_ERROR;
  615. }
  616. }
  617. /**
  618. * @brief Initiates and transmits a CAN frame message.
  619. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  620. * the configuration information for the specified CAN.
  621. * @retval HAL status
  622. */
  623. HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  624. {
  625. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  626. /* Check the parameters */
  627. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  628. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  629. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  630. if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
  631. ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
  632. ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
  633. {
  634. /* Process Locked */
  635. __HAL_LOCK(hcan);
  636. /* Select one empty transmit mailbox */
  637. if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
  638. {
  639. transmitmailbox = CAN_TXMAILBOX_0;
  640. }
  641. else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
  642. {
  643. transmitmailbox = CAN_TXMAILBOX_1;
  644. }
  645. else
  646. {
  647. transmitmailbox = CAN_TXMAILBOX_2;
  648. }
  649. /* Set up the Id */
  650. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  651. if(hcan->pTxMsg->IDE == CAN_ID_STD)
  652. {
  653. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  654. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
  655. hcan->pTxMsg->RTR);
  656. }
  657. else
  658. {
  659. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  660. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
  661. hcan->pTxMsg->IDE | \
  662. hcan->pTxMsg->RTR);
  663. }
  664. /* Set up the DLC */
  665. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  666. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
  667. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  668. /* Set up the data field */
  669. hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
  670. ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
  671. ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
  672. ((uint32_t)hcan->pTxMsg->Data[0U]));
  673. hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
  674. ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
  675. ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
  676. ((uint32_t)hcan->pTxMsg->Data[4U]));
  677. /* Change CAN state */
  678. switch(hcan->State)
  679. {
  680. case(HAL_CAN_STATE_BUSY_RX0):
  681. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  682. break;
  683. case(HAL_CAN_STATE_BUSY_RX1):
  684. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  685. break;
  686. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  687. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  688. break;
  689. default: /* HAL_CAN_STATE_READY */
  690. hcan->State = HAL_CAN_STATE_BUSY_TX;
  691. break;
  692. }
  693. /* Set CAN error code to none */
  694. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  695. /* Process Unlocked */
  696. __HAL_UNLOCK(hcan);
  697. /* Request transmission */
  698. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  699. /* Enable Error warning, Error passive, Bus-off,
  700. Last error and Error Interrupts */
  701. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  702. CAN_IT_EPV |
  703. CAN_IT_BOF |
  704. CAN_IT_LEC |
  705. CAN_IT_ERR |
  706. CAN_IT_TME);
  707. }
  708. else
  709. {
  710. /* Change CAN state */
  711. hcan->State = HAL_CAN_STATE_ERROR;
  712. /* Return function status */
  713. return HAL_ERROR;
  714. }
  715. return HAL_OK;
  716. }
  717. /**
  718. * @brief Receives a correct CAN frame.
  719. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  720. * the configuration information for the specified CAN.
  721. * @param FIFONumber FIFO Number value
  722. * @param Timeout Specify Timeout value
  723. * @retval HAL status
  724. */
  725. HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
  726. {
  727. uint32_t tickstart = 0U;
  728. CanRxMsgTypeDef* pRxMsg = NULL;
  729. /* Check the parameters */
  730. assert_param(IS_CAN_FIFO(FIFONumber));
  731. /* Check if CAN state is not busy for RX FIFO0 */
  732. if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
  733. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
  734. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  735. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  736. {
  737. return HAL_BUSY;
  738. }
  739. /* Check if CAN state is not busy for RX FIFO1 */
  740. if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
  741. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
  742. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  743. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  744. {
  745. return HAL_BUSY;
  746. }
  747. /* Process locked */
  748. __HAL_LOCK(hcan);
  749. /* Change CAN state */
  750. if (FIFONumber == CAN_FIFO0)
  751. {
  752. switch(hcan->State)
  753. {
  754. case(HAL_CAN_STATE_BUSY_TX):
  755. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  756. break;
  757. case(HAL_CAN_STATE_BUSY_RX1):
  758. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  759. break;
  760. case(HAL_CAN_STATE_BUSY_TX_RX1):
  761. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  762. break;
  763. default: /* HAL_CAN_STATE_READY */
  764. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  765. break;
  766. }
  767. }
  768. else /* FIFONumber == CAN_FIFO1 */
  769. {
  770. switch(hcan->State)
  771. {
  772. case(HAL_CAN_STATE_BUSY_TX):
  773. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  774. break;
  775. case(HAL_CAN_STATE_BUSY_RX0):
  776. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  777. break;
  778. case(HAL_CAN_STATE_BUSY_TX_RX0):
  779. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  780. break;
  781. default: /* HAL_CAN_STATE_READY */
  782. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  783. break;
  784. }
  785. }
  786. /* Get tick */
  787. tickstart = HAL_GetTick();
  788. /* Check pending message */
  789. while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
  790. {
  791. /* Check for the Timeout */
  792. if(Timeout != HAL_MAX_DELAY)
  793. {
  794. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  795. {
  796. hcan->State = HAL_CAN_STATE_TIMEOUT;
  797. /* Process unlocked */
  798. __HAL_UNLOCK(hcan);
  799. return HAL_TIMEOUT;
  800. }
  801. }
  802. }
  803. /* Set RxMsg pointer */
  804. if(FIFONumber == CAN_FIFO0)
  805. {
  806. pRxMsg = hcan->pRxMsg;
  807. }
  808. else /* FIFONumber == CAN_FIFO1 */
  809. {
  810. pRxMsg = hcan->pRx1Msg;
  811. }
  812. /* Get the Id */
  813. pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  814. if (pRxMsg->IDE == CAN_ID_STD)
  815. {
  816. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
  817. }
  818. else
  819. {
  820. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
  821. }
  822. pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  823. /* Get the DLC */
  824. pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  825. /* Get the FMI */
  826. pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
  827. /* Get the FIFONumber */
  828. pRxMsg->FIFONumber = FIFONumber;
  829. /* Get the data field */
  830. pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  831. pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
  832. pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
  833. pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
  834. pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  835. pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
  836. pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
  837. pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
  838. /* Release the FIFO */
  839. if(FIFONumber == CAN_FIFO0)
  840. {
  841. /* Release FIFO0 */
  842. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  843. }
  844. else /* FIFONumber == CAN_FIFO1 */
  845. {
  846. /* Release FIFO1 */
  847. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  848. }
  849. /* Change CAN state */
  850. if (FIFONumber == CAN_FIFO0)
  851. {
  852. switch(hcan->State)
  853. {
  854. case(HAL_CAN_STATE_BUSY_TX_RX0):
  855. hcan->State = HAL_CAN_STATE_BUSY_TX;
  856. break;
  857. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  858. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  859. break;
  860. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  861. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  862. break;
  863. default: /* HAL_CAN_STATE_BUSY_RX0 */
  864. hcan->State = HAL_CAN_STATE_READY;
  865. break;
  866. }
  867. }
  868. else /* FIFONumber == CAN_FIFO1 */
  869. {
  870. switch(hcan->State)
  871. {
  872. case(HAL_CAN_STATE_BUSY_TX_RX1):
  873. hcan->State = HAL_CAN_STATE_BUSY_TX;
  874. break;
  875. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  876. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  877. break;
  878. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  879. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  880. break;
  881. default: /* HAL_CAN_STATE_BUSY_RX1 */
  882. hcan->State = HAL_CAN_STATE_READY;
  883. break;
  884. }
  885. }
  886. /* Process unlocked */
  887. __HAL_UNLOCK(hcan);
  888. /* Return function status */
  889. return HAL_OK;
  890. }
  891. /**
  892. * @brief Receives a correct CAN frame.
  893. * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
  894. * the configuration information for the specified CAN.
  895. * @param FIFONumber Specify the FIFO number
  896. * @retval HAL status
  897. */
  898. HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  899. {
  900. /* Check the parameters */
  901. assert_param(IS_CAN_FIFO(FIFONumber));
  902. /* Check if CAN state is not busy for RX FIFO0 */
  903. if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
  904. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
  905. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  906. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  907. {
  908. return HAL_BUSY;
  909. }
  910. /* Check if CAN state is not busy for RX FIFO1 */
  911. if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
  912. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
  913. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  914. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  915. {
  916. return HAL_BUSY;
  917. }
  918. /* Process locked */
  919. __HAL_LOCK(hcan);
  920. /* Change CAN state */
  921. if(FIFONumber == CAN_FIFO0)
  922. {
  923. switch(hcan->State)
  924. {
  925. case(HAL_CAN_STATE_BUSY_TX):
  926. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  927. break;
  928. case(HAL_CAN_STATE_BUSY_RX1):
  929. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  930. break;
  931. case(HAL_CAN_STATE_BUSY_TX_RX1):
  932. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  933. break;
  934. default: /* HAL_CAN_STATE_READY */
  935. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  936. break;
  937. }
  938. }
  939. else /* FIFONumber == CAN_FIFO1 */
  940. {
  941. switch(hcan->State)
  942. {
  943. case(HAL_CAN_STATE_BUSY_TX):
  944. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  945. break;
  946. case(HAL_CAN_STATE_BUSY_RX0):
  947. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  948. break;
  949. case(HAL_CAN_STATE_BUSY_TX_RX0):
  950. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  951. break;
  952. default: /* HAL_CAN_STATE_READY */
  953. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  954. break;
  955. }
  956. }
  957. /* Set CAN error code to none */
  958. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  959. /* Enable interrupts: */
  960. /* - Enable Error warning Interrupt */
  961. /* - Enable Error passive Interrupt */
  962. /* - Enable Bus-off Interrupt */
  963. /* - Enable Last error code Interrupt */
  964. /* - Enable Error Interrupt */
  965. /* - Enable Transmit mailbox empty Interrupt */
  966. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  967. CAN_IT_EPV |
  968. CAN_IT_BOF |
  969. CAN_IT_LEC |
  970. CAN_IT_ERR |
  971. CAN_IT_TME);
  972. /* Process unlocked */
  973. __HAL_UNLOCK(hcan);
  974. if(FIFONumber == CAN_FIFO0)
  975. {
  976. /* Enable FIFO 0 overrun and message pending Interrupt */
  977. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
  978. }
  979. else
  980. {
  981. /* Enable FIFO 1 overrun and message pending Interrupt */
  982. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
  983. }
  984. /* Return function status */
  985. return HAL_OK;
  986. }
  987. /**
  988. * @brief Enters the Sleep (low power) mode.
  989. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  990. * the configuration information for the specified CAN.
  991. * @retval HAL status.
  992. */
  993. HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
  994. {
  995. uint32_t tickstart = 0U;
  996. /* Process locked */
  997. __HAL_LOCK(hcan);
  998. /* Change CAN state */
  999. hcan->State = HAL_CAN_STATE_BUSY;
  1000. /* Request Sleep mode */
  1001. hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
  1002. /* Sleep mode status */
  1003. if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
  1004. {
  1005. /* Process unlocked */
  1006. __HAL_UNLOCK(hcan);
  1007. /* Return function status */
  1008. return HAL_ERROR;
  1009. }
  1010. /* Get tick */
  1011. tickstart = HAL_GetTick();
  1012. /* Wait the acknowledge */
  1013. while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
  1014. {
  1015. if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
  1016. {
  1017. hcan->State = HAL_CAN_STATE_TIMEOUT;
  1018. /* Process unlocked */
  1019. __HAL_UNLOCK(hcan);
  1020. return HAL_TIMEOUT;
  1021. }
  1022. }
  1023. /* Change CAN state */
  1024. hcan->State = HAL_CAN_STATE_READY;
  1025. /* Process unlocked */
  1026. __HAL_UNLOCK(hcan);
  1027. /* Return function status */
  1028. return HAL_OK;
  1029. }
  1030. /**
  1031. * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
  1032. * is in the normal mode.
  1033. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1034. * the configuration information for the specified CAN.
  1035. * @retval HAL status.
  1036. */
  1037. HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
  1038. {
  1039. uint32_t tickstart = 0U;
  1040. /* Process locked */
  1041. __HAL_LOCK(hcan);
  1042. /* Change CAN state */
  1043. hcan->State = HAL_CAN_STATE_BUSY;
  1044. /* Wake up request */
  1045. hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
  1046. /* Get tick */
  1047. tickstart = HAL_GetTick();
  1048. /* Sleep mode status */
  1049. while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
  1050. {
  1051. if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
  1052. {
  1053. hcan->State= HAL_CAN_STATE_TIMEOUT;
  1054. /* Process unlocked */
  1055. __HAL_UNLOCK(hcan);
  1056. return HAL_TIMEOUT;
  1057. }
  1058. }
  1059. if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
  1060. {
  1061. /* Process unlocked */
  1062. __HAL_UNLOCK(hcan);
  1063. /* Return function status */
  1064. return HAL_ERROR;
  1065. }
  1066. /* Change CAN state */
  1067. hcan->State = HAL_CAN_STATE_READY;
  1068. /* Process unlocked */
  1069. __HAL_UNLOCK(hcan);
  1070. /* Return function status */
  1071. return HAL_OK;
  1072. }
  1073. /**
  1074. * @brief Handles CAN interrupt request
  1075. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1076. * the configuration information for the specified CAN.
  1077. * @retval None
  1078. */
  1079. void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
  1080. {
  1081. uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
  1082. uint32_t errorcode = HAL_CAN_ERROR_NONE;
  1083. /* Check Overrun flag for FIFO0 */
  1084. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0);
  1085. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0);
  1086. if(tmp1 && tmp2)
  1087. {
  1088. /* Set CAN error code to FOV0 error */
  1089. errorcode |= HAL_CAN_ERROR_FOV0;
  1090. /* Clear FIFO0 Overrun Flag */
  1091. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
  1092. }
  1093. /* Check Overrun flag for FIFO1 */
  1094. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1);
  1095. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1);
  1096. if(tmp1 && tmp2)
  1097. {
  1098. /* Set CAN error code to FOV1 error */
  1099. errorcode |= HAL_CAN_ERROR_FOV1;
  1100. /* Clear FIFO1 Overrun Flag */
  1101. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
  1102. }
  1103. /* Check End of transmission flag */
  1104. if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
  1105. {
  1106. tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
  1107. tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
  1108. tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
  1109. if(tmp1 || tmp2 || tmp3)
  1110. {
  1111. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0);
  1112. tmp2 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1);
  1113. tmp3 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2);
  1114. /* Check Transmit success */
  1115. if(tmp1 || tmp2 || tmp3)
  1116. {
  1117. /* Call transmit function */
  1118. CAN_Transmit_IT(hcan);
  1119. }
  1120. else /* Transmit failure */
  1121. {
  1122. /* Set CAN error code to TXFAIL error */
  1123. errorcode |= HAL_CAN_ERROR_TXFAIL;
  1124. }
  1125. /* Clear transmission status flags (RQCPx and TXOKx) */
  1126. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
  1127. CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
  1128. }
  1129. }
  1130. tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
  1131. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
  1132. /* Check End of reception flag for FIFO0 */
  1133. if((tmp1 != 0U) && tmp2)
  1134. {
  1135. /* Call receive function */
  1136. CAN_Receive_IT(hcan, CAN_FIFO0);
  1137. }
  1138. tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
  1139. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
  1140. /* Check End of reception flag for FIFO1 */
  1141. if((tmp1 != 0U) && tmp2)
  1142. {
  1143. /* Call receive function */
  1144. CAN_Receive_IT(hcan, CAN_FIFO1);
  1145. }
  1146. /* Set error code in handle */
  1147. hcan->ErrorCode |= errorcode;
  1148. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
  1149. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
  1150. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1151. /* Check Error Warning Flag */
  1152. if(tmp1 && tmp2 && tmp3)
  1153. {
  1154. /* Set CAN error code to EWG error */
  1155. hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
  1156. }
  1157. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
  1158. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
  1159. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1160. /* Check Error Passive Flag */
  1161. if(tmp1 && tmp2 && tmp3)
  1162. {
  1163. /* Set CAN error code to EPV error */
  1164. hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
  1165. }
  1166. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
  1167. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
  1168. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1169. /* Check Bus-Off Flag */
  1170. if(tmp1 && tmp2 && tmp3)
  1171. {
  1172. /* Set CAN error code to BOF error */
  1173. hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
  1174. }
  1175. tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
  1176. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
  1177. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1178. /* Check Last error code Flag */
  1179. if((!tmp1) && tmp2 && tmp3)
  1180. {
  1181. tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
  1182. switch(tmp1)
  1183. {
  1184. case(CAN_ESR_LEC_0):
  1185. /* Set CAN error code to STF error */
  1186. hcan->ErrorCode |= HAL_CAN_ERROR_STF;
  1187. break;
  1188. case(CAN_ESR_LEC_1):
  1189. /* Set CAN error code to FOR error */
  1190. hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
  1191. break;
  1192. case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
  1193. /* Set CAN error code to ACK error */
  1194. hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
  1195. break;
  1196. case(CAN_ESR_LEC_2):
  1197. /* Set CAN error code to BR error */
  1198. hcan->ErrorCode |= HAL_CAN_ERROR_BR;
  1199. break;
  1200. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
  1201. /* Set CAN error code to BD error */
  1202. hcan->ErrorCode |= HAL_CAN_ERROR_BD;
  1203. break;
  1204. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
  1205. /* Set CAN error code to CRC error */
  1206. hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
  1207. break;
  1208. default:
  1209. break;
  1210. }
  1211. /* Clear Last error code Flag */
  1212. hcan->Instance->ESR &= ~(CAN_ESR_LEC);
  1213. }
  1214. /* Call the Error call Back in case of Errors */
  1215. if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
  1216. {
  1217. /* Clear ERRI Flag */
  1218. hcan->Instance->MSR = CAN_MSR_ERRI;
  1219. /* Set the CAN state ready to be able to start again the process */
  1220. hcan->State = HAL_CAN_STATE_READY;
  1221. /* Disable interrupts: */
  1222. /* - Disable Error warning Interrupt */
  1223. /* - Disable Error passive Interrupt */
  1224. /* - Disable Bus-off Interrupt */
  1225. /* - Disable Last error code Interrupt */
  1226. /* - Disable Error Interrupt */
  1227. /* - Disable FIFO 0 message pending Interrupt */
  1228. /* - Disable FIFO 0 Overrun Interrupt */
  1229. /* - Disable FIFO 1 message pending Interrupt */
  1230. /* - Disable FIFO 1 Overrun Interrupt */
  1231. /* - Disable Transmit mailbox empty Interrupt */
  1232. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1233. CAN_IT_EPV |
  1234. CAN_IT_BOF |
  1235. CAN_IT_LEC |
  1236. CAN_IT_ERR |
  1237. CAN_IT_FMP0|
  1238. CAN_IT_FOV0|
  1239. CAN_IT_FMP1|
  1240. CAN_IT_FOV1|
  1241. CAN_IT_TME);
  1242. /* Call Error callback function */
  1243. HAL_CAN_ErrorCallback(hcan);
  1244. }
  1245. }
  1246. /**
  1247. * @brief Transmission complete callback in non blocking mode
  1248. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1249. * the configuration information for the specified CAN.
  1250. * @retval None
  1251. */
  1252. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
  1253. {
  1254. /* Prevent unused argument(s) compilation warning */
  1255. UNUSED(hcan);
  1256. /* NOTE : This function Should not be modified, when the callback is needed,
  1257. the HAL_CAN_TxCpltCallback could be implemented in the user file
  1258. */
  1259. }
  1260. /**
  1261. * @brief Transmission complete callback in non blocking mode
  1262. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1263. * the configuration information for the specified CAN.
  1264. * @retval None
  1265. */
  1266. __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  1267. {
  1268. /* Prevent unused argument(s) compilation warning */
  1269. UNUSED(hcan);
  1270. /* NOTE : This function Should not be modified, when the callback is needed,
  1271. the HAL_CAN_RxCpltCallback could be implemented in the user file
  1272. */
  1273. }
  1274. /**
  1275. * @brief Error CAN callback.
  1276. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1277. * the configuration information for the specified CAN.
  1278. * @retval None
  1279. */
  1280. __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  1281. {
  1282. /* Prevent unused argument(s) compilation warning */
  1283. UNUSED(hcan);
  1284. /* NOTE : This function Should not be modified, when the callback is needed,
  1285. the HAL_CAN_ErrorCallback could be implemented in the user file
  1286. */
  1287. }
  1288. /**
  1289. * @}
  1290. */
  1291. /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
  1292. * @brief CAN Peripheral State functions
  1293. *
  1294. @verbatim
  1295. ==============================================================================
  1296. ##### Peripheral State and Error functions #####
  1297. ==============================================================================
  1298. [..]
  1299. This subsection provides functions allowing to :
  1300. (+) Check the CAN state.
  1301. (+) Check CAN Errors detected during interrupt process
  1302. @endverbatim
  1303. * @{
  1304. */
  1305. /**
  1306. * @brief return the CAN state
  1307. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1308. * the configuration information for the specified CAN.
  1309. * @retval HAL state
  1310. */
  1311. HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
  1312. {
  1313. /* Return CAN state */
  1314. return hcan->State;
  1315. }
  1316. /**
  1317. * @brief Return the CAN error code
  1318. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1319. * the configuration information for the specified CAN.
  1320. * @retval CAN Error Code
  1321. */
  1322. uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
  1323. {
  1324. return hcan->ErrorCode;
  1325. }
  1326. /**
  1327. * @}
  1328. */
  1329. /**
  1330. * @brief Initiates and transmits a CAN frame message.
  1331. * @param hcan pointer to a CAN_HandleTypeDef structure that contains
  1332. * the configuration information for the specified CAN.
  1333. * @retval HAL status
  1334. */
  1335. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  1336. {
  1337. /* Disable Transmit mailbox empty Interrupt */
  1338. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
  1339. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  1340. {
  1341. /* Disable Error warning, Error passive, Bus-off, Last error code
  1342. and Error Interrupts */
  1343. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1344. CAN_IT_EPV |
  1345. CAN_IT_BOF |
  1346. CAN_IT_LEC |
  1347. CAN_IT_ERR );
  1348. }
  1349. /* Change CAN state */
  1350. switch(hcan->State)
  1351. {
  1352. case(HAL_CAN_STATE_BUSY_TX_RX0):
  1353. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  1354. break;
  1355. case(HAL_CAN_STATE_BUSY_TX_RX1):
  1356. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  1357. break;
  1358. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1359. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  1360. break;
  1361. default: /* HAL_CAN_STATE_BUSY_TX */
  1362. hcan->State = HAL_CAN_STATE_READY;
  1363. break;
  1364. }
  1365. /* Transmission complete callback */
  1366. HAL_CAN_TxCpltCallback(hcan);
  1367. return HAL_OK;
  1368. }
  1369. /**
  1370. * @brief Receives a correct CAN frame.
  1371. * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
  1372. * the configuration information for the specified CAN.
  1373. * @param FIFONumber Specify the FIFO number
  1374. * @retval HAL status
  1375. * @retval None
  1376. */
  1377. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  1378. {
  1379. uint32_t tmp1 = 0U;
  1380. CanRxMsgTypeDef* pRxMsg = NULL;
  1381. /* Set RxMsg pointer */
  1382. if(FIFONumber == CAN_FIFO0)
  1383. {
  1384. pRxMsg = hcan->pRxMsg;
  1385. }
  1386. else /* FIFONumber == CAN_FIFO1 */
  1387. {
  1388. pRxMsg = hcan->pRx1Msg;
  1389. }
  1390. /* Get the Id */
  1391. pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1392. if (pRxMsg->IDE == CAN_ID_STD)
  1393. {
  1394. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
  1395. }
  1396. else
  1397. {
  1398. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
  1399. }
  1400. pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1401. /* Get the DLC */
  1402. pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  1403. /* Get the FIFONumber */
  1404. pRxMsg->FIFONumber = FIFONumber;
  1405. /* Get the FMI */
  1406. pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
  1407. /* Get the data field */
  1408. pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  1409. pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
  1410. pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
  1411. pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
  1412. pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  1413. pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
  1414. pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
  1415. pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
  1416. /* Release the FIFO */
  1417. /* Release FIFO0 */
  1418. if (FIFONumber == CAN_FIFO0)
  1419. {
  1420. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  1421. /* Disable FIFO 0 overrun and message pending Interrupt */
  1422. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
  1423. }
  1424. /* Release FIFO1 */
  1425. else /* FIFONumber == CAN_FIFO1 */
  1426. {
  1427. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  1428. /* Disable FIFO 1 overrun and message pending Interrupt */
  1429. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
  1430. }
  1431. tmp1 = hcan->State;
  1432. if((tmp1 == HAL_CAN_STATE_BUSY_RX0) || (tmp1 == HAL_CAN_STATE_BUSY_RX1))
  1433. {
  1434. /* Disable Error warning, Error passive, Bus-off, Last error code
  1435. and Error Interrupts */
  1436. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1437. CAN_IT_EPV |
  1438. CAN_IT_BOF |
  1439. CAN_IT_LEC |
  1440. CAN_IT_ERR);
  1441. }
  1442. /* Change CAN state */
  1443. if (FIFONumber == CAN_FIFO0)
  1444. {
  1445. switch(hcan->State)
  1446. {
  1447. case(HAL_CAN_STATE_BUSY_TX_RX0):
  1448. hcan->State = HAL_CAN_STATE_BUSY_TX;
  1449. break;
  1450. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  1451. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  1452. break;
  1453. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1454. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  1455. break;
  1456. default: /* HAL_CAN_STATE_BUSY_RX0 */
  1457. hcan->State = HAL_CAN_STATE_READY;
  1458. break;
  1459. }
  1460. }
  1461. else /* FIFONumber == CAN_FIFO1 */
  1462. {
  1463. switch(hcan->State)
  1464. {
  1465. case(HAL_CAN_STATE_BUSY_TX_RX1):
  1466. hcan->State = HAL_CAN_STATE_BUSY_TX;
  1467. break;
  1468. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  1469. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  1470. break;
  1471. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1472. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  1473. break;
  1474. default: /* HAL_CAN_STATE_BUSY_RX1 */
  1475. hcan->State = HAL_CAN_STATE_READY;
  1476. break;
  1477. }
  1478. }
  1479. /* Receive complete callback */
  1480. HAL_CAN_RxCpltCallback(hcan);
  1481. /* Return function status */
  1482. return HAL_OK;
  1483. }
  1484. /**
  1485. * @}
  1486. */
  1487. #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
  1488. STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx ||\
  1489. STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
  1490. #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
  1491. /**
  1492. * @}
  1493. */
  1494. /**
  1495. * @}
  1496. */
  1497. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/