Subversion Repositories DashDisplay

Rev

Rev 2 | 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.4
  6.   * @date    29-April-2016
  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) 2016 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.   /* Prevent unused argument(s) compilation warning */
  480.   UNUSED(hcan);
  481.   /* NOTE : This function Should not be modified, when the callback is needed,
  482.             the HAL_CAN_MspInit can be implemented in the user file
  483.    */
  484. }
  485.  
  486. /**
  487.   * @brief  DeInitializes the CAN MSP.
  488.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  489.   *         the configuration information for the specified CAN.  
  490.   * @retval None
  491.   */
  492. __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
  493. {
  494.   /* Prevent unused argument(s) compilation warning */
  495.   UNUSED(hcan);
  496.   /* NOTE : This function Should not be modified, when the callback is needed,
  497.             the HAL_CAN_MspDeInit can be implemented in the user file
  498.    */
  499. }
  500.  
  501. /**
  502.   * @}
  503.   */
  504.  
  505. /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
  506.  *  @brief    I/O operation functions
  507.  *
  508. @verbatim  
  509.   ==============================================================================
  510.                       ##### IO operation functions #####
  511.   ==============================================================================
  512.     [..]  This section provides functions allowing to:
  513.       (+) Transmit a CAN frame message.
  514.       (+) Receive a CAN frame message.
  515.       (+) Enter CAN peripheral in sleep mode.
  516.       (+) Wake up the CAN peripheral from sleep mode.
  517.                
  518. @endverbatim
  519.   * @{
  520.   */
  521.  
  522. /**
  523.   * @brief  Initiates and transmits a CAN frame message.
  524.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  525.   *         the configuration information for the specified CAN.  
  526.   * @param  Timeout: Specify Timeout value  
  527.   * @retval HAL status
  528.   */
  529. HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
  530. {
  531.   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  532.   uint32_t tickstart = 0;
  533.  
  534.   /* Check the parameters */
  535.   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  536.   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  537.   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  538.  
  539.   /* Process locked */
  540.   __HAL_LOCK(hcan);
  541.  
  542.   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  543.   {
  544.     /* Change CAN state */
  545.     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  546.   }
  547.   else
  548.   {
  549.     /* Change CAN state */
  550.     hcan->State = HAL_CAN_STATE_BUSY_TX;
  551.   }
  552.  
  553.   /* Select one empty transmit mailbox */
  554.   if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  555.   {
  556.     transmitmailbox = 0;
  557.   }
  558.   else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  559.   {
  560.     transmitmailbox = 1;
  561.   }
  562.   else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  563.   {
  564.     transmitmailbox = 2;
  565.   }
  566.   else
  567.   {
  568.     transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  569.   }
  570.  
  571.   if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  572.   {
  573.     /* Set up the Id */
  574.     hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  575.     if (hcan->pTxMsg->IDE == CAN_ID_STD)
  576.     {
  577.       assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
  578.       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
  579.                                                            hcan->pTxMsg->RTR);
  580.     }
  581.     else
  582.     {
  583.       assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  584.       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
  585.                                                            hcan->pTxMsg->IDE |
  586.                                                            hcan->pTxMsg->RTR);
  587.     }
  588.    
  589.     /* Set up the DLC */
  590.     hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  591.     hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  592.     hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  593.  
  594.     /* Set up the data field */
  595.     WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
  596.                                                                 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
  597.                                                                 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
  598.                                                                 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
  599.     WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
  600.                                                                 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
  601.                                                                 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
  602.                                                                 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
  603.     /* Request transmission */
  604.     SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
  605.  
  606.     /* Get timeout */
  607.     tickstart = HAL_GetTick();  
  608.  
  609.     /* Check End of transmission flag */
  610.     while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  611.     {
  612.       /* Check for the Timeout */
  613.       if(Timeout != HAL_MAX_DELAY)
  614.       {
  615.         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
  616.         {
  617.           hcan->State = HAL_CAN_STATE_TIMEOUT;
  618.          
  619.           /* Process unlocked */
  620.           __HAL_UNLOCK(hcan);
  621.          
  622.           return HAL_TIMEOUT;
  623.         }
  624.       }
  625.     }
  626.     if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  627.     {
  628.       /* Change CAN state */
  629.       hcan->State = HAL_CAN_STATE_BUSY_RX;
  630.      
  631.       /* Process unlocked */
  632.       __HAL_UNLOCK(hcan);
  633.     }
  634.     else
  635.     {
  636.       /* Change CAN state */
  637.       hcan->State = HAL_CAN_STATE_READY;
  638.     }
  639.    
  640.     /* Process unlocked */
  641.     __HAL_UNLOCK(hcan);
  642.    
  643.     /* Return function status */
  644.     return HAL_OK;
  645.   }
  646.   else
  647.   {
  648.     /* Change CAN state */
  649.     hcan->State = HAL_CAN_STATE_ERROR;
  650.    
  651.     /* Process unlocked */
  652.     __HAL_UNLOCK(hcan);
  653.  
  654.     /* Return function status */
  655.     return HAL_ERROR;
  656.   }
  657. }
  658.  
  659. /**
  660.   * @brief  Initiates and transmits a CAN frame message.
  661.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  662.   *         the configuration information for the specified CAN.  
  663.   * @retval HAL status
  664.   */
  665. HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  666. {
  667.   uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  668.  
  669.   /* Check the parameters */
  670.   assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  671.   assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  672.   assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  673.  
  674.   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
  675.   {
  676.     /* Process Locked */
  677.     __HAL_LOCK(hcan);
  678.    
  679.     /* Select one empty transmit mailbox */
  680.     if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  681.     {
  682.       transmitmailbox = 0;
  683.     }
  684.     else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  685.     {
  686.       transmitmailbox = 1;
  687.     }
  688.     else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  689.     {
  690.       transmitmailbox = 2;
  691.     }
  692.     else
  693.     {
  694.       transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  695.     }
  696.  
  697.     if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  698.     {
  699.       /* Set up the Id */
  700.       hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  701.       if (hcan->pTxMsg->IDE == CAN_ID_STD)
  702.       {
  703.         assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
  704.         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
  705.                                                              hcan->pTxMsg->RTR);
  706.       }
  707.       else
  708.       {
  709.         assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  710.         hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
  711.                                                              hcan->pTxMsg->IDE |
  712.                                                              hcan->pTxMsg->RTR);
  713.       }
  714.    
  715.       /* Set up the DLC */
  716.       hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  717.       hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  718.       hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  719.      
  720.       /* Set up the data field */
  721.       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
  722.                                                                   ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
  723.                                                                   ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
  724.                                                                   ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
  725.       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
  726.                                                                   ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
  727.                                                                   ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
  728.                                                                   ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
  729.    
  730.       if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  731.       {
  732.         /* Change CAN state */
  733.         hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  734.       }
  735.       else
  736.       {
  737.         /* Change CAN state */
  738.         hcan->State = HAL_CAN_STATE_BUSY_TX;
  739.       }
  740.      
  741.       /* Set CAN error code to none */
  742.       hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  743.      
  744.       /* Process Unlocked */
  745.       __HAL_UNLOCK(hcan);
  746.      
  747.       /* Enable interrupts: */
  748.       /*  - Enable Error warning Interrupt */
  749.       /*  - Enable Error passive Interrupt */
  750.       /*  - Enable Bus-off Interrupt */
  751.       /*  - Enable Last error code Interrupt */
  752.       /*  - Enable Error Interrupt */
  753.       /*  - Enable Transmit mailbox empty Interrupt */
  754.       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  755.                                 CAN_IT_EPV |
  756.                                 CAN_IT_BOF |
  757.                                 CAN_IT_LEC |
  758.                                 CAN_IT_ERR |
  759.                                 CAN_IT_TME  );
  760.      
  761.       /* Request transmission */
  762.       hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  763.     }
  764.   }
  765.   else
  766.   {
  767.     return HAL_BUSY;
  768.   }
  769.  
  770.   return HAL_OK;
  771. }
  772.  
  773. /**
  774.   * @brief  Receives a correct CAN frame.
  775.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  776.   *         the configuration information for the specified CAN.  
  777.   * @param  FIFONumber: FIFO Number value
  778.   * @param  Timeout: Specify Timeout value
  779.   * @retval HAL status
  780.   * @retval None
  781.   */
  782. HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
  783. {
  784.   uint32_t tickstart = 0;
  785.    
  786.   /* Check the parameters */
  787.   assert_param(IS_CAN_FIFO(FIFONumber));
  788.  
  789.   /* Process locked */
  790.   __HAL_LOCK(hcan);
  791.  
  792.   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  793.   {
  794.     /* Change CAN state */
  795.     hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  796.   }
  797.   else
  798.   {
  799.     /* Change CAN state */
  800.     hcan->State = HAL_CAN_STATE_BUSY_RX;
  801.   }
  802.    
  803.   /* Get tick */
  804.   tickstart = HAL_GetTick();
  805.  
  806.   /* Check pending message */
  807.   while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
  808.   {
  809.     /* Check for the Timeout */
  810.     if(Timeout != HAL_MAX_DELAY)
  811.     {
  812.       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
  813.       {
  814.         hcan->State = HAL_CAN_STATE_TIMEOUT;
  815.        
  816.         /* Process unlocked */
  817.         __HAL_UNLOCK(hcan);
  818.        
  819.         return HAL_TIMEOUT;
  820.       }
  821.     }
  822.   }
  823.  
  824.   /* Get the Id */
  825.   hcan->pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  826.   if (hcan->pRxMsg->IDE == CAN_ID_STD)
  827.   {
  828.     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
  829.   }
  830.   else
  831.   {
  832.     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
  833.   }
  834.  
  835.   hcan->pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  836.   /* Get the DLC */
  837.   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  838.   /* Get the FMI */
  839.   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
  840.   /* Get the data field */
  841.   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  842.   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
  843.   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
  844.   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
  845.   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  846.   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
  847.   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
  848.   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
  849.  
  850.   /* Release the FIFO */
  851.   if(FIFONumber == CAN_FIFO0)
  852.   {
  853.     /* Release FIFO0 */
  854.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  855.   }
  856.   else /* FIFONumber == CAN_FIFO1 */
  857.   {
  858.     /* Release FIFO1 */
  859.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  860.   }
  861.  
  862.   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  863.   {
  864.     /* Change CAN state */
  865.     hcan->State = HAL_CAN_STATE_BUSY_TX;
  866.   }
  867.   else
  868.   {
  869.     /* Change CAN state */
  870.     hcan->State = HAL_CAN_STATE_READY;
  871.   }
  872.  
  873.   /* Process unlocked */
  874.   __HAL_UNLOCK(hcan);
  875.  
  876.   /* Return function status */
  877.   return HAL_OK;
  878. }
  879.  
  880. /**
  881.   * @brief  Receives a correct CAN frame.
  882.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  883.   *         the configuration information for the specified CAN.  
  884.   * @param  FIFONumber: Specify the FIFO number    
  885.   * @retval HAL status
  886.   * @retval None
  887.   */
  888. HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  889. {
  890.   /* Check the parameters */
  891.   assert_param(IS_CAN_FIFO(FIFONumber));
  892.  
  893.   if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
  894.   {
  895.     /* Process locked */
  896.     __HAL_LOCK(hcan);
  897.  
  898.     if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  899.     {
  900.       /* Change CAN state */
  901.       hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  902.     }
  903.     else
  904.     {
  905.       /* Change CAN state */
  906.       hcan->State = HAL_CAN_STATE_BUSY_RX;
  907.     }
  908.    
  909.     /* Set CAN error code to none */
  910.     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  911.    
  912.     /* Enable interrupts: */
  913.     /*  - Enable Error warning Interrupt */
  914.     /*  - Enable Error passive Interrupt */
  915.     /*  - Enable Bus-off Interrupt */
  916.     /*  - Enable Last error code Interrupt */
  917.     /*  - Enable Error Interrupt */
  918.     /*  - Enable Transmit mailbox empty Interrupt */
  919.     __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  920.                               CAN_IT_EPV |
  921.                               CAN_IT_BOF |
  922.                               CAN_IT_LEC |
  923.                               CAN_IT_ERR |
  924.                               CAN_IT_TME  );
  925.  
  926.     /* Process unlocked */
  927.     __HAL_UNLOCK(hcan);
  928.  
  929.     if(FIFONumber == CAN_FIFO0)
  930.     {
  931.       /* Enable FIFO 0 message pending Interrupt */
  932.       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
  933.     }
  934.     else
  935.     {
  936.       /* Enable FIFO 1 message pending Interrupt */
  937.       __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
  938.     }
  939.    
  940.   }
  941.   else
  942.   {
  943.     return HAL_BUSY;
  944.   }
  945.  
  946.   /* Return function status */
  947.   return HAL_OK;
  948. }
  949.  
  950. /**
  951.   * @brief  Enters the Sleep (low power) mode.
  952.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  953.   *         the configuration information for the specified CAN.
  954.   * @retval HAL status.
  955.   */
  956. HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
  957. {
  958.   uint32_t tickstart = 0;
  959.    
  960.   /* Process locked */
  961.   __HAL_LOCK(hcan);
  962.  
  963.   /* Change CAN state */
  964.   hcan->State = HAL_CAN_STATE_BUSY;
  965.    
  966.   /* Request Sleep mode */
  967.   MODIFY_REG(hcan->Instance->MCR,
  968.              CAN_MCR_INRQ       ,
  969.              CAN_MCR_SLEEP       );
  970.      
  971.   /* Sleep mode status */
  972.   if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  973.       HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
  974.   {
  975.     /* Process unlocked */
  976.     __HAL_UNLOCK(hcan);
  977.  
  978.     /* Return function status */
  979.     return HAL_ERROR;
  980.   }
  981.  
  982.   /* Get tick */
  983.   tickstart = HAL_GetTick();
  984.  
  985.   /* Wait the acknowledge */
  986.   while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  987.          HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
  988.   {
  989.     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  990.     {
  991.       hcan->State = HAL_CAN_STATE_TIMEOUT;
  992.      
  993.       /* Process unlocked */
  994.       __HAL_UNLOCK(hcan);
  995.      
  996.       return HAL_TIMEOUT;
  997.     }
  998.   }
  999.  
  1000.   /* Change CAN state */
  1001.   hcan->State = HAL_CAN_STATE_READY;
  1002.  
  1003.   /* Process unlocked */
  1004.   __HAL_UNLOCK(hcan);
  1005.  
  1006.   /* Return function status */
  1007.   return HAL_OK;
  1008. }
  1009.  
  1010. /**
  1011.   * @brief  Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
  1012.   *         is in the normal mode.
  1013.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1014.   *         the configuration information for the specified CAN.
  1015.   * @retval HAL status.
  1016.   */
  1017. HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
  1018. {
  1019.   uint32_t tickstart = 0;
  1020.    
  1021.   /* Process locked */
  1022.   __HAL_LOCK(hcan);
  1023.  
  1024.   /* Change CAN state */
  1025.   hcan->State = HAL_CAN_STATE_BUSY;  
  1026.  
  1027.   /* Wake up request */
  1028.   CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
  1029.    
  1030.   /* Get timeout */
  1031.   tickstart = HAL_GetTick();  
  1032.  
  1033.   /* Sleep mode status */
  1034.   while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
  1035.   {
  1036.     if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  1037.     {
  1038.       hcan->State= HAL_CAN_STATE_TIMEOUT;
  1039.      
  1040.       /* Process unlocked */
  1041.       __HAL_UNLOCK(hcan);
  1042.      
  1043.       return HAL_TIMEOUT;
  1044.     }
  1045.   }
  1046.   if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
  1047.   {
  1048.     /* Process unlocked */
  1049.     __HAL_UNLOCK(hcan);
  1050.  
  1051.     /* Return function status */
  1052.     return HAL_ERROR;
  1053.   }
  1054.  
  1055.   /* Change CAN state */
  1056.   hcan->State = HAL_CAN_STATE_READY;
  1057.  
  1058.   /* Process unlocked */
  1059.   __HAL_UNLOCK(hcan);
  1060.  
  1061.   /* Return function status */
  1062.   return HAL_OK;
  1063. }
  1064.  
  1065. /**
  1066.   * @brief  Handles CAN interrupt request  
  1067.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1068.   *         the configuration information for the specified CAN.
  1069.   * @retval None
  1070.   */
  1071. void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
  1072. {
  1073.   /* Check End of transmission flag */
  1074.   if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
  1075.   {
  1076.     if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
  1077.        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
  1078.        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
  1079.     {
  1080.       /* Call transmit function */
  1081.       CAN_Transmit_IT(hcan);
  1082.     }
  1083.   }
  1084.  
  1085.   /* Check End of reception flag for FIFO0 */
  1086.   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
  1087.      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
  1088.   {
  1089.     /* Call receive function */
  1090.     CAN_Receive_IT(hcan, CAN_FIFO0);
  1091.   }
  1092.  
  1093.   /* Check End of reception flag for FIFO1 */
  1094.   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
  1095.      (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
  1096.   {
  1097.     /* Call receive function */
  1098.     CAN_Receive_IT(hcan, CAN_FIFO1);
  1099.   }
  1100.  
  1101.   /* Check Error Warning Flag */
  1102.   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG))    &&
  1103.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
  1104.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  1105.   {
  1106.     /* Set CAN error code to EWG error */
  1107.     hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
  1108.     /* No need for clear of Error Warning Flag as read-only */
  1109.   }
  1110.  
  1111.   /* Check Error Passive Flag */
  1112.   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV))    &&
  1113.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
  1114.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  1115.   {
  1116.     /* Set CAN error code to EPV error */
  1117.     hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
  1118.     /* No need for clear of Error Passive Flag as read-only */
  1119.   }
  1120.  
  1121.   /* Check Bus-Off Flag */
  1122.   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF))    &&
  1123.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
  1124.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  1125.   {
  1126.     /* Set CAN error code to BOF error */
  1127.     hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
  1128.     /* No need for clear of Bus-Off Flag as read-only */
  1129.   }
  1130.  
  1131.   /* Check Last error code Flag */
  1132.   if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
  1133.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC))         &&
  1134.      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  1135.   {
  1136.     switch(hcan->Instance->ESR & CAN_ESR_LEC)
  1137.     {
  1138.       case(CAN_ESR_LEC_0):
  1139.           /* Set CAN error code to STF error */
  1140.           hcan->ErrorCode |= HAL_CAN_ERROR_STF;
  1141.           break;
  1142.       case(CAN_ESR_LEC_1):
  1143.           /* Set CAN error code to FOR error */
  1144.           hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
  1145.           break;
  1146.       case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
  1147.           /* Set CAN error code to ACK error */
  1148.           hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
  1149.           break;
  1150.       case(CAN_ESR_LEC_2):
  1151.           /* Set CAN error code to BR error */
  1152.           hcan->ErrorCode |= HAL_CAN_ERROR_BR;
  1153.           break;
  1154.       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
  1155.           /* Set CAN error code to BD error */
  1156.           hcan->ErrorCode |= HAL_CAN_ERROR_BD;
  1157.           break;
  1158.       case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
  1159.           /* Set CAN error code to CRC error */
  1160.           hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
  1161.           break;
  1162.       default:
  1163.           break;
  1164.     }
  1165.  
  1166.     /* Clear Last error code Flag */
  1167.     CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
  1168.   }
  1169.  
  1170.   /* Call the Error call Back in case of Errors */
  1171.   if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
  1172.   {
  1173.     /* Clear ERRI Flag */
  1174.     hcan->Instance->MSR |= CAN_MSR_ERRI;
  1175.     /* Set the CAN state ready to be able to start again the process */
  1176.     hcan->State = HAL_CAN_STATE_READY;
  1177.    
  1178.     /* Call Error callback function */
  1179.     HAL_CAN_ErrorCallback(hcan);
  1180.   }  
  1181. }
  1182.  
  1183. /**
  1184.   * @brief  Transmission  complete callback in non blocking mode
  1185.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1186.   *         the configuration information for the specified CAN.
  1187.   * @retval None
  1188.   */
  1189. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
  1190. {
  1191.   /* Prevent unused argument(s) compilation warning */
  1192.   UNUSED(hcan);
  1193.   /* NOTE : This function Should not be modified, when the callback is needed,
  1194.             the HAL_CAN_TxCpltCallback can be implemented in the user file
  1195.    */
  1196. }
  1197.  
  1198. /**
  1199.   * @brief  Transmission  complete callback in non blocking mode
  1200.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1201.   *         the configuration information for the specified CAN.
  1202.   * @retval None
  1203.   */
  1204. __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  1205. {
  1206.   /* Prevent unused argument(s) compilation warning */
  1207.   UNUSED(hcan);
  1208.   /* NOTE : This function Should not be modified, when the callback is needed,
  1209.             the HAL_CAN_RxCpltCallback can be implemented in the user file
  1210.    */
  1211. }
  1212.  
  1213. /**
  1214.   * @brief  Error CAN callback.
  1215.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1216.   *         the configuration information for the specified CAN.
  1217.   * @retval None
  1218.   */
  1219. __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  1220. {
  1221.   /* Prevent unused argument(s) compilation warning */
  1222.   UNUSED(hcan);
  1223.   /* NOTE : This function Should not be modified, when the callback is needed,
  1224.             the HAL_CAN_ErrorCallback can be implemented in the user file
  1225.    */
  1226. }
  1227.  
  1228. /**
  1229.   * @}
  1230.   */
  1231.  
  1232. /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
  1233.  *  @brief   CAN Peripheral State functions
  1234.  *
  1235. @verbatim  
  1236.   ==============================================================================
  1237.             ##### Peripheral State and Error functions #####
  1238.   ==============================================================================
  1239.     [..]
  1240.     This subsection provides functions allowing to :
  1241.       (+) Check the CAN state.
  1242.       (+) Check CAN Errors detected during interrupt process
  1243.          
  1244. @endverbatim
  1245.   * @{
  1246.   */
  1247.  
  1248. /**
  1249.   * @brief  return the CAN state
  1250.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1251.   *         the configuration information for the specified CAN.
  1252.   * @retval HAL state
  1253.   */
  1254. HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
  1255. {
  1256.   /* Return CAN state */
  1257.   return hcan->State;
  1258. }
  1259.  
  1260. /**
  1261.   * @brief  Return the CAN error code
  1262.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1263.   *         the configuration information for the specified CAN.
  1264.   * @retval CAN Error Code
  1265.   */
  1266. uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
  1267. {
  1268.   return hcan->ErrorCode;
  1269. }
  1270.  
  1271. /**
  1272.   * @}
  1273.   */
  1274.  
  1275. /**
  1276.   * @}
  1277.   */
  1278.  
  1279. /** @defgroup CAN_Private_Functions CAN Private Functions
  1280.  * @{
  1281.  */
  1282. /**
  1283.   * @brief  Initiates and transmits a CAN frame message.
  1284.   * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  1285.   *         the configuration information for the specified CAN.  
  1286.   * @retval HAL status
  1287.   */
  1288. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  1289. {
  1290.   /* Disable Transmit mailbox empty Interrupt */
  1291.   __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
  1292.  
  1293.   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  1294.   {  
  1295.     /* Disable interrupts: */
  1296.     /*  - Disable Error warning Interrupt */
  1297.     /*  - Disable Error passive Interrupt */
  1298.     /*  - Disable Bus-off Interrupt */
  1299.     /*  - Disable Last error code Interrupt */
  1300.     /*  - Disable Error Interrupt */
  1301.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1302.                                CAN_IT_EPV |
  1303.                                CAN_IT_BOF |
  1304.                                CAN_IT_LEC |
  1305.                                CAN_IT_ERR  );
  1306.   }
  1307.  
  1308.   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  1309.   {
  1310.     /* Change CAN state */
  1311.     hcan->State = HAL_CAN_STATE_BUSY_RX;
  1312.   }
  1313.   else
  1314.   {
  1315.     /* Change CAN state */
  1316.     hcan->State = HAL_CAN_STATE_READY;
  1317.   }
  1318.  
  1319.   /* Transmission complete callback */
  1320.   HAL_CAN_TxCpltCallback(hcan);
  1321.  
  1322.   return HAL_OK;
  1323. }
  1324.  
  1325. /**
  1326.   * @brief  Receives a correct CAN frame.
  1327.   * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
  1328.   *         the configuration information for the specified CAN.  
  1329.   * @param  FIFONumber: Specify the FIFO number    
  1330.   * @retval HAL status
  1331.   * @retval None
  1332.   */
  1333. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  1334. {
  1335.   /* Get the Id */
  1336.   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1337.   if (hcan->pRxMsg->IDE == CAN_ID_STD)
  1338.   {
  1339.     hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
  1340.   }
  1341.   else
  1342.   {
  1343.     hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
  1344.   }
  1345.  
  1346.   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1347.   /* Get the DLC */
  1348.   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  1349.   /* Get the FMI */
  1350.   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
  1351.   /* Get the data field */
  1352.   hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  1353.   hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
  1354.   hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
  1355.   hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
  1356.   hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  1357.   hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
  1358.   hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
  1359.   hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
  1360.   /* Release the FIFO */
  1361.   /* Release FIFO0 */
  1362.   if (FIFONumber == CAN_FIFO0)
  1363.   {
  1364.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  1365.    
  1366.     /* Disable FIFO 0 message pending Interrupt */
  1367.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
  1368.   }
  1369.   /* Release FIFO1 */
  1370.   else /* FIFONumber == CAN_FIFO1 */
  1371.   {
  1372.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  1373.    
  1374.     /* Disable FIFO 1 message pending Interrupt */
  1375.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
  1376.   }
  1377.  
  1378.   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  1379.   {
  1380.     /* Disable interrupts: */
  1381.     /*  - Disable Error warning Interrupt */
  1382.     /*  - Disable Error passive Interrupt */
  1383.     /*  - Disable Bus-off Interrupt */
  1384.     /*  - Disable Last error code Interrupt */
  1385.     /*  - Disable Error Interrupt */
  1386.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1387.                                CAN_IT_EPV |
  1388.                                CAN_IT_BOF |
  1389.                                CAN_IT_LEC |
  1390.                                CAN_IT_ERR  );
  1391.   }
  1392.  
  1393.   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  1394.   {
  1395.     /* Disable CAN state */
  1396.     hcan->State = HAL_CAN_STATE_BUSY_TX;
  1397.   }
  1398.   else
  1399.   {
  1400.     /* Change CAN state */
  1401.     hcan->State = HAL_CAN_STATE_READY;
  1402.   }
  1403.  
  1404.   /* Receive complete callback */
  1405.   HAL_CAN_RxCpltCallback(hcan);
  1406.  
  1407.   /* Return function status */
  1408.   return HAL_OK;
  1409. }
  1410.  
  1411. /**
  1412.  * @}
  1413.  */
  1414.  
  1415. /**
  1416.   * @}
  1417.   */
  1418.  
  1419. #endif /* STM32F103x6) || STM32F103xB || STM32F103xE || */
  1420.        /* STM32F103xG) || STM32F105xC || STM32F107xC    */
  1421.  
  1422. #endif /* HAL_CAN_MODULE_ENABLED */
  1423.  
  1424. /**
  1425.   * @}
  1426.   */
  1427.  
  1428. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1429.