]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_can.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F1 / stm32f1xx_hal_can.c
1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_hal_can.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    15-December-2014
7   * @brief   CAN HAL module driver.
8   *          This file provides firmware functions to manage the following 
9   *          functionalities of the Controller Area Network (CAN) peripheral:           
10   *           + Initialization and de-initialization functions 
11   *           + IO operation functions
12   *           + Peripheral Control functions
13   *           + Peripheral State and Error functions
14   *
15   @verbatim
16   ==============================================================================
17                         ##### How to use this driver #####
18   ==============================================================================
19     [..]            
20       (#) Enable the CAN controller interface clock using 
21           __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
22       -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
23        
24       (#) CAN pins configuration
25         (++) Enable the clock for the CAN GPIOs using the following function:
26              __HAL_RCC_GPIOx_CLK_ENABLE();   
27         (++) Connect and configure the involved CAN pins using the 
28               following function HAL_GPIO_Init(); 
29               
30       (#) Initialise and configure the CAN using HAL_CAN_Init() function.   
31                  
32       (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
33            
34       (#) Receive a CAN frame using HAL_CAN_Receive() 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) 2014 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 "stm32f1xx_hal.h"
105   
106 #ifdef HAL_CAN_MODULE_ENABLED  
107   
108 #if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
109     defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
110       
111 /** @addtogroup STM32F1xx_HAL_Driver
112   * @{
113   */
114
115 /** @defgroup CAN CAN
116   * @brief CAN driver modules
117   * @{
118   */
119
120 /* Private typedef -----------------------------------------------------------*/
121 /* Private define ------------------------------------------------------------*/
122 /** @defgroup CAN_Private_Constants CAN Private Constants
123   * @{
124   */
125 #define CAN_TIMEOUT_VALUE  10
126       
127 #define CAN_TI0R_STID_BIT_POSITION    ((uint32_t)21)  /* Position of LSB bits STID in register CAN_TI0R */
128 #define CAN_TI0R_EXID_BIT_POSITION    ((uint32_t) 3)  /* Position of LSB bits EXID in register CAN_TI0R */
129 #define CAN_TDL0R_DATA0_BIT_POSITION  ((uint32_t) 0)  /* Position of LSB bits DATA0 in register CAN_TDL0R */
130 #define CAN_TDL0R_DATA1_BIT_POSITION  ((uint32_t) 8)  /* Position of LSB bits DATA1 in register CAN_TDL0R */
131 #define CAN_TDL0R_DATA2_BIT_POSITION  ((uint32_t)16)  /* Position of LSB bits DATA2 in register CAN_TDL0R */
132 #define CAN_TDL0R_DATA3_BIT_POSITION  ((uint32_t)24)  /* Position of LSB bits DATA3 in register CAN_TDL0R */
133       
134 /**
135   * @}
136   */
137
138 /* Private macro -------------------------------------------------------------*/
139 /* Private variables ---------------------------------------------------------*/
140 /* Private function prototypes -----------------------------------------------*/
141 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
142 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
143 /* Exported functions ---------------------------------------------------------*/
144
145 /** @defgroup CAN_Exported_Functions CAN Exported Functions
146   * @{
147   */
148
149 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions 
150  *  @brief    Initialization and Configuration functions 
151  *
152 @verbatim    
153   ==============================================================================
154               ##### Initialization and de-initialization functions #####
155   ==============================================================================
156     [..]  This section provides functions allowing to:
157       (+) Initialize and configure the CAN. 
158       (+) De-initialize the CAN. 
159          
160 @endverbatim
161   * @{
162   */
163   
164 /**
165   * @brief  Initializes the CAN peripheral according to the specified
166   *         parameters in the CAN_InitStruct.
167   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
168   *         the configuration information for the specified CAN.  
169   * @retval HAL status
170   */
171 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
172 {
173   uint32_t status = CAN_INITSTATUS_FAILED;  /* Default init status */
174   uint32_t tickstart = 0;
175   uint32_t tmp_mcr = 0;
176   
177   /* Check CAN handle */
178   if(hcan == NULL)
179   {
180      return HAL_ERROR;
181   }
182
183   /* Check the parameters */
184   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
185   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
186   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
187   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
188   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
189   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
190   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
191   assert_param(IS_CAN_MODE(hcan->Init.Mode));
192   assert_param(IS_CAN_SJW(hcan->Init.SJW));
193   assert_param(IS_CAN_BS1(hcan->Init.BS1));
194   assert_param(IS_CAN_BS2(hcan->Init.BS2));
195   assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
196   
197   if(hcan->State == HAL_CAN_STATE_RESET)
198   {
199     /* Allocate lock resource and initialize it */
200     hcan-> Lock = HAL_UNLOCKED;
201     /* Init the low level hardware */
202     HAL_CAN_MspInit(hcan);
203   }
204   
205   /* Initialize the CAN state*/
206   hcan->State = HAL_CAN_STATE_BUSY;
207   
208   /* Exit from sleep mode */
209   CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
210
211   /* Request initialisation */
212   SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
213
214   /* Get timeout */
215   tickstart = HAL_GetTick();   
216   
217   /* Wait the acknowledge */
218   while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
219   {
220     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
221     {
222       hcan->State= HAL_CAN_STATE_TIMEOUT;
223
224       /* Process unlocked */
225       __HAL_UNLOCK(hcan);
226
227       return HAL_TIMEOUT;
228     }
229   }
230
231   /* Check acknowledge */
232   if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
233   {
234     /* Set the time triggered communication mode */
235     if (hcan->Init.TTCM == ENABLE)
236     {
237       SET_BIT(tmp_mcr, CAN_MCR_TTCM);
238     }
239
240     /* Set the automatic bus-off management */
241     if (hcan->Init.ABOM == ENABLE)
242     {
243       SET_BIT(tmp_mcr, CAN_MCR_ABOM);
244     }
245
246     /* Set the automatic wake-up mode */
247     if (hcan->Init.AWUM == ENABLE)
248     {
249       SET_BIT(tmp_mcr, CAN_MCR_AWUM);
250     }
251     
252     /* Set the no automatic retransmission */
253     if (hcan->Init.NART == ENABLE)
254     {
255       SET_BIT(tmp_mcr, CAN_MCR_NART);
256     }
257
258     /* Set the receive FIFO locked mode */
259     if (hcan->Init.RFLM == ENABLE)
260     {
261       SET_BIT(tmp_mcr, CAN_MCR_RFLM);
262     }
263     
264     /* Set the transmit FIFO priority */
265     if (hcan->Init.TXFP == ENABLE)
266     {
267       SET_BIT(tmp_mcr, CAN_MCR_TXFP);
268     }
269     
270     /* Update register MCR */
271     MODIFY_REG(hcan->Instance->MCR,
272                CAN_MCR_TTCM |
273                CAN_MCR_ABOM |
274                CAN_MCR_AWUM |
275                CAN_MCR_NART |
276                CAN_MCR_RFLM |
277                CAN_MCR_TXFP,
278                tmp_mcr);
279     
280     /* Set the bit timing register */
281     WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode           |
282                                               hcan->Init.SJW            |
283                                               hcan->Init.BS1            |
284                                               hcan->Init.BS2            |
285                                               (hcan->Init.Prescaler - 1) ));
286
287     /* Request leave initialisation */
288     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
289
290     /* Get timeout */
291     tickstart = HAL_GetTick();   
292    
293     /* Wait the acknowledge */
294     while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
295     {
296       if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
297       {
298         hcan->State= HAL_CAN_STATE_TIMEOUT;
299
300         /* Process unlocked */
301         __HAL_UNLOCK(hcan);
302
303         return HAL_TIMEOUT;
304       }
305     }
306
307     /* Check acknowledged */
308     if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
309     {
310       status = CAN_INITSTATUS_SUCCESS;
311     }
312   }
313  
314   if(status == CAN_INITSTATUS_SUCCESS)
315   {
316     /* Set CAN error code to none */
317     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
318     
319     /* Initialize the CAN state */
320     hcan->State = HAL_CAN_STATE_READY;
321   
322     /* Return function status */
323     return HAL_OK;
324   }
325   else
326   {
327     /* Initialize the CAN state */
328     hcan->State = HAL_CAN_STATE_ERROR;
329     
330     /* Return function status */
331     return HAL_ERROR;
332   }
333 }
334
335 /**
336   * @brief  Configures the CAN reception filter according to the specified
337   *         parameters in the CAN_FilterInitStruct.
338   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
339   *         the configuration information for the specified CAN.
340   * @param  sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
341   *         contains the filter configuration information.
342   * @retval None
343   */
344 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
345 {
346   uint32_t filternbrbitpos = 0;
347   
348   /* Check the parameters */
349   assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
350   assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
351   assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
352   assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
353   assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
354   assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
355   
356   filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
357
358   /* Initialisation mode for the filter */
359   /* Select the start slave bank */
360   MODIFY_REG(hcan->Instance->FMR                         ,
361              CAN_FMR_CAN2SB                              ,
362              CAN_FMR_FINIT                              |
363              (uint32_t)(sFilterConfig->BankNumber << 8)   );
364   
365   /* Filter Deactivation */
366   CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
367   
368   /* Filter Scale */
369   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
370   {
371     /* 16-bit scale for the filter */
372     CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
373
374     /* First 16-bit identifier and First 16-bit mask */
375     /* Or First 16-bit identifier and Second 16-bit identifier */
376     hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
377        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
378         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
379
380     /* Second 16-bit identifier and Second 16-bit mask */
381     /* Or Third 16-bit identifier and Fourth 16-bit identifier */
382     hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
383        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
384         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
385   }
386
387   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
388   {
389     /* 32-bit scale for the filter */
390     SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
391     /* 32-bit identifier or First 32-bit identifier */
392     hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
393        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
394         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
395     /* 32-bit mask or Second 32-bit identifier */
396     hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
397        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
398         (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
399   }
400
401   /* Filter Mode */
402   if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
403   {
404     /*Id/Mask mode for the filter*/
405     CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
406   }
407   else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
408   {
409     /*Identifier list mode for the filter*/
410     SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
411   }
412
413   /* Filter FIFO assignment */
414   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
415   {
416     /* FIFO 0 assignation for the filter */
417     CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
418   }
419   else
420   {
421     /* FIFO 1 assignation for the filter */
422     SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
423   }
424   
425   /* Filter activation */
426   if (sFilterConfig->FilterActivation == ENABLE)
427   {
428     SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
429   }
430
431   /* Leave the initialisation mode for the filter */
432   CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
433   
434   /* Return function status */
435   return HAL_OK;
436 }
437
438 /**
439   * @brief  Deinitializes the CANx peripheral registers to their default reset values. 
440   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
441   *         the configuration information for the specified CAN.  
442   * @retval HAL status
443   */
444 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
445 {
446   /* Check CAN handle */
447   if(hcan == NULL)
448   {
449      return HAL_ERROR;
450   }
451   
452   /* Check the parameters */
453   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
454   
455   /* Change CAN state */
456   hcan->State = HAL_CAN_STATE_BUSY;
457   
458   /* DeInit the low level hardware */
459   HAL_CAN_MspDeInit(hcan);
460   
461   /* Change CAN state */
462   hcan->State = HAL_CAN_STATE_RESET;
463
464   /* Release Lock */
465   __HAL_UNLOCK(hcan);
466
467   /* Return function status */
468   return HAL_OK;
469 }
470
471 /**
472   * @brief  Initializes the CAN MSP.
473   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
474   *         the configuration information for the specified CAN.  
475   * @retval None
476   */
477 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
478 {
479   /* NOTE : This function Should not be modified, when the callback is needed,
480             the HAL_CAN_MspInit can be implemented in the user file
481    */ 
482 }
483
484 /**
485   * @brief  DeInitializes the CAN MSP.
486   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
487   *         the configuration information for the specified CAN.  
488   * @retval None
489   */
490 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
491 {
492   /* NOTE : This function Should not be modified, when the callback is needed,
493             the HAL_CAN_MspDeInit can be implemented in the user file
494    */ 
495 }
496
497 /**
498   * @}
499   */
500
501 /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
502  *  @brief    I/O operation functions 
503  *
504 @verbatim   
505   ==============================================================================
506                       ##### IO operation functions #####
507   ==============================================================================
508     [..]  This section provides functions allowing to:
509       (+) Transmit a CAN frame message.
510       (+) Receive a CAN frame message.
511       (+) Enter CAN peripheral in sleep mode. 
512       (+) Wake up the CAN peripheral from sleep mode.
513                
514 @endverbatim
515   * @{
516   */
517
518 /**
519   * @brief  Initiates and transmits a CAN frame message.
520   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
521   *         the configuration information for the specified CAN.  
522   * @param  Timeout: Specify Timeout value   
523   * @retval HAL status
524   */
525 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
526 {
527   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
528   uint32_t tickstart = 0;
529
530   /* Check the parameters */
531   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
532   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
533   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
534   
535   /* Process locked */
536   __HAL_LOCK(hcan);
537   
538   if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
539   {
540     /* Change CAN state */
541     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
542   }
543   else
544   {
545     /* Change CAN state */
546     hcan->State = HAL_CAN_STATE_BUSY_TX;
547   }
548   
549   /* Select one empty transmit mailbox */
550   if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
551   {
552     transmitmailbox = 0;
553   }
554   else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
555   {
556     transmitmailbox = 1;
557   }
558   else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
559   {
560     transmitmailbox = 2;
561   }
562   else
563   {
564     transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
565   }
566
567   if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
568   {
569     /* Set up the Id */
570     hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
571     if (hcan->pTxMsg->IDE == CAN_ID_STD)
572     {
573       assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
574       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
575                                                            hcan->pTxMsg->RTR);
576     }
577     else
578     {
579       assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
580       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
581                                                            hcan->pTxMsg->IDE |
582                                                            hcan->pTxMsg->RTR);
583     }
584     
585     /* Set up the DLC */
586     hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
587     hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
588     hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
589
590     /* Set up the data field */
591     WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) | 
592                                                                 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
593                                                                 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) | 
594                                                                 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
595     WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) | 
596                                                                 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
597                                                                 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
598                                                                 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
599     /* Request transmission */
600     SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
601   
602     /* Get timeout */
603     tickstart = HAL_GetTick();   
604   
605     /* Check End of transmission flag */
606     while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
607     {
608       /* Check for the Timeout */
609       if(Timeout != HAL_MAX_DELAY)
610       {
611         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
612         {
613           hcan->State = HAL_CAN_STATE_TIMEOUT;
614           
615           /* Process unlocked */
616           __HAL_UNLOCK(hcan);
617           
618           return HAL_TIMEOUT;
619         }
620       }
621     }
622     if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
623     {
624       /* Change CAN state */
625       hcan->State = HAL_CAN_STATE_BUSY_RX;
626       
627       /* Process unlocked */
628       __HAL_UNLOCK(hcan);
629     }
630     else
631     {
632       /* Change CAN state */
633       hcan->State = HAL_CAN_STATE_READY;
634     }
635     
636     /* Process unlocked */
637     __HAL_UNLOCK(hcan);
638     
639     /* Return function status */
640     return HAL_OK;
641   }
642   else
643   {
644     /* Change CAN state */
645     hcan->State = HAL_CAN_STATE_ERROR; 
646     
647     /* Process unlocked */
648     __HAL_UNLOCK(hcan);
649
650     /* Return function status */
651     return HAL_ERROR;
652   }
653 }
654
655 /**
656   * @brief  Initiates and transmits a CAN frame message.
657   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
658   *         the configuration information for the specified CAN.  
659   * @retval HAL status
660   */
661 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
662 {
663   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
664
665   /* Check the parameters */
666   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
667   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
668   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
669   
670   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
671   {
672     /* Process Locked */
673     __HAL_LOCK(hcan);
674     
675     /* Select one empty transmit mailbox */
676     if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
677     {
678       transmitmailbox = 0;
679     }
680     else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
681     {
682       transmitmailbox = 1;
683     }
684     else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
685     {
686       transmitmailbox = 2;
687     }
688     else
689     {
690       transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
691     }
692
693     if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
694     {
695       /* Set up the Id */
696       hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
697       if (hcan->pTxMsg->IDE == CAN_ID_STD)
698       {
699         assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
700         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
701                                                              hcan->pTxMsg->RTR);
702       }
703       else
704       {
705         assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
706         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
707                                                              hcan->pTxMsg->IDE |
708                                                              hcan->pTxMsg->RTR);
709       }
710     
711       /* Set up the DLC */
712       hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
713       hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
714       hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
715       
716       /* Set up the data field */
717       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) | 
718                                                                   ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
719                                                                   ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) | 
720                                                                   ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
721       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) | 
722                                                                   ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
723                                                                   ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
724                                                                   ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
725     
726       if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
727       {
728         /* Change CAN state */
729         hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
730       }
731       else
732       {
733         /* Change CAN state */
734         hcan->State = HAL_CAN_STATE_BUSY_TX;
735       }
736       
737       /* Set CAN error code to none */
738       hcan->ErrorCode = HAL_CAN_ERROR_NONE;
739       
740       /* Process Unlocked */
741       __HAL_UNLOCK(hcan);
742       
743       /* Enable interrupts: */
744       /*  - Enable Error warning Interrupt */
745       /*  - Enable Error passive Interrupt */
746       /*  - Enable Bus-off Interrupt */
747       /*  - Enable Last error code Interrupt */
748       /*  - Enable Error Interrupt */
749       /*  - Enable Transmit mailbox empty Interrupt */
750       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
751                                 CAN_IT_EPV |
752                                 CAN_IT_BOF |
753                                 CAN_IT_LEC |
754                                 CAN_IT_ERR |
755                                 CAN_IT_TME  );
756       
757       /* Request transmission */
758       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
759     }
760   }
761   else
762   {
763     return HAL_BUSY;
764   }
765   
766   return HAL_OK;
767 }
768
769 /**
770   * @brief  Receives a correct CAN frame.
771   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
772   *         the configuration information for the specified CAN.  
773   * @param  FIFONumber: FIFO Number value
774   * @param  Timeout: Specify Timeout value 
775   * @retval HAL status
776   * @retval None
777   */
778 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
779 {
780   uint32_t tickstart = 0;
781    
782   /* Check the parameters */
783   assert_param(IS_CAN_FIFO(FIFONumber));
784   
785   /* Process locked */
786   __HAL_LOCK(hcan);
787   
788   if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
789   {
790     /* Change CAN state */
791     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
792   }
793   else
794   {
795     /* Change CAN state */
796     hcan->State = HAL_CAN_STATE_BUSY_RX;
797   }
798     
799   /* Get tick */ 
800   tickstart = HAL_GetTick();
801   
802   /* Check pending message */
803   while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
804   {
805     /* Check for the Timeout */
806     if(Timeout != HAL_MAX_DELAY)
807     {
808       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
809       {
810         hcan->State = HAL_CAN_STATE_TIMEOUT;
811         
812         /* Process unlocked */
813         __HAL_UNLOCK(hcan);
814         
815         return HAL_TIMEOUT;
816       }
817     }
818   }
819   
820   /* Get the Id */
821   hcan->pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
822   if (hcan->pRxMsg->IDE == CAN_ID_STD)
823   {
824     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
825   }
826   else
827   {
828     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
829   }
830   
831   hcan->pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
832   /* Get the DLC */
833   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
834   /* Get the FMI */
835   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
836   /* Get the data field */
837   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
838   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
839   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
840   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
841   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
842   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
843   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
844   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
845   
846   /* Release the FIFO */
847   if(FIFONumber == CAN_FIFO0)
848   {
849     /* Release FIFO0 */
850     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
851   }
852   else /* FIFONumber == CAN_FIFO1 */
853   {
854     /* Release FIFO1 */
855     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
856   }
857   
858   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
859   {
860     /* Change CAN state */
861     hcan->State = HAL_CAN_STATE_BUSY_TX;
862   }
863   else
864   {
865     /* Change CAN state */
866     hcan->State = HAL_CAN_STATE_READY;
867   }
868   
869   /* Process unlocked */
870   __HAL_UNLOCK(hcan);
871
872   /* Return function status */
873   return HAL_OK;
874 }
875
876 /**
877   * @brief  Receives a correct CAN frame.
878   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
879   *         the configuration information for the specified CAN.  
880   * @param  FIFONumber: Specify the FIFO number    
881   * @retval HAL status
882   * @retval None
883   */
884 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
885 {
886   /* Check the parameters */
887   assert_param(IS_CAN_FIFO(FIFONumber));
888   
889   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
890   {
891     /* Process locked */
892     __HAL_LOCK(hcan);
893   
894     if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
895     {
896       /* Change CAN state */
897       hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
898     }
899     else
900     {
901       /* Change CAN state */
902       hcan->State = HAL_CAN_STATE_BUSY_RX;
903     }
904     
905     /* Set CAN error code to none */
906     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
907     
908     /* Enable interrupts: */
909     /*  - Enable Error warning Interrupt */
910     /*  - Enable Error passive Interrupt */
911     /*  - Enable Bus-off Interrupt */
912     /*  - Enable Last error code Interrupt */
913     /*  - Enable Error Interrupt */
914     /*  - Enable Transmit mailbox empty Interrupt */
915     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
916                               CAN_IT_EPV |
917                               CAN_IT_BOF |
918                               CAN_IT_LEC |
919                               CAN_IT_ERR |
920                               CAN_IT_TME  );
921
922     /* Process unlocked */
923     __HAL_UNLOCK(hcan);
924
925     if(FIFONumber == CAN_FIFO0)
926     {
927       /* Enable FIFO 0 message pending Interrupt */
928       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
929     }
930     else
931     {
932       /* Enable FIFO 1 message pending Interrupt */
933       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
934     }
935     
936   }
937   else
938   {
939     return HAL_BUSY;
940   }
941   
942   /* Return function status */
943   return HAL_OK;
944 }
945
946 /**
947   * @brief  Enters the Sleep (low power) mode.
948   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
949   *         the configuration information for the specified CAN.
950   * @retval HAL status.
951   */
952 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
953 {
954   uint32_t tickstart = 0;
955    
956   /* Process locked */
957   __HAL_LOCK(hcan);
958   
959   /* Change CAN state */
960   hcan->State = HAL_CAN_STATE_BUSY; 
961     
962   /* Request Sleep mode */
963   MODIFY_REG(hcan->Instance->MCR,
964              CAN_MCR_INRQ       ,
965              CAN_MCR_SLEEP       );
966      
967   /* Sleep mode status */
968   if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
969       HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
970   {
971     /* Process unlocked */
972     __HAL_UNLOCK(hcan);
973
974     /* Return function status */
975     return HAL_ERROR;
976   }
977   
978   /* Get tick */ 
979   tickstart = HAL_GetTick();
980   
981   /* Wait the acknowledge */
982   while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
983          HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
984   {
985     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
986     {
987       hcan->State = HAL_CAN_STATE_TIMEOUT;
988       
989       /* Process unlocked */
990       __HAL_UNLOCK(hcan);
991       
992       return HAL_TIMEOUT;
993     }
994   }
995   
996   /* Change CAN state */
997   hcan->State = HAL_CAN_STATE_READY;
998   
999   /* Process unlocked */
1000   __HAL_UNLOCK(hcan);
1001   
1002   /* Return function status */
1003   return HAL_OK;
1004 }
1005
1006 /**
1007   * @brief  Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1008   *         is in the normal mode.
1009   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1010   *         the configuration information for the specified CAN.
1011   * @retval HAL status.
1012   */
1013 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1014 {
1015   uint32_t tickstart = 0;
1016     
1017   /* Process locked */
1018   __HAL_LOCK(hcan);
1019   
1020   /* Change CAN state */
1021   hcan->State = HAL_CAN_STATE_BUSY;  
1022  
1023   /* Wake up request */
1024   CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1025     
1026   /* Get timeout */
1027   tickstart = HAL_GetTick();   
1028   
1029   /* Sleep mode status */
1030   while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1031   {
1032     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
1033     {
1034       hcan->State= HAL_CAN_STATE_TIMEOUT;
1035       
1036       /* Process unlocked */
1037       __HAL_UNLOCK(hcan);
1038       
1039       return HAL_TIMEOUT;
1040     }
1041   }
1042   if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1043   {
1044     /* Process unlocked */
1045     __HAL_UNLOCK(hcan);
1046
1047     /* Return function status */
1048     return HAL_ERROR;
1049   }
1050   
1051   /* Change CAN state */
1052   hcan->State = HAL_CAN_STATE_READY; 
1053   
1054   /* Process unlocked */
1055   __HAL_UNLOCK(hcan);
1056   
1057   /* Return function status */
1058   return HAL_OK;
1059 }
1060
1061 /**
1062   * @brief  Handles CAN interrupt request  
1063   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1064   *         the configuration information for the specified CAN.
1065   * @retval None
1066   */
1067 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1068 {
1069   /* Check End of transmission flag */
1070   if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1071   {
1072     if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
1073        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
1074        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
1075     {
1076       /* Call transmit function */
1077       CAN_Transmit_IT(hcan);
1078     }
1079   }
1080   
1081   /* Check End of reception flag for FIFO0 */
1082   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
1083      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
1084   {
1085     /* Call receive function */
1086     CAN_Receive_IT(hcan, CAN_FIFO0);
1087   }
1088   
1089   /* Check End of reception flag for FIFO1 */
1090   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
1091      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
1092   {
1093     /* Call receive function */
1094     CAN_Receive_IT(hcan, CAN_FIFO1);
1095   }
1096   
1097   /* Check Error Warning Flag */
1098   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG))    &&
1099      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
1100      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1101   {
1102     /* Set CAN error code to EWG error */
1103     hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1104     /* No need for clear of Error Warning Flag as read-only */
1105   }
1106   
1107   /* Check Error Passive Flag */
1108   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV))    &&
1109      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
1110      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1111   {
1112     /* Set CAN error code to EPV error */
1113     hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1114     /* No need for clear of Error Passive Flag as read-only */ 
1115   }
1116   
1117   /* Check Bus-Off Flag */
1118   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF))    &&
1119      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
1120      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1121   {
1122     /* Set CAN error code to BOF error */
1123     hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1124     /* No need for clear of Bus-Off Flag as read-only */
1125   }
1126   
1127   /* Check Last error code Flag */
1128   if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
1129      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC))         &&
1130      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1131   {
1132     switch(hcan->Instance->ESR & CAN_ESR_LEC)
1133     {
1134       case(CAN_ESR_LEC_0):
1135           /* Set CAN error code to STF error */
1136           hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1137           break;
1138       case(CAN_ESR_LEC_1):
1139           /* Set CAN error code to FOR error */
1140           hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1141           break;
1142       case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1143           /* Set CAN error code to ACK error */
1144           hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1145           break;
1146       case(CAN_ESR_LEC_2):
1147           /* Set CAN error code to BR error */
1148           hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1149           break;
1150       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1151           /* Set CAN error code to BD error */
1152           hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1153           break;
1154       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1155           /* Set CAN error code to CRC error */
1156           hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1157           break;
1158       default:
1159           break;
1160     }
1161
1162     /* Clear Last error code Flag */ 
1163     CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
1164   }
1165   
1166   /* Call the Error call Back in case of Errors */
1167   if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1168   {
1169     /* Set the CAN state ready to be able to start again the process */
1170     hcan->State = HAL_CAN_STATE_READY;
1171     
1172     /* Call Error callback function */
1173     HAL_CAN_ErrorCallback(hcan);
1174   }  
1175 }
1176
1177 /**
1178   * @brief  Transmission  complete callback in non blocking mode 
1179   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1180   *         the configuration information for the specified CAN.
1181   * @retval None
1182   */
1183 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1184 {
1185   /* NOTE : This function Should not be modified, when the callback is needed,
1186             the HAL_CAN_TxCpltCallback can be implemented in the user file
1187    */
1188 }
1189
1190 /**
1191   * @brief  Transmission  complete callback in non blocking mode 
1192   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1193   *         the configuration information for the specified CAN.
1194   * @retval None
1195   */
1196 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1197 {
1198   /* NOTE : This function Should not be modified, when the callback is needed,
1199             the HAL_CAN_RxCpltCallback can be implemented in the user file
1200    */
1201 }
1202
1203 /**
1204   * @brief  Error CAN callback.
1205   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1206   *         the configuration information for the specified CAN.
1207   * @retval None
1208   */
1209 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1210 {
1211   /* NOTE : This function Should not be modified, when the callback is needed,
1212             the HAL_CAN_ErrorCallback can be implemented in the user file
1213    */
1214 }
1215
1216 /**
1217   * @}
1218   */
1219
1220 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1221  *  @brief   CAN Peripheral State functions 
1222  *
1223 @verbatim   
1224   ==============================================================================
1225             ##### Peripheral State and Error functions #####
1226   ==============================================================================
1227     [..]
1228     This subsection provides functions allowing to :
1229       (+) Check the CAN state.
1230       (+) Check CAN Errors detected during interrupt process
1231          
1232 @endverbatim
1233   * @{
1234   */
1235
1236 /**
1237   * @brief  return the CAN state
1238   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1239   *         the configuration information for the specified CAN.
1240   * @retval HAL state
1241   */
1242 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1243 {
1244   /* Return CAN state */
1245   return hcan->State;
1246 }
1247
1248 /**
1249   * @brief  Return the CAN error code
1250   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1251   *         the configuration information for the specified CAN.
1252   * @retval CAN Error Code
1253   */
1254 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1255 {
1256   return hcan->ErrorCode;
1257 }
1258
1259 /**
1260   * @}
1261   */
1262
1263 /**
1264   * @}
1265   */
1266
1267 /** @defgroup CAN_Private_Functions CAN Private Functions
1268  * @{
1269  */
1270 /**
1271   * @brief  Initiates and transmits a CAN frame message.
1272   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1273   *         the configuration information for the specified CAN.  
1274   * @retval HAL status
1275   */
1276 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1277 {
1278   /* Disable Transmit mailbox empty Interrupt */
1279   __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1280   
1281   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1282   {   
1283     /* Disable interrupts: */
1284     /*  - Disable Error warning Interrupt */
1285     /*  - Disable Error passive Interrupt */
1286     /*  - Disable Bus-off Interrupt */
1287     /*  - Disable Last error code Interrupt */
1288     /*  - Disable Error Interrupt */
1289     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1290                                CAN_IT_EPV |
1291                                CAN_IT_BOF |
1292                                CAN_IT_LEC |
1293                                CAN_IT_ERR  );
1294   }
1295   
1296   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
1297   {
1298     /* Change CAN state */
1299     hcan->State = HAL_CAN_STATE_BUSY_RX;
1300   }
1301   else
1302   {
1303     /* Change CAN state */
1304     hcan->State = HAL_CAN_STATE_READY;
1305   }
1306   
1307   /* Transmission complete callback */ 
1308   HAL_CAN_TxCpltCallback(hcan);
1309   
1310   return HAL_OK;
1311 }
1312
1313 /**
1314   * @brief  Receives a correct CAN frame.
1315   * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
1316   *         the configuration information for the specified CAN.  
1317   * @param  FIFONumber: Specify the FIFO number    
1318   * @retval HAL status
1319   * @retval None
1320   */
1321 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1322 {
1323   /* Get the Id */
1324   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1325   if (hcan->pRxMsg->IDE == CAN_ID_STD)
1326   {
1327     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
1328   }
1329   else
1330   {
1331     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
1332   }
1333   
1334   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1335   /* Get the DLC */
1336   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1337   /* Get the FMI */
1338   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
1339   /* Get the data field */
1340   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1341   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
1342   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
1343   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
1344   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1345   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
1346   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
1347   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
1348   /* Release the FIFO */
1349   /* Release FIFO0 */
1350   if (FIFONumber == CAN_FIFO0)
1351   {
1352     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1353     
1354     /* Disable FIFO 0 message pending Interrupt */
1355     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
1356   }
1357   /* Release FIFO1 */
1358   else /* FIFONumber == CAN_FIFO1 */
1359   {
1360     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1361     
1362     /* Disable FIFO 1 message pending Interrupt */
1363     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
1364   }
1365   
1366   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
1367   {
1368     /* Disable interrupts: */
1369     /*  - Disable Error warning Interrupt */
1370     /*  - Disable Error passive Interrupt */
1371     /*  - Disable Bus-off Interrupt */
1372     /*  - Disable Last error code Interrupt */
1373     /*  - Disable Error Interrupt */
1374     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1375                                CAN_IT_EPV |
1376                                CAN_IT_BOF |
1377                                CAN_IT_LEC |
1378                                CAN_IT_ERR  );
1379   }
1380   
1381   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
1382   {
1383     /* Disable CAN state */
1384     hcan->State = HAL_CAN_STATE_BUSY_TX;
1385   }
1386   else
1387   {
1388     /* Change CAN state */
1389     hcan->State = HAL_CAN_STATE_READY;
1390   }
1391
1392   /* Receive complete callback */ 
1393   HAL_CAN_RxCpltCallback(hcan);
1394
1395   /* Return function status */
1396   return HAL_OK;
1397 }
1398
1399 /**
1400  * @}
1401  */
1402
1403 /**
1404   * @}
1405   */
1406
1407 #endif /* STM32F103x6) || STM32F103xB || STM32F103xE || */
1408        /* STM32F103xG) || STM32F105xC || STM32F107xC    */
1409
1410 #endif /* HAL_CAN_MODULE_ENABLED */
1411
1412 /**
1413   * @}
1414   */
1415
1416 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/