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