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