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.
Fork of TUKS-COURSE-TIMER by
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 17:38:49 by
