001

Committer:
ganlikun
Date:
Sun Jun 12 14:02:44 2022 +0000
Revision:
0:13413ea9a877
00

Who changed what in which revision?

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