stm32l4xx_hal_can.c 45 KB

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