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