stm32f4xx_hal_can.c 44 KB

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