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