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