Subversion Repositories DashDisplay

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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