TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_can.c Source File

stm32l4xx_hal_can.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_can.c
00004   * @author  MCD Application Team
00005   * @version V1.5.1
00006   * @date    31-May-2016
00007   * @brief   CAN HAL module driver.
00008   *          This file provides firmware functions to manage the following 
00009   *          functionalities of the Controller Area Network (CAN) peripheral:           
00010   *           + Initialization and de-initialization functions 
00011   *           + IO operation functions
00012   *           + Peripheral Control functions
00013   *           + Peripheral State and Error functions
00014   *
00015   @verbatim
00016   ==============================================================================    
00017                         ##### How to use this driver #####
00018   ==============================================================================
00019     [..]            
00020       (#) Enable the CAN controller interface clock using 
00021           __HAL_RCC_CAN1_CLK_ENABLE() for CAN1.
00022        
00023       (#) CAN pins configuration
00024         (++) Enable the clock for the CAN GPIOs using the following function:
00025              __HAL_RCC_GPIOx_CLK_ENABLE();   
00026         (++) Connect and configure the involved CAN pins using the 
00027               following function HAL_GPIO_Init(); 
00028               
00029       (#) Initialize and configure the CAN using HAL_CAN_Init() function.   
00030                  
00031       (#) Transmit the desired CAN frame using HAL_CAN_Transmit() or 
00032           HAL_CAN_Transmit_IT() function.
00033            
00034       (#) Receive a CAN frame using HAL_CAN_Receive() or HAL_CAN_Receive_IT() function.
00035 
00036      *** Polling mode IO operation ***
00037      =================================
00038      [..]    
00039        (+) Start the CAN peripheral transmission and wait the end of this operation 
00040            using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
00041            according to his end application
00042        (+) Start the CAN peripheral reception and wait the end of this operation 
00043            using HAL_CAN_Receive(), at this stage user can specify the value of timeout
00044            according to his end application 
00045        
00046      *** Interrupt mode IO operation ***    
00047      ===================================
00048      [..]    
00049        (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
00050        (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()         
00051        (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
00052        (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can 
00053             add his own code by customization of function pointer HAL_CAN_TxCpltCallback 
00054        (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can 
00055             add his own code by customization of function pointer HAL_CAN_ErrorCallback
00056  
00057      *** CAN HAL driver macros list ***
00058      ============================================= 
00059      [..]
00060        Below the list of most used macros in CAN HAL driver.
00061        
00062       (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
00063       (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
00064       (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
00065       (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
00066       (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
00067       
00068      [..] 
00069       (@) You can refer to the CAN HAL driver header file for more useful macros 
00070                 
00071   @endverbatim
00072            
00073   ******************************************************************************
00074   * @attention
00075   *
00076   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00077   *
00078   * Redistribution and use in source and binary forms, with or without modification,
00079   * are permitted provided that the following conditions are met:
00080   *   1. Redistributions of source code must retain the above copyright notice,
00081   *      this list of conditions and the following disclaimer.
00082   *   2. Redistributions in binary form must reproduce the above copyright notice,
00083   *      this list of conditions and the following disclaimer in the documentation
00084   *      and/or other materials provided with the distribution.
00085   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00086   *      may be used to endorse or promote products derived from this software
00087   *      without specific prior written permission.
00088   *
00089   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00090   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00091   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00092   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00093   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00094   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00095   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00096   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00097   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00098   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00099   *
00100   ******************************************************************************
00101   */
00102 
00103 /* Includes ------------------------------------------------------------------*/
00104 #include "stm32l4xx_hal.h"
00105 
00106 /** @addtogroup STM32L4xx_HAL_Driver
00107   * @{
00108   */
00109 
00110 /** @defgroup CAN CAN
00111   * @brief CAN driver modules
00112   * @{
00113   */ 
00114   
00115 #ifdef HAL_CAN_MODULE_ENABLED  
00116   
00117 /* Private typedef -----------------------------------------------------------*/
00118 /* Private define ------------------------------------------------------------*/
00119 /** @defgroup CAN_Private_Constants CAN Private Constants
00120   * @{
00121   */
00122 #define CAN_TIMEOUT_VALUE  10
00123 /**
00124   * @}
00125   */
00126 /* Private macro -------------------------------------------------------------*/
00127 /* Private variables ---------------------------------------------------------*/
00128 /* Private function prototypes -----------------------------------------------*/
00129 /** @defgroup CAN_Private_Functions CAN Private Functions
00130  * @{
00131  */
00132 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
00133 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
00134 /**
00135   * @}
00136   */
00137 
00138 /* Exported functions --------------------------------------------------------*/
00139 
00140 /** @defgroup CAN_Exported_Functions CAN Exported Functions
00141   * @{
00142   */
00143 
00144 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions 
00145  *  @brief    Initialization and Configuration functions 
00146  *
00147 @verbatim    
00148   ==============================================================================
00149               ##### Initialization and de-initialization functions #####
00150   ==============================================================================
00151     [..]  This section provides functions allowing to:
00152       (+) Initialize and configure the CAN. 
00153       (+) De-initialize the CAN. 
00154          
00155 @endverbatim
00156   * @{
00157   */
00158   
00159 /**
00160   * @brief  Initialize the CAN peripheral according to the specified parameters 
00161   *         in the CAN_InitStruct structure and initialize the associated handle.
00162   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00163   *         the configuration information for the specified CAN.  
00164   * @retval HAL status
00165   */
00166 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
00167 {
00168   uint32_t status = CAN_INITSTATUS_FAILED;  /* Default init status */
00169   uint32_t tickstart = 0;
00170   
00171   /* Check CAN handle */
00172   if(hcan == NULL)
00173   {
00174      return HAL_ERROR;
00175   }
00176 
00177   /* Check the parameters */
00178   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
00179   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
00180   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
00181   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
00182   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
00183   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
00184   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
00185   assert_param(IS_CAN_MODE(hcan->Init.Mode));
00186   assert_param(IS_CAN_SJW(hcan->Init.SJW));
00187   assert_param(IS_CAN_BS1(hcan->Init.BS1));
00188   assert_param(IS_CAN_BS2(hcan->Init.BS2));
00189   assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
00190   
00191   if(hcan->State == HAL_CAN_STATE_RESET)
00192   {
00193     /* Allocate lock resource and initialize it */
00194     hcan->Lock = HAL_UNLOCKED;
00195 
00196     /* Init the low level hardware */
00197     HAL_CAN_MspInit(hcan);
00198   }
00199   
00200   /* Initialize the CAN state*/
00201   hcan->State = HAL_CAN_STATE_BUSY;
00202   
00203   /* Exit from sleep mode */
00204   hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
00205 
00206   /* Request initialisation */
00207   hcan->Instance->MCR |= CAN_MCR_INRQ ;
00208 
00209   /* Get tick */
00210   tickstart = HAL_GetTick();
00211 
00212   /* Wait the acknowledge */
00213   while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
00214   {
00215     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
00216     {
00217       hcan->State= HAL_CAN_STATE_TIMEOUT;
00218       /* Process unlocked */
00219       __HAL_UNLOCK(hcan);
00220       return HAL_TIMEOUT;
00221     }
00222   }
00223 
00224   /* Check acknowledge */
00225   if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
00226   {
00227     /* Set the time triggered communication mode */
00228     if (hcan->Init.TTCM == ENABLE)
00229     {
00230       hcan->Instance->MCR |= CAN_MCR_TTCM;
00231     }
00232     else
00233     {
00234       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
00235     }
00236 
00237     /* Set the automatic bus-off management */
00238     if (hcan->Init.ABOM == ENABLE)
00239     {
00240       hcan->Instance->MCR |= CAN_MCR_ABOM;
00241     }
00242     else
00243     {
00244       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
00245     }
00246 
00247     /* Set the automatic wake-up mode */
00248     if (hcan->Init.AWUM == ENABLE)
00249     {
00250       hcan->Instance->MCR |= CAN_MCR_AWUM;
00251     }
00252     else
00253     {
00254       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
00255     }
00256 
00257     /* Set the no automatic retransmission */
00258     if (hcan->Init.NART == ENABLE)
00259     {
00260       hcan->Instance->MCR |= CAN_MCR_NART;
00261     }
00262     else
00263     {
00264       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
00265     }
00266 
00267     /* Set the receive FIFO locked mode */
00268     if (hcan->Init.RFLM == ENABLE)
00269     {
00270       hcan->Instance->MCR |= CAN_MCR_RFLM;
00271     }
00272     else
00273     {
00274       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
00275     }
00276 
00277     /* Set the transmit FIFO priority */
00278     if (hcan->Init.TXFP == ENABLE)
00279     {
00280       hcan->Instance->MCR |= CAN_MCR_TXFP;
00281     }
00282     else
00283     {
00284       hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
00285     }
00286 
00287     /* Set the bit timing register */
00288     hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
00289                 ((uint32_t)hcan->Init.SJW) | \
00290                 ((uint32_t)hcan->Init.BS1) | \
00291                 ((uint32_t)hcan->Init.BS2) | \
00292                ((uint32_t)hcan->Init.Prescaler - 1);
00293 
00294     /* Request leave initialisation */
00295     hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
00296 
00297     /* Get tick */
00298     tickstart = HAL_GetTick();
00299    
00300     /* Wait the acknowledge */
00301     while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
00302     {
00303       if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
00304       {
00305          hcan->State= HAL_CAN_STATE_TIMEOUT;
00306          /* Process unlocked */
00307          __HAL_UNLOCK(hcan);
00308          return HAL_TIMEOUT;
00309       }
00310     }
00311 
00312     /* Check acknowledged */
00313     if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
00314     {
00315       status = CAN_INITSTATUS_SUCCESS;
00316     }
00317   }
00318  
00319   if(status == CAN_INITSTATUS_SUCCESS)
00320   {
00321     /* Set CAN error code to none */
00322     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
00323     
00324     /* Initialize the CAN state */
00325     hcan->State = HAL_CAN_STATE_READY;
00326   
00327     /* Return function status */
00328     return HAL_OK;
00329   }
00330   else
00331   {
00332     /* Initialize the CAN state */
00333     hcan->State = HAL_CAN_STATE_ERROR;
00334 
00335     /* Return function status */
00336     return HAL_ERROR;
00337   }
00338 }
00339 
00340 /**
00341   * @brief  Configure the CAN reception filter according to the specified
00342   *         parameters in the CAN_FilterInitStruct.
00343   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00344   *         the configuration information for the specified CAN.
00345   * @param  sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
00346   *         contains the filter configuration information.
00347   * @retval None
00348   */
00349 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
00350 {
00351   uint32_t filternbrbitpos = 0;
00352   
00353   /* Prevent unused argument(s) compilation warning */
00354   UNUSED(hcan);
00355 
00356   /* Check the parameters */
00357   assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
00358   assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
00359   assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
00360   assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
00361   assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
00362   assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
00363 
00364   filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
00365 
00366   /* Initialisation mode for the filter */
00367   CAN1->FMR |= (uint32_t)CAN_FMR_FINIT;
00368   
00369   /* Filter Deactivation */
00370   CAN1->FA1R &= ~(uint32_t)filternbrbitpos;
00371 
00372   /* Filter Scale */
00373   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
00374   {
00375     /* 16-bit scale for the filter */
00376     CAN1->FS1R &= ~(uint32_t)filternbrbitpos;
00377 
00378     /* First 16-bit identifier and First 16-bit mask */
00379     /* Or First 16-bit identifier and Second 16-bit identifier */
00380     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
00381        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
00382         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
00383 
00384     /* Second 16-bit identifier and Second 16-bit mask */
00385     /* Or Third 16-bit identifier and Fourth 16-bit identifier */
00386     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
00387        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
00388         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
00389   }
00390 
00391   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
00392   {
00393     /* 32-bit scale for the filter */
00394     CAN1->FS1R |= filternbrbitpos;
00395     /* 32-bit identifier or First 32-bit identifier */
00396     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
00397        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
00398         (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
00399     /* 32-bit mask or Second 32-bit identifier */
00400     CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = 
00401        ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
00402         (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
00403   }
00404 
00405   /* Filter Mode */
00406   if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
00407   {
00408     /*Id/Mask mode for the filter*/
00409     CAN1->FM1R &= ~(uint32_t)filternbrbitpos;
00410   }
00411   else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
00412   {
00413     /*Identifier list mode for the filter*/
00414     CAN1->FM1R |= (uint32_t)filternbrbitpos;
00415   }
00416 
00417   /* Filter FIFO assignment */
00418   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
00419   {
00420     /* FIFO 0 assignation for the filter */
00421     CAN1->FFA1R &= ~(uint32_t)filternbrbitpos;
00422   }
00423 
00424   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
00425   {
00426     /* FIFO 1 assignation for the filter */
00427     CAN1->FFA1R |= (uint32_t)filternbrbitpos;
00428   }
00429   
00430   /* Filter activation */
00431   if (sFilterConfig->FilterActivation == ENABLE)
00432   {
00433     CAN1->FA1R |= filternbrbitpos;
00434   }
00435 
00436   /* Leave the initialisation mode for the filter */
00437   CAN1->FMR &= ~((uint32_t)CAN_FMR_FINIT);
00438   
00439   /* Return function status */
00440   return HAL_OK;
00441 }
00442 
00443 /**
00444   * @brief  DeInitialize the CAN peripheral registers to their default reset values. 
00445   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00446   *         the configuration information for the specified CAN.  
00447   * @retval HAL status
00448   */
00449 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
00450 {
00451   /* Check CAN handle */
00452   if(hcan == NULL)
00453   {
00454      return HAL_ERROR;
00455   }
00456   
00457   /* Check the parameters */
00458   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
00459   
00460   /* Change CAN state */
00461   hcan->State = HAL_CAN_STATE_BUSY;
00462   
00463   /* DeInit the low level hardware */
00464   HAL_CAN_MspDeInit(hcan);
00465   
00466   /* Change CAN state */
00467   hcan->State = HAL_CAN_STATE_RESET;
00468 
00469   /* Release Lock */
00470   __HAL_UNLOCK(hcan);
00471 
00472   /* Return function status */
00473   return HAL_OK;
00474 }
00475 
00476 /**
00477   * @brief  Initialize the CAN MSP.
00478   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00479   *         the configuration information for the specified CAN.  
00480   * @retval None
00481   */
00482 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
00483 {
00484   /* Prevent unused argument(s) compilation warning */
00485   UNUSED(hcan);
00486 
00487   /* NOTE : This function should not be modified, when the callback is needed,
00488             the HAL_CAN_MspInit could be implemented in the user file
00489    */ 
00490 }
00491 
00492 /**
00493   * @brief  DeInitialize the CAN MSP.
00494   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00495   *         the configuration information for the specified CAN.  
00496   * @retval None
00497   */
00498 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
00499 {
00500   /* Prevent unused argument(s) compilation warning */
00501   UNUSED(hcan);
00502 
00503   /* NOTE : This function should not be modified, when the callback is needed,
00504             the HAL_CAN_MspDeInit could be implemented in the user file
00505    */ 
00506 }
00507 
00508 /**
00509   * @}
00510   */
00511 
00512 /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
00513  *  @brief    I/O operation functions 
00514  *
00515 @verbatim   
00516   ==============================================================================
00517                       ##### IO operation functions #####
00518   ==============================================================================
00519     [..]  This section provides functions allowing to:
00520       (+) Transmit a CAN frame message.
00521       (+) Receive a CAN frame message.
00522       (+) Enter CAN peripheral in sleep mode. 
00523       (+) Wake up the CAN peripheral from sleep mode.
00524                
00525 @endverbatim
00526   * @{
00527   */
00528 
00529 /**
00530   * @brief  Initiate and transmit a CAN frame message.
00531   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00532   *         the configuration information for the specified CAN.  
00533   * @param  Timeout: Timeout duration.
00534   * @retval HAL status
00535   */
00536 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
00537 {
00538   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
00539   uint32_t tickstart = 0;
00540 
00541   /* Check the parameters */
00542   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
00543   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
00544   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
00545   
00546   /* Process locked */
00547   __HAL_LOCK(hcan);
00548   
00549   if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
00550   {
00551     /* Change CAN state */
00552     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
00553   }
00554   else
00555   {
00556     /* Change CAN state */
00557     hcan->State = HAL_CAN_STATE_BUSY_TX;
00558   }
00559   
00560   /* Select one empty transmit mailbox */
00561   if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
00562   {
00563     transmitmailbox = 0;
00564   }
00565   else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
00566   {
00567     transmitmailbox = 1;
00568   }
00569   else if ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
00570   {
00571     transmitmailbox = 2;
00572   }
00573 
00574   if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
00575   {
00576     /* Set up the Id */
00577     hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
00578     if (hcan->pTxMsg->IDE == CAN_ID_STD)
00579     {
00580       assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
00581       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
00582                                                   hcan->pTxMsg->RTR);
00583     }
00584     else
00585     {
00586       assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
00587       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
00588                                                   hcan->pTxMsg->IDE | \
00589                                                   hcan->pTxMsg->RTR);
00590     }
00591     
00592     /* Set up the DLC */
00593     hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
00594     hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
00595     hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
00596 
00597     /* Set up the data field */
00598     hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | 
00599                                              ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
00600                                              ((uint32_t)hcan->pTxMsg->Data[1] << 8) | 
00601                                              ((uint32_t)hcan->pTxMsg->Data[0]));
00602     hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | 
00603                                              ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
00604                                              ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
00605                                              ((uint32_t)hcan->pTxMsg->Data[4]));
00606     /* Request transmission */
00607     hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
00608   
00609     /* Get tick */
00610     tickstart = HAL_GetTick();
00611   
00612     /* Check End of transmission flag */
00613     while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
00614     {
00615       /* Check for the Timeout */
00616       if(Timeout != HAL_MAX_DELAY)
00617       {
00618         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
00619         {
00620           hcan->State = HAL_CAN_STATE_TIMEOUT;
00621           /* Process unlocked */
00622           __HAL_UNLOCK(hcan);
00623           return HAL_TIMEOUT;
00624         }
00625       }
00626     }
00627     if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
00628     {
00629       /* Change CAN state */
00630       hcan->State = HAL_CAN_STATE_BUSY_RX;
00631     }
00632     else
00633     {
00634       /* Change CAN state */
00635       hcan->State = HAL_CAN_STATE_READY;
00636     }
00637     
00638     /* Process unlocked */
00639     __HAL_UNLOCK(hcan);
00640     
00641     /* Return function status */
00642     return HAL_OK;
00643   }
00644   else
00645   {
00646     /* Change CAN state */
00647     hcan->State = HAL_CAN_STATE_ERROR; 
00648     
00649     /* Process unlocked */
00650     __HAL_UNLOCK(hcan);
00651 
00652     /* Return function status */
00653     return HAL_ERROR;
00654   }
00655 }
00656 
00657 /**
00658   * @brief  Initiate and transmit a CAN frame message in Interrupt mode.
00659   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00660   *         the configuration information for the specified CAN.  
00661   * @retval HAL status
00662   */
00663 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
00664 {
00665   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
00666 
00667   /* Check the parameters */
00668   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
00669   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
00670   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
00671   
00672   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
00673   {
00674     /* Process Locked */
00675     __HAL_LOCK(hcan);
00676     
00677     /* Select one empty transmit mailbox */
00678     if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
00679     {
00680       transmitmailbox = 0;
00681     }
00682     else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
00683     {
00684       transmitmailbox = 1;
00685     }
00686     else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
00687     {
00688       transmitmailbox = 2;
00689     }
00690 
00691     if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
00692     {
00693       /* Set up the Id */
00694       hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
00695       if(hcan->pTxMsg->IDE == CAN_ID_STD)
00696       {
00697         assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
00698         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
00699                                                   hcan->pTxMsg->RTR);
00700       }
00701       else
00702       {
00703         assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
00704         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
00705                                                   hcan->pTxMsg->IDE | \
00706                                                   hcan->pTxMsg->RTR);
00707       }
00708     
00709       /* Set up the DLC */
00710       hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
00711       hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
00712       hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
00713 
00714       /* Set up the data field */
00715       hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | 
00716                                              ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
00717                                              ((uint32_t)hcan->pTxMsg->Data[1] << 8) | 
00718                                              ((uint32_t)hcan->pTxMsg->Data[0]));
00719       hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | 
00720                                              ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
00721                                              ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
00722                                              ((uint32_t)hcan->pTxMsg->Data[4]));
00723     
00724       if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
00725       {
00726         /* Change CAN state */
00727         hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
00728       }
00729       else
00730       {
00731         /* Change CAN state */
00732         hcan->State = HAL_CAN_STATE_BUSY_TX;
00733       }
00734       
00735       /* Set CAN error code to none */
00736       hcan->ErrorCode = HAL_CAN_ERROR_NONE;
00737       
00738       /* Process Unlocked */
00739       __HAL_UNLOCK(hcan);
00740       
00741       /* Enable interrupts: */
00742       /*  - Enable Error warning Interrupt */
00743       /*  - Enable Error passive Interrupt */
00744       /*  - Enable Bus-off Interrupt */
00745       /*  - Enable Last error code Interrupt */
00746       /*  - Enable Error Interrupt */
00747       /*  - Enable Transmit mailbox empty Interrupt */
00748       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
00749                                 CAN_IT_EPV |
00750                                 CAN_IT_BOF |
00751                                 CAN_IT_LEC |
00752                                 CAN_IT_ERR |
00753                                 CAN_IT_TME  );
00754       
00755       /* Request transmission */
00756       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
00757     }
00758   }
00759   else
00760   {
00761     return HAL_BUSY;
00762   }
00763   
00764   return HAL_OK;
00765 }
00766 
00767 /**
00768   * @brief  Receive a correct CAN frame.
00769   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00770   *         the configuration information for the specified CAN.  
00771   * @param  FIFONumber:    FIFO number.
00772   * @param  Timeout:       Timeout duration.
00773   * @retval HAL status
00774   */
00775 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
00776 {
00777   uint32_t tickstart = 0;
00778    
00779   /* Check the parameters */
00780   assert_param(IS_CAN_FIFO(FIFONumber));
00781   
00782   /* Process locked */
00783   __HAL_LOCK(hcan);
00784   
00785   if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
00786   {
00787     /* Change CAN state */
00788     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
00789   }
00790   else
00791   {
00792     /* Change CAN state */
00793     hcan->State = HAL_CAN_STATE_BUSY_RX;
00794   }
00795     
00796   /* Get tick */
00797   tickstart = HAL_GetTick();
00798   
00799   /* Check pending message */
00800   while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
00801   {
00802     /* Check for the Timeout */
00803     if(Timeout != HAL_MAX_DELAY)
00804     {
00805       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
00806       {
00807         hcan->State = HAL_CAN_STATE_TIMEOUT;
00808         /* Process unlocked */
00809         __HAL_UNLOCK(hcan);
00810         return HAL_TIMEOUT;
00811       }
00812     }
00813   }
00814   
00815   /* Get the Id */
00816   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
00817   if (hcan->pRxMsg->IDE == CAN_ID_STD)
00818   {
00819     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
00820   }
00821   else
00822   {
00823     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
00824   }
00825   
00826   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
00827   /* Get the DLC */
00828   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
00829   /* Get the FMI */
00830   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
00831   /* Get the data field */
00832   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
00833   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
00834   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
00835   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
00836   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
00837   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
00838   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
00839   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
00840   
00841   /* Release the FIFO */
00842   if(FIFONumber == CAN_FIFO0)
00843   {
00844     /* Release FIFO0 */
00845     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
00846   }
00847   else /* FIFONumber == CAN_FIFO1 */
00848   {
00849     /* Release FIFO1 */
00850     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
00851   }
00852   
00853   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
00854   {
00855     /* Change CAN state */
00856     hcan->State = HAL_CAN_STATE_BUSY_TX;
00857   }
00858   else
00859   {
00860     /* Change CAN state */
00861     hcan->State = HAL_CAN_STATE_READY;
00862   }
00863   
00864   /* Process unlocked */
00865   __HAL_UNLOCK(hcan);
00866 
00867   /* Return function status */
00868   return HAL_OK;
00869 }
00870 
00871 /**
00872   * @brief  Receive a correct CAN frame in Interrupt mode.
00873   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00874   *         the configuration information for the specified CAN.  
00875   * @param  FIFONumber:    FIFO number.
00876   * @retval HAL status
00877   */
00878 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
00879 {
00880   /* Check the parameters */
00881   assert_param(IS_CAN_FIFO(FIFONumber));
00882   
00883   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
00884   {
00885     /* Process locked */
00886     __HAL_LOCK(hcan);
00887   
00888     if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
00889     {
00890       /* Change CAN state */
00891       hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
00892     }
00893     else
00894     {
00895       /* Change CAN state */
00896       hcan->State = HAL_CAN_STATE_BUSY_RX;
00897     }
00898     
00899     /* Set CAN error code to none */
00900     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
00901     
00902     /* Enable interrupts: */
00903     /*  - Enable Error warning Interrupt */
00904     /*  - Enable Error passive Interrupt */
00905     /*  - Enable Bus-off Interrupt */
00906     /*  - Enable Last error code Interrupt */
00907     /*  - Enable Error Interrupt */
00908     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
00909                               CAN_IT_EPV |
00910                               CAN_IT_BOF |
00911                               CAN_IT_LEC |
00912                               CAN_IT_ERR );
00913 
00914     /* Process unlocked */
00915     __HAL_UNLOCK(hcan);
00916 
00917     if(FIFONumber == CAN_FIFO0)
00918     {
00919       /* Enable FIFO 0 message pending Interrupt */
00920       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
00921     }
00922     else
00923     {
00924       /* Enable FIFO 1 message pending Interrupt */
00925       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
00926     }
00927     
00928   }
00929   else
00930   {
00931     return HAL_BUSY;
00932   }
00933   
00934   /* Return function status */
00935   return HAL_OK;
00936 }
00937 
00938 /**
00939   * @brief  Enter the Sleep (low power) mode.
00940   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00941   *         the configuration information for the specified CAN.
00942   * @retval HAL status.
00943   */
00944 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
00945 {
00946   uint32_t tickstart = 0;
00947    
00948   /* Process locked */
00949   __HAL_LOCK(hcan);
00950   
00951   /* Change CAN state */
00952   hcan->State = HAL_CAN_STATE_BUSY; 
00953     
00954   /* Request Sleep mode */
00955    hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
00956    
00957   /* Sleep mode status */
00958   if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
00959   {
00960     /* Process unlocked */
00961     __HAL_UNLOCK(hcan);
00962 
00963     /* Return function status */
00964     return HAL_ERROR;
00965   }
00966   
00967   /* Get tick */
00968   tickstart = HAL_GetTick();
00969   
00970   /* Wait the acknowledge */
00971   while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
00972   {
00973     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
00974     {
00975       hcan->State = HAL_CAN_STATE_TIMEOUT;
00976       /* Process unlocked */
00977       __HAL_UNLOCK(hcan);
00978       return HAL_TIMEOUT;
00979     }
00980   }
00981   
00982   /* Change CAN state */
00983   hcan->State = HAL_CAN_STATE_READY;
00984   
00985   /* Process unlocked */
00986   __HAL_UNLOCK(hcan);
00987   
00988   /* Return function status */
00989   return HAL_OK;
00990 }
00991 
00992 /**
00993   * @brief  Wake up the CAN peripheral from sleep mode (after that the CAN peripheral
00994   *         is in the normal mode).
00995   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
00996   *         the configuration information for the specified CAN.
00997   * @retval HAL status.
00998   */
00999 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
01000 {
01001   uint32_t tickstart = 0;
01002     
01003   /* Process locked */
01004   __HAL_LOCK(hcan);
01005   
01006   /* Change CAN state */
01007   hcan->State = HAL_CAN_STATE_BUSY;  
01008  
01009   /* Wake up request */
01010   hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
01011 
01012   /* Get tick */
01013   tickstart = HAL_GetTick();
01014 
01015   /* Sleep mode status */
01016   while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
01017   {
01018     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
01019     {
01020       hcan->State= HAL_CAN_STATE_TIMEOUT;
01021       /* Process unlocked */
01022       __HAL_UNLOCK(hcan);
01023       return HAL_TIMEOUT;
01024     }
01025   }
01026   if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
01027   {
01028     /* Process unlocked */
01029     __HAL_UNLOCK(hcan);
01030 
01031     /* Return function status */
01032     return HAL_ERROR;
01033   }
01034   
01035   /* Change CAN state */
01036   hcan->State = HAL_CAN_STATE_READY; 
01037   
01038   /* Process unlocked */
01039   __HAL_UNLOCK(hcan);
01040   
01041   /* Return function status */
01042   return HAL_OK;
01043 }
01044 
01045 /**
01046   * @brief  Handle CAN interrupt request.
01047   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01048   *         the configuration information for the specified CAN.
01049   * @retval None
01050   */
01051 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
01052 {
01053   /* Check End of transmission flag */
01054   if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
01055   {
01056     if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
01057        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
01058        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
01059     {
01060       /* Call transmit function */
01061       CAN_Transmit_IT(hcan);
01062     }
01063   }
01064   
01065   /* Check End of reception flag for FIFO0 */
01066   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
01067      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
01068   {
01069     /* Call receive function */
01070     CAN_Receive_IT(hcan, CAN_FIFO0);
01071   }
01072   
01073   /* Check End of reception flag for FIFO1 */
01074   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
01075      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
01076   {
01077     /* Call receive function */
01078     CAN_Receive_IT(hcan, CAN_FIFO1);
01079   }
01080   
01081   /* Check Error Warning Flag */
01082   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG))    &&
01083      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
01084      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
01085   {
01086     /* Set CAN error code to EWG error */
01087     hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
01088     /* No need for clear of Error Warning Flag as read-only */
01089   }
01090   
01091   /* Check Error Passive Flag */
01092   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV))    &&
01093      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
01094      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
01095   {
01096     /* Set CAN error code to EPV error */
01097     hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
01098     /* No need for clear of Error Passive Flag as read-only */ 
01099   }
01100   
01101   /* Check Bus-Off Flag */
01102   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF))    &&
01103      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
01104      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
01105   {
01106     /* Set CAN error code to BOF error */
01107     hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
01108     /* No need for clear of Bus-Off Flag as read-only */
01109   }
01110   
01111   /* Check Last error code Flag */
01112   if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
01113      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC))         &&
01114      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
01115   {
01116     switch(hcan->Instance->ESR & CAN_ESR_LEC)
01117     {
01118       case(CAN_ESR_LEC_0):
01119           /* Set CAN error code to STF error */
01120           hcan->ErrorCode |= HAL_CAN_ERROR_STF;
01121           break;
01122       case(CAN_ESR_LEC_1):
01123           /* Set CAN error code to FOR error */
01124           hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
01125           break;
01126       case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
01127           /* Set CAN error code to ACK error */
01128           hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
01129           break;
01130       case(CAN_ESR_LEC_2):
01131           /* Set CAN error code to BR error */
01132           hcan->ErrorCode |= HAL_CAN_ERROR_BR;
01133           break;
01134       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
01135           /* Set CAN error code to BD error */
01136           hcan->ErrorCode |= HAL_CAN_ERROR_BD;
01137           break;
01138       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
01139           /* Set CAN error code to CRC error */
01140           hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
01141           break;
01142       default:
01143           break;
01144     }
01145 
01146     /* Clear Last error code Flag */ 
01147     hcan->Instance->ESR &= ~(CAN_ESR_LEC);
01148   }
01149 
01150   /* Call the Error call Back in case of Errors */
01151   if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
01152   {
01153     /* Clear ERRI bit */
01154     SET_BIT(hcan->Instance->MSR, CAN_MSR_ERRI);
01155     /* Set the CAN state ready to be able to start again the process */
01156     hcan->State = HAL_CAN_STATE_READY;
01157     /* Call Error callback function */
01158     HAL_CAN_ErrorCallback(hcan);
01159   }  
01160 }
01161 
01162 /**
01163   * @brief  Transmission complete callback in non-blocking mode.
01164   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01165   *         the configuration information for the specified CAN.
01166   * @retval None
01167   */
01168 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
01169 {
01170   /* Prevent unused argument(s) compilation warning */
01171   UNUSED(hcan);
01172 
01173   /* NOTE : This function should not be modified, when the callback is needed,
01174             the HAL_CAN_TxCpltCallback could be implemented in the user file
01175    */
01176 }
01177 
01178 /**
01179   * @brief  Reception complete callback in non-blocking mode.
01180   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01181   *         the configuration information for the specified CAN.
01182   * @retval None
01183   */
01184 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
01185 {
01186   /* Prevent unused argument(s) compilation warning */
01187   UNUSED(hcan);
01188 
01189   /* NOTE : This function should not be modified, when the callback is needed,
01190             the HAL_CAN_RxCpltCallback could be implemented in the user file
01191    */
01192 }
01193 
01194 /**
01195   * @brief  Error CAN callback.
01196   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01197   *         the configuration information for the specified CAN.
01198   * @retval None
01199   */
01200 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
01201 {
01202   /* Prevent unused argument(s) compilation warning */
01203   UNUSED(hcan);
01204 
01205   /* NOTE : This function should not be modified, when the callback is needed,
01206             the HAL_CAN_ErrorCallback could be implemented in the user file
01207    */
01208 }
01209 
01210 /**
01211   * @}
01212   */
01213 
01214 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
01215  *  @brief   CAN Peripheral State functions 
01216  *
01217 @verbatim   
01218   ==============================================================================
01219             ##### Peripheral State and Error functions #####
01220   ==============================================================================
01221     [..]
01222     This subsection provides functions allowing to :
01223       (+) Check the CAN state.
01224       (+) Check CAN Errors detected during interrupt process.
01225          
01226 @endverbatim
01227   * @{
01228   */
01229 
01230 /**
01231   * @brief  Return the CAN handle state.
01232   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01233   *         the configuration information for the specified CAN.
01234   * @retval HAL state
01235   */
01236 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
01237 {
01238   /* Return CAN handle state */
01239   return hcan->State;
01240 }
01241 
01242 /**
01243   * @brief  Return the CAN error code.
01244   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01245   *         the configuration information for the specified CAN.
01246   * @retval CAN Error Code
01247   */
01248 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
01249 {
01250   return hcan->ErrorCode;
01251 }
01252 
01253 /**
01254   * @}
01255   */
01256 
01257 /**
01258   * @}
01259   */
01260 
01261 /** @defgroup CAN_Private_Functions CAN Private Functions
01262  * @{
01263  */
01264 /**
01265   * @brief  Initiate and transmit a CAN frame message.
01266   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
01267   *         the configuration information for the specified CAN.  
01268   * @retval HAL status
01269   */
01270 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
01271 {
01272   /* Disable Transmit mailbox empty Interrupt */
01273   __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
01274   
01275   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
01276   {   
01277     /* Disable interrupts: */
01278     /*  - Disable Error warning Interrupt */
01279     /*  - Disable Error passive Interrupt */
01280     /*  - Disable Bus-off Interrupt */
01281     /*  - Disable Last error code Interrupt */
01282     /*  - Disable Error Interrupt */
01283     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
01284                                CAN_IT_EPV |
01285                                CAN_IT_BOF |
01286                                CAN_IT_LEC |
01287                                CAN_IT_ERR  );
01288   }
01289   
01290   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
01291   {
01292     /* Change CAN state */
01293     hcan->State = HAL_CAN_STATE_BUSY_RX;
01294   }
01295   else
01296   {
01297     /* Change CAN state */
01298     hcan->State = HAL_CAN_STATE_READY;
01299   }
01300   
01301   /* Transmission complete callback */ 
01302   HAL_CAN_TxCpltCallback(hcan);
01303   
01304   return HAL_OK;
01305 }
01306 
01307 /**
01308   * @brief  Receive a correct CAN frame.
01309   * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
01310   *         the configuration information for the specified CAN.  
01311   * @param  FIFONumber: Specify the FIFO number    
01312   * @retval HAL status
01313   */
01314 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
01315 {
01316   /* Get the Id */
01317   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
01318   if (hcan->pRxMsg->IDE == CAN_ID_STD)
01319   {
01320     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
01321   }
01322   else
01323   {
01324     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
01325   }
01326   
01327   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
01328   /* Get the DLC */
01329   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
01330   /* Get the FMI */
01331   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
01332   /* Get the data field */
01333   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
01334   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
01335   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
01336   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
01337   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
01338   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
01339   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
01340   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
01341   /* Release the FIFO */
01342   /* Release FIFO0 */
01343   if (FIFONumber == CAN_FIFO0)
01344   {
01345     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
01346     
01347     /* Disable FIFO 0 message pending Interrupt */
01348     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
01349   }
01350   /* Release FIFO1 */
01351   else /* FIFONumber == CAN_FIFO1 */
01352   {
01353     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
01354     
01355     /* Disable FIFO 1 message pending Interrupt */
01356     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
01357   }
01358   
01359   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
01360   {
01361     /* Disable interrupts: */
01362     /*  - Disable Error warning Interrupt */
01363     /*  - Disable Error passive Interrupt */
01364     /*  - Disable Bus-off Interrupt */
01365     /*  - Disable Last error code Interrupt */
01366     /*  - Disable Error Interrupt */
01367     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
01368                                CAN_IT_EPV |
01369                                CAN_IT_BOF |
01370                                CAN_IT_LEC |
01371                                CAN_IT_ERR  );
01372   }
01373   
01374   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
01375   {
01376     /* Disable CAN state */
01377     hcan->State = HAL_CAN_STATE_BUSY_TX;
01378   }
01379   else
01380   {
01381     /* Change CAN state */
01382     hcan->State = HAL_CAN_STATE_READY;
01383   }
01384 
01385   /* Receive complete callback */ 
01386   HAL_CAN_RxCpltCallback(hcan);
01387 
01388   /* Return function status */
01389   return HAL_OK;
01390 }
01391 /**
01392  * @}
01393  */
01394 
01395 #endif /* HAL_CAN_MODULE_ENABLED */
01396 /**
01397   * @}
01398   */
01399 
01400 /**
01401   * @}
01402   */
01403 
01404 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/