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