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