]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_can.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_can.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_can.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    19-June-2014
7   * @brief   This file provides firmware functions to manage the following 
8   *          functionalities of the Controller Area Network (CAN) peripheral:
9   *           + Initialization and de-initialization functions 
10   *           + IO operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State and Error functions
13   *
14   @verbatim
15   ==============================================================================
16                         ##### How to use this driver #####
17   ==============================================================================
18     [..]            
19       (#) Enable the CAN controller interface clock using 
20           __CAN1_CLK_ENABLE() for CAN1 and __CAN1_CLK_ENABLE() for CAN2
21       -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
22        
23       (#) CAN pins configuration
24         (++) Enable the clock for the CAN GPIOs using the following function:
25              __GPIOx_CLK_ENABLE()   
26         (++) Connect and configure the involved CAN pins to AF9 using the 
27               following function HAL_GPIO_Init() 
28               
29       (#) Initialise and configure the CAN using CAN_Init() function.   
30                  
31       (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
32            
33       (#) Receive a CAN frame using HAL_CAN_Recieve() function.
34
35      *** Polling mode IO operation ***
36      =================================
37      [..]    
38        (+) Start the CAN peripheral transmission and wait the end of this operation 
39            using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
40            according to his end application
41        (+) Start the CAN peripheral reception and wait the end of this operation 
42            using HAL_CAN_Receive(), at this stage user can specify the value of timeout
43            according to his end application 
44        
45      *** Interrupt mode IO operation ***    
46      ===================================
47      [..]    
48        (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
49        (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()         
50        (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
51        (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can 
52             add his own code by customization of function pointer HAL_CAN_TxCpltCallback 
53        (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can 
54             add his own code by customization of function pointer HAL_CAN_ErrorCallback
55  
56      *** CAN HAL driver macros list ***
57      ============================================= 
58      [..]
59        Below the list of most used macros in CAN HAL driver.
60        
61       (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
62       (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
63       (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
64       (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
65       (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
66       
67      [..] 
68       (@) You can refer to the CAN HAL driver header file for more useful macros 
69                 
70   @endverbatim
71            
72   ******************************************************************************
73   * @attention
74   *
75   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
76   *
77   * Redistribution and use in source and binary forms, with or without modification,
78   * are permitted provided that the following conditions are met:
79   *   1. Redistributions of source code must retain the above copyright notice,
80   *      this list of conditions and the following disclaimer.
81   *   2. Redistributions in binary form must reproduce the above copyright notice,
82   *      this list of conditions and the following disclaimer in the documentation
83   *      and/or other materials provided with the distribution.
84   *   3. Neither the name of STMicroelectronics nor the names of its contributors
85   *      may be used to endorse or promote products derived from this software
86   *      without specific prior written permission.
87   *
88   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
92   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
94   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
95   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
96   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
97   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98   *
99   ******************************************************************************
100   */
101
102 /* Includes ------------------------------------------------------------------*/
103 #include "stm32f4xx_hal.h"
104
105 /** @addtogroup STM32F4xx_HAL_Driver
106   * @{
107   */
108
109 /** @defgroup CAN 
110   * @brief CAN driver modules
111   * @{
112   */ 
113   
114 #ifdef HAL_CAN_MODULE_ENABLED  
115
116 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
117   
118 /* Private typedef -----------------------------------------------------------*/
119 /* Private define ------------------------------------------------------------*/
120 #define CAN_TIMEOUT_VALUE  10
121 /* Private macro -------------------------------------------------------------*/
122 /* Private variables ---------------------------------------------------------*/
123 /* Private function prototypes -----------------------------------------------*/
124 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
125 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
126 /* Private functions ---------------------------------------------------------*/
127
128 /** @defgroup CAN_Private_Functions
129   * @{
130   */
131
132 /** @defgroup CAN_Group1 Initialization and de-initialization functions 
133  *  @brief    Initialization and Configuration functions 
134  *
135 @verbatim    
136   ==============================================================================
137               ##### Initialization and de-initialization functions #####
138   ==============================================================================
139     [..]  This section provides functions allowing to:
140       (+) Initialize and configure the CAN. 
141       (+) De-initialize the CAN. 
142          
143 @endverbatim
144   * @{
145   */
146   
147 /**
148   * @brief  Initializes the CAN peripheral according to the specified
149   *         parameters in the CAN_InitStruct.
150   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
151   *         the configuration information for the specified CAN.  
152   * @retval HAL status
153   */
154 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
155 {
156   uint32_t InitStatus = 3;
157   uint32_t tickstart = 0;
158   
159   /* Check CAN handle */
160   if(hcan == HAL_NULL)
161   {
162      return HAL_ERROR;
163   }
164   
165   /* Check the parameters */
166   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
167   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
168   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
169   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
170   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
171   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
172   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
173   assert_param(IS_CAN_MODE(hcan->Init.Mode));
174   assert_param(IS_CAN_SJW(hcan->Init.SJW));
175   assert_param(IS_CAN_BS1(hcan->Init.BS1));
176   assert_param(IS_CAN_BS2(hcan->Init.BS2));
177   assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
178   
179
180   if(hcan->State == HAL_CAN_STATE_RESET)
181   {    
182     /* Init the low level hardware */
183     HAL_CAN_MspInit(hcan);
184   }
185   
186   /* Initialize the CAN state*/
187   hcan->State = HAL_CAN_STATE_BUSY;
188   
189   /* Exit from sleep mode */
190   hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
191
192   /* Request initialisation */
193   hcan->Instance->MCR |= CAN_MCR_INRQ ;
194   
195   /* Get tick */
196   tickstart = HAL_GetTick();
197
198   /* Wait the acknowledge */
199   while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
200   {
201     if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
202     {
203       hcan->State= HAL_CAN_STATE_TIMEOUT;
204       /* Process unlocked */
205       __HAL_UNLOCK(hcan);
206       return HAL_TIMEOUT;
207     }
208   }
209
210   /* Check acknowledge */
211   if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
212   {
213     InitStatus = CAN_INITSTATUS_FAILED;
214   }
215   else 
216   {
217     /* Set the time triggered communication mode */
218     if (hcan->Init.TTCM == ENABLE)
219     {
220       hcan->Instance->MCR |= CAN_MCR_TTCM;
221     }
222     else
223     {
224       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
225     }
226
227     /* Set the automatic bus-off management */
228     if (hcan->Init.ABOM == ENABLE)
229     {
230       hcan->Instance->MCR |= CAN_MCR_ABOM;
231     }
232     else
233     {
234       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
235     }
236
237     /* Set the automatic wake-up mode */
238     if (hcan->Init.AWUM == ENABLE)
239     {
240       hcan->Instance->MCR |= CAN_MCR_AWUM;
241     }
242     else
243     {
244       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
245     }
246
247     /* Set the no automatic retransmission */
248     if (hcan->Init.NART == ENABLE)
249     {
250       hcan->Instance->MCR |= CAN_MCR_NART;
251     }
252     else
253     {
254       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
255     }
256
257     /* Set the receive FIFO locked mode */
258     if (hcan->Init.RFLM == ENABLE)
259     {
260       hcan->Instance->MCR |= CAN_MCR_RFLM;
261     }
262     else
263     {
264       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
265     }
266
267     /* Set the transmit FIFO priority */
268     if (hcan->Init.TXFP == ENABLE)
269     {
270       hcan->Instance->MCR |= CAN_MCR_TXFP;
271     }
272     else
273     {
274       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
275     }
276
277     /* Set the bit timing register */
278     hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
279                 ((uint32_t)hcan->Init.SJW) | \
280                 ((uint32_t)hcan->Init.BS1) | \
281                 ((uint32_t)hcan->Init.BS2) | \
282                ((uint32_t)hcan->Init.Prescaler - 1);
283
284     /* Request leave initialisation */
285     hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
286
287   /* Get tick */
288   tickstart = HAL_GetTick();
289
290    /* Wait the acknowledge */
291    while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
292    {
293     if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
294      {
295        hcan->State= HAL_CAN_STATE_TIMEOUT;
296        /* Process unlocked */
297        __HAL_UNLOCK(hcan);
298        return HAL_TIMEOUT;
299      }
300    }
301
302     /* Check acknowledged */
303     if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
304     {
305       InitStatus = CAN_INITSTATUS_FAILED;
306     }
307     else
308     {
309       InitStatus = CAN_INITSTATUS_SUCCESS;
310     }
311   }
312  
313   if(InitStatus == CAN_INITSTATUS_SUCCESS)
314   {
315     /* Set CAN error code to none */
316     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
317     
318     /* Initialize the CAN state */
319     hcan->State = HAL_CAN_STATE_READY;
320   
321     /* Return function status */
322     return HAL_OK;
323   }
324   else
325   {
326     /* Initialize the CAN state */
327     hcan->State = HAL_CAN_STATE_ERROR;
328     
329     /* Return function status */
330     return HAL_ERROR;
331   }
332 }
333
334 /**
335   * @brief  Configures the CAN reception filter according to the specified
336   *         parameters in the CAN_FilterInitStruct.
337   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
338   *         the configuration information for the specified CAN.
339   * @param  sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
340   *         contains the filter configuration information.
341   * @retval None
342   */
343 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
344 {
345   uint32_t filternbrbitpos = 0;
346   
347   /* Check the parameters */
348   assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
349   assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
350   assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
351   assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
352   assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
353   assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
354   
355   filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
356
357   /* Initialisation mode for the filter */
358   CAN1->FMR |= (uint32_t)CAN_FMR_FINIT;
359   
360   /* Select the start slave bank */
361   CAN1->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
362   CAN1->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8);
363      
364   /* Filter Deactivation */
365   CAN1->FA1R &= ~(uint32_t)filternbrbitpos;
366
367   /* Filter Scale */
368   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
369   {
370     /* 16-bit scale for the filter */
371     CAN1->FS1R &= ~(uint32_t)filternbrbitpos;
372
373     /* First 16-bit identifier and First 16-bit mask */
374     /* Or First 16-bit identifier and Second 16-bit identifier */
375     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
376        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
377         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
378
379     /* Second 16-bit identifier and Second 16-bit mask */
380     /* Or Third 16-bit identifier and Fourth 16-bit identifier */
381     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
382        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
383         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
384   }
385
386   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
387   {
388     /* 32-bit scale for the filter */
389     CAN1->FS1R |= filternbrbitpos;
390     /* 32-bit identifier or First 32-bit identifier */
391     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
392        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
393         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
394     /* 32-bit mask or Second 32-bit identifier */
395     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
396        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
397         (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
398   }
399
400   /* Filter Mode */
401   if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
402   {
403     /*Id/Mask mode for the filter*/
404     CAN1->FM1R &= ~(uint32_t)filternbrbitpos;
405   }
406   else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
407   {
408     /*Identifier list mode for the filter*/
409     CAN1->FM1R |= (uint32_t)filternbrbitpos;
410   }
411
412   /* Filter FIFO assignment */
413   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
414   {
415     /* FIFO 0 assignation for the filter */
416     CAN1->FFA1R &= ~(uint32_t)filternbrbitpos;
417   }
418
419   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
420   {
421     /* FIFO 1 assignation for the filter */
422     CAN1->FFA1R |= (uint32_t)filternbrbitpos;
423   }
424   
425   /* Filter activation */
426   if (sFilterConfig->FilterActivation == ENABLE)
427   {
428     CAN1->FA1R |= filternbrbitpos;
429   }
430
431   /* Leave the initialisation mode for the filter */
432   CAN1->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 == HAL_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 could 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 could be implemented in the user file
494    */ 
495 }
496
497 /**
498   * @}
499   */
500
501 /** @defgroup CAN_Group2 IO operation functions
502  *  @brief    IO 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 = 5;
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 ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
551   {
552     transmitmailbox = 0;
553   }
554   else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
555   {
556     transmitmailbox = 1;
557   }
558   else if ((hcan->Instance->TSR&CAN_TSR_TME2) == 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 << 21) | \
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 << 3) | \
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     hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | 
592                                              ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
593                                              ((uint32_t)hcan->pTxMsg->Data[1] << 8) | 
594                                              ((uint32_t)hcan->pTxMsg->Data[0]));
595     hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | 
596                                              ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
597                                              ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
598                                              ((uint32_t)hcan->pTxMsg->Data[4]));
599     /* Request transmission */
600     hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
601   
602   /* Get tick */ 
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          /* Process unlocked */
615          __HAL_UNLOCK(hcan);
616          return HAL_TIMEOUT;
617         }
618       }
619     }
620     if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
621     {
622       /* Change CAN state */
623       hcan->State = HAL_CAN_STATE_BUSY_RX;
624       
625       /* Process unlocked */
626       __HAL_UNLOCK(hcan);
627     }
628     else
629     {
630       /* Change CAN state */
631       hcan->State = HAL_CAN_STATE_READY;
632       
633       /* Process unlocked */
634       __HAL_UNLOCK(hcan);
635     }
636     
637     /* Return function status */
638     return HAL_OK;
639   }
640   else
641   {
642     /* Change CAN state */
643     hcan->State = HAL_CAN_STATE_ERROR; 
644     
645     /* Return function status */
646     return HAL_ERROR;
647   }
648 }
649
650 /**
651   * @brief  Initiates and transmits a CAN frame message.
652   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
653   *         the configuration information for the specified CAN.  
654   * @retval HAL status
655   */
656 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
657 {
658   uint32_t  transmitmailbox = 5;
659   uint32_t tmp = 0;
660   
661   /* Check the parameters */
662   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
663   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
664   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
665   
666   tmp = hcan->State;
667   if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_RX))
668   {
669     /* Process Locked */
670     __HAL_LOCK(hcan);
671     
672     /* Select one empty transmit mailbox */
673     if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
674     {
675       transmitmailbox = 0;
676     }
677     else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
678     {
679       transmitmailbox = 1;
680     }
681     else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
682     {
683       transmitmailbox = 2;
684     }
685     else
686     {
687       transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
688     }
689
690     if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
691     {
692       /* Set up the Id */
693       hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
694       if(hcan->pTxMsg->IDE == CAN_ID_STD)
695       {
696         assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
697         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
698                                                   hcan->pTxMsg->RTR);
699       }
700       else
701       {
702         assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
703         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
704                                                   hcan->pTxMsg->IDE | \
705                                                   hcan->pTxMsg->RTR);
706       }
707     
708       /* Set up the DLC */
709       hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
710       hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
711       hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
712
713       /* Set up the data field */
714       hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | 
715                                              ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
716                                              ((uint32_t)hcan->pTxMsg->Data[1] << 8) | 
717                                              ((uint32_t)hcan->pTxMsg->Data[0]));
718       hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | 
719                                              ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
720                                              ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
721                                              ((uint32_t)hcan->pTxMsg->Data[4]));
722     
723       if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
724       {
725         /* Change CAN state */
726         hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
727       }
728       else
729       {
730         /* Change CAN state */
731         hcan->State = HAL_CAN_STATE_BUSY_TX;
732       }
733       
734       /* Set CAN error code to none */
735       hcan->ErrorCode = HAL_CAN_ERROR_NONE;
736       
737       /* Process Unlocked */
738       __HAL_UNLOCK(hcan);
739       
740       /* Enable Error warning Interrupt */
741       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
742       
743       /* Enable Error passive Interrupt */
744       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
745       
746       /* Enable Bus-off Interrupt */
747       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
748       
749       /* Enable Last error code Interrupt */
750       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
751       
752       /* Enable Error Interrupt */
753       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
754       
755       /* Enable Transmit mailbox empty Interrupt */
756       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME);
757       
758       /* Request transmission */
759       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
760     }
761   }
762   else
763   {
764     return HAL_BUSY;
765   }
766   
767   return HAL_OK;
768 }
769
770 /**
771   * @brief  Receives a correct CAN frame.
772   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
773   *         the configuration information for the specified CAN.  
774   * @param  FIFONumber: FIFO Number value
775   * @param  Timeout: Specify Timeout value 
776   * @retval HAL status
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         /* Process unlocked */
812         __HAL_UNLOCK(hcan);
813         return HAL_TIMEOUT;
814       }
815     }
816   }
817   
818   /* Get the Id */
819   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
820   if (hcan->pRxMsg->IDE == CAN_ID_STD)
821   {
822     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
823   }
824   else
825   {
826     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
827   }
828   
829   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
830   /* Get the DLC */
831   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
832   /* Get the FMI */
833   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
834   /* Get the data field */
835   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
836   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
837   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
838   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
839   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
840   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
841   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
842   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
843   
844   /* Release the FIFO */
845   if(FIFONumber == CAN_FIFO0)
846   {
847     /* Release FIFO0 */
848     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
849   }
850   else /* FIFONumber == CAN_FIFO1 */
851   {
852     /* Release FIFO1 */
853     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
854   }
855   
856   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
857   {
858     /* Change CAN state */
859     hcan->State = HAL_CAN_STATE_BUSY_TX;
860     
861     /* Process unlocked */
862     __HAL_UNLOCK(hcan);
863   }
864   else
865   {
866     /* Change CAN state */
867     hcan->State = HAL_CAN_STATE_READY;
868     
869     /* Process unlocked */
870     __HAL_UNLOCK(hcan);
871   }
872   
873   /* Return function status */
874   return HAL_OK;
875 }
876
877 /**
878   * @brief  Receives a correct CAN frame.
879   * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
880   *         the configuration information for the specified CAN.  
881   * @param  FIFONumber: Specify the FIFO number    
882   * @retval HAL status
883   */
884 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
885 {
886   uint32_t tmp = 0;
887   
888   /* Check the parameters */
889   assert_param(IS_CAN_FIFO(FIFONumber));
890   
891   tmp = hcan->State;
892   if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_TX))
893   {
894     /* Process locked */
895     __HAL_LOCK(hcan);
896   
897     if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
898     {
899       /* Change CAN state */
900       hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
901     }
902     else
903     {
904       /* Change CAN state */
905       hcan->State = HAL_CAN_STATE_BUSY_RX;
906     }
907     
908     /* Set CAN error code to none */
909     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
910     
911     /* Enable Error warning Interrupt */
912     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
913       
914     /* Enable Error passive Interrupt */
915     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
916       
917     /* Enable Bus-off Interrupt */
918     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
919       
920     /* Enable Last error code Interrupt */
921     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
922       
923     /* Enable Error Interrupt */
924     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
925
926     /* Process unlocked */
927     __HAL_UNLOCK(hcan);
928
929     if(FIFONumber == CAN_FIFO0)
930     {
931       /* Enable FIFO 0 message pending Interrupt */
932       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
933     }
934     else
935     {
936       /* Enable FIFO 1 message pending Interrupt */
937       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
938     }
939     
940   }
941   else
942   {
943     return HAL_BUSY;
944   }
945   
946   /* Return function status */
947   return HAL_OK;
948 }
949
950 /**
951   * @brief  Enters the Sleep (low power) mode.
952   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
953   *         the configuration information for the specified CAN.
954   * @retval HAL status.
955   */
956 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
957 {
958   uint32_t tickstart = 0;
959    
960   /* Process locked */
961   __HAL_LOCK(hcan);
962   
963   /* Change CAN state */
964   hcan->State = HAL_CAN_STATE_BUSY; 
965     
966   /* Request Sleep mode */
967    hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
968    
969   /* Sleep mode status */
970   if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
971   {
972     /* Return function status */
973     return HAL_ERROR;
974   }
975   
976   /* Get tick */ 
977   tickstart = HAL_GetTick();
978   
979   /* Wait the acknowledge */
980   while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
981   {
982     if((HAL_GetTick()  - tickstart) > CAN_TIMEOUT_VALUE)
983     {
984       hcan->State = HAL_CAN_STATE_TIMEOUT;
985       /* Process unlocked */
986       __HAL_UNLOCK(hcan);
987       return HAL_TIMEOUT;
988     }
989   }
990   
991   /* Change CAN state */
992   hcan->State = HAL_CAN_STATE_READY;
993   
994   /* Process unlocked */
995   __HAL_UNLOCK(hcan);
996   
997   /* Return function status */
998   return HAL_OK;
999 }
1000
1001 /**
1002   * @brief  Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1003   *         is in the normal mode.
1004   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1005   *         the configuration information for the specified CAN.
1006   * @retval HAL status.
1007   */
1008 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1009 {
1010   uint32_t tickstart = 0;
1011     
1012   /* Process locked */
1013   __HAL_LOCK(hcan);
1014   
1015   /* Change CAN state */
1016   hcan->State = HAL_CAN_STATE_BUSY;  
1017  
1018   /* Wake up request */
1019   hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
1020
1021   /* Get tick */ 
1022   tickstart = HAL_GetTick();
1023
1024   /* Sleep mode status */
1025   while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1026   {
1027     if((HAL_GetTick()  - tickstart) > CAN_TIMEOUT_VALUE)
1028     {
1029       hcan->State= HAL_CAN_STATE_TIMEOUT;
1030       /* Process unlocked */
1031       __HAL_UNLOCK(hcan);
1032       return HAL_TIMEOUT;
1033     }
1034   }
1035   if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1036   {
1037     /* Return function status */
1038     return HAL_ERROR;
1039   }
1040   
1041   /* Change CAN state */
1042   hcan->State = HAL_CAN_STATE_READY; 
1043   
1044   /* Process unlocked */
1045   __HAL_UNLOCK(hcan);
1046   
1047   /* Return function status */
1048   return HAL_OK;
1049 }
1050
1051 /**
1052   * @brief  Handles CAN interrupt request  
1053   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1054   *         the configuration information for the specified CAN.
1055   * @retval None
1056   */
1057 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1058 {
1059   uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;
1060   
1061   /* Check End of transmission flag */
1062   if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1063   {
1064     tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
1065     tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
1066     tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
1067     if(tmp1 || tmp2 || tmp3)  
1068     {
1069       /* Call transmit function */
1070       CAN_Transmit_IT(hcan);
1071     }
1072   }
1073   
1074   tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
1075   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
1076   /* Check End of reception flag for FIFO0 */
1077   if((tmp1 != 0) && tmp2)
1078   {
1079     /* Call receive function */
1080     CAN_Receive_IT(hcan, CAN_FIFO0);
1081   }
1082   
1083   tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
1084   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
1085   /* Check End of reception flag for FIFO1 */
1086   if((tmp1 != 0) && tmp2)
1087   {
1088     /* Call receive function */
1089     CAN_Receive_IT(hcan, CAN_FIFO1);
1090   }
1091   
1092   tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
1093   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
1094   tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1095   /* Check Error Warning Flag */
1096   if(tmp1 && tmp2 && tmp3)
1097   {
1098     /* Set CAN error code to EWG error */
1099     hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1100     /* Clear Error Warning Flag */ 
1101     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EWG);
1102   }
1103   
1104   tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
1105   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
1106   tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR); 
1107   /* Check Error Passive Flag */
1108   if(tmp1 && tmp2 && tmp3)
1109   {
1110     /* Set CAN error code to EPV error */
1111     hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1112     /* Clear Error Passive Flag */ 
1113     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EPV);
1114   }
1115   
1116   tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
1117   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
1118   tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);  
1119   /* Check Bus-Off Flag */
1120   if(tmp1 && tmp2 && tmp3)
1121   {
1122     /* Set CAN error code to BOF error */
1123     hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1124     /* Clear Bus-Off Flag */ 
1125     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_BOF);
1126   }
1127   
1128   tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
1129   tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
1130   tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1131   /* Check Last error code Flag */
1132   if((!tmp1) && tmp2 && tmp3)
1133   {
1134     tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
1135     switch(tmp1)
1136     {
1137       case(CAN_ESR_LEC_0):
1138           /* Set CAN error code to STF error */
1139           hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1140           break;
1141       case(CAN_ESR_LEC_1):
1142           /* Set CAN error code to FOR error */
1143           hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1144           break;
1145       case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1146           /* Set CAN error code to ACK error */
1147           hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1148           break;
1149       case(CAN_ESR_LEC_2):
1150           /* Set CAN error code to BR error */
1151           hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1152           break;
1153       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1154           /* Set CAN error code to BD error */
1155           hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1156           break;
1157       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1158           /* Set CAN error code to CRC error */
1159           hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1160           break;
1161       default:
1162           break;
1163     }
1164
1165     /* Clear Last error code Flag */ 
1166     hcan->Instance->ESR &= ~(CAN_ESR_LEC);
1167   }
1168   
1169   /* Call the Error call Back in case of Errors */
1170   if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1171   {
1172     /* Set the CAN state ready to be able to start again the process */
1173     hcan->State = HAL_CAN_STATE_READY;
1174     /* Call Error callback function */
1175     HAL_CAN_ErrorCallback(hcan);
1176   }  
1177 }
1178
1179 /**
1180   * @brief  Transmission  complete callback in non blocking mode 
1181   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1182   *         the configuration information for the specified CAN.
1183   * @retval None
1184   */
1185 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1186 {
1187   /* NOTE : This function Should not be modified, when the callback is needed,
1188             the HAL_CAN_TxCpltCallback could be implemented in the user file
1189    */
1190 }
1191
1192 /**
1193   * @brief  Transmission  complete callback in non blocking mode 
1194   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1195   *         the configuration information for the specified CAN.
1196   * @retval None
1197   */
1198 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1199 {
1200   /* NOTE : This function Should not be modified, when the callback is needed,
1201             the HAL_CAN_RxCpltCallback could be implemented in the user file
1202    */
1203 }
1204
1205 /**
1206   * @brief  Error CAN callback.
1207   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1208   *         the configuration information for the specified CAN.
1209   * @retval None
1210   */
1211 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1212 {
1213   /* NOTE : This function Should not be modified, when the callback is needed,
1214             the HAL_CAN_ErrorCallback could be implemented in the user file
1215    */
1216 }
1217
1218 /**
1219   * @}
1220   */
1221
1222 /** @defgroup CAN_Group3 Peripheral State and Error functions
1223  *  @brief   CAN Peripheral State functions 
1224  *
1225 @verbatim   
1226   ==============================================================================
1227             ##### Peripheral State and Error functions #####
1228   ==============================================================================
1229     [..]
1230     This subsection provides functions allowing to :
1231       (+) Check the CAN state.
1232       (+) Check CAN Errors detected during interrupt process
1233          
1234 @endverbatim
1235   * @{
1236   */
1237
1238 /**
1239   * @brief  return the CAN state
1240   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1241   *         the configuration information for the specified CAN.
1242   * @retval HAL state
1243   */
1244 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1245 {
1246   /* Return CAN state */
1247   return hcan->State;
1248 }
1249
1250 /**
1251   * @brief  Return the CAN error code
1252   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1253   *         the configuration information for the specified CAN.
1254   * @retval CAN Error Code
1255   */
1256 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1257 {
1258   return hcan->ErrorCode;
1259 }
1260
1261 /**
1262   * @}
1263   */
1264 /**
1265   * @brief  Initiates and transmits a CAN frame message.
1266   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1267   *         the configuration information for the specified CAN.  
1268   * @retval HAL status
1269   */
1270 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1271 {
1272   /* Disable Transmit mailbox empty Interrupt */
1273   __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1274   
1275   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1276   {   
1277     /* Disable Error warning Interrupt */
1278     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
1279     
1280     /* Disable Error passive Interrupt */
1281     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
1282     
1283     /* Disable Bus-off Interrupt */
1284     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
1285     
1286     /* Disable Last error code Interrupt */
1287     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
1288     
1289     /* Disable Error Interrupt */
1290     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
1291   }
1292   
1293   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
1294   {
1295     /* Change CAN state */
1296     hcan->State = HAL_CAN_STATE_BUSY_RX;
1297   }
1298   else
1299   {
1300     /* Change CAN state */
1301     hcan->State = HAL_CAN_STATE_READY;
1302   }
1303   
1304   /* Transmission complete callback */ 
1305   HAL_CAN_TxCpltCallback(hcan);
1306   
1307   return HAL_OK;
1308 }
1309
1310 /**
1311   * @brief  Receives a correct CAN frame.
1312   * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
1313   *         the configuration information for the specified CAN.  
1314   * @param  FIFONumber: Specify the FIFO number    
1315   * @retval HAL status
1316   * @retval None
1317   */
1318 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1319 {
1320   /* Get the Id */
1321   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1322   if (hcan->pRxMsg->IDE == CAN_ID_STD)
1323   {
1324     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
1325   }
1326   else
1327   {
1328     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
1329   }
1330   
1331   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1332   /* Get the DLC */
1333   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1334   /* Get the FMI */
1335   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
1336   /* Get the data field */
1337   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1338   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
1339   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
1340   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
1341   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1342   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
1343   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
1344   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
1345   /* Release the FIFO */
1346   /* Release FIFO0 */
1347   if (FIFONumber == CAN_FIFO0)
1348   {
1349     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1350     
1351     /* Disable FIFO 0 message pending Interrupt */
1352     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
1353   }
1354   /* Release FIFO1 */
1355   else /* FIFONumber == CAN_FIFO1 */
1356   {
1357     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1358     
1359     /* Disable FIFO 1 message pending Interrupt */
1360     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
1361   }
1362   
1363   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
1364   {   
1365     /* Disable Error warning Interrupt */
1366     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
1367     
1368     /* Disable Error passive Interrupt */
1369     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
1370     
1371     /* Disable Bus-off Interrupt */
1372     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
1373     
1374     /* Disable Last error code Interrupt */
1375     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
1376     
1377     /* Disable Error Interrupt */
1378     __HAL_CAN_DISABLE_IT(hcan, 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 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
1403
1404 #endif /* HAL_CAN_MODULE_ENABLED */
1405 /**
1406   * @}
1407   */
1408
1409 /**
1410   * @}
1411   */
1412
1413 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/