STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_uart.c 00004 * @author MCD Application Team 00005 * @brief UART HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * 00012 * 00013 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2017 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 =============================================================================== 00026 ##### How to use this driver ##### 00027 =============================================================================== 00028 [..] 00029 The UART HAL driver can be used as follows: 00030 00031 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). 00032 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: 00033 (++) Enable the USARTx interface clock. 00034 (++) UART pins configuration: 00035 (+++) Enable the clock for the UART GPIOs. 00036 (+++) Configure these UART pins as alternate function pull-up. 00037 (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() 00038 and HAL_UART_Receive_IT() APIs): 00039 (+++) Configure the USARTx interrupt priority. 00040 (+++) Enable the NVIC USART IRQ handle. 00041 (++) UART interrupts handling: 00042 -@@- The specific UART interrupts (Transmission complete interrupt, 00043 RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts) 00044 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() 00045 inside the transmit and receive processes. 00046 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() 00047 and HAL_UART_Receive_DMA() APIs): 00048 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00049 (+++) Enable the DMAx interface clock. 00050 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00051 (+++) Configure the DMA Tx/Rx channel. 00052 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. 00053 (+++) Configure the priority and enable the NVIC for the transfer complete 00054 interrupt on the DMA Tx/Rx channel. 00055 00056 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware 00057 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. 00058 00059 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) 00060 in the huart handle AdvancedInit structure. 00061 00062 (#) For the UART asynchronous mode, initialize the UART registers by calling 00063 the HAL_UART_Init() API. 00064 00065 (#) For the UART Half duplex mode, initialize the UART registers by calling 00066 the HAL_HalfDuplex_Init() API. 00067 00068 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers 00069 by calling the HAL_LIN_Init() API. 00070 00071 (#) For the UART Multiprocessor mode, initialize the UART registers 00072 by calling the HAL_MultiProcessor_Init() API. 00073 00074 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers 00075 by calling the HAL_RS485Ex_Init() API. 00076 00077 [..] 00078 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), 00079 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by 00080 calling the customized HAL_UART_MspInit() API. 00081 00082 ##### Callback registration ##### 00083 ================================== 00084 00085 [..] 00086 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1 00087 allows the user to configure dynamically the driver callbacks. 00088 00089 [..] 00090 Use Function HAL_UART_RegisterCallback() to register a user callback. 00091 Function HAL_UART_RegisterCallback() allows to register following callbacks: 00092 (+) TxHalfCpltCallback : Tx Half Complete Callback. 00093 (+) TxCpltCallback : Tx Complete Callback. 00094 (+) RxHalfCpltCallback : Rx Half Complete Callback. 00095 (+) RxCpltCallback : Rx Complete Callback. 00096 (+) ErrorCallback : Error Callback. 00097 (+) AbortCpltCallback : Abort Complete Callback. 00098 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 00099 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 00100 (+) WakeupCallback : Wakeup Callback. 00101 #if defined(USART_CR1_FIFOEN) 00102 (+) RxFifoFullCallback : Rx Fifo Full Callback. 00103 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. 00104 #endif 00105 (+) MspInitCallback : UART MspInit. 00106 (+) MspDeInitCallback : UART MspDeInit. 00107 This function takes as parameters the HAL peripheral handle, the Callback ID 00108 and a pointer to the user callback function. 00109 00110 [..] 00111 Use function HAL_UART_UnRegisterCallback() to reset a callback to the default 00112 weak (surcharged) function. 00113 HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00114 and the Callback ID. 00115 This function allows to reset following callbacks: 00116 (+) TxHalfCpltCallback : Tx Half Complete Callback. 00117 (+) TxCpltCallback : Tx Complete Callback. 00118 (+) RxHalfCpltCallback : Rx Half Complete Callback. 00119 (+) RxCpltCallback : Rx Complete Callback. 00120 (+) ErrorCallback : Error Callback. 00121 (+) AbortCpltCallback : Abort Complete Callback. 00122 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 00123 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 00124 (+) WakeupCallback : Wakeup Callback. 00125 #if defined(USART_CR1_FIFOEN) 00126 (+) RxFifoFullCallback : Rx Fifo Full Callback. 00127 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. 00128 #endif 00129 (+) MspInitCallback : UART MspInit. 00130 (+) MspDeInitCallback : UART MspDeInit. 00131 00132 [..] 00133 For specific callback RxEventCallback, use dedicated registration/reset functions: 00134 respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback(). 00135 00136 [..] 00137 By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET 00138 all callbacks are set to the corresponding weak (surcharged) functions: 00139 examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback(). 00140 Exception done for MspInit and MspDeInit functions that are respectively 00141 reset to the legacy weak (surcharged) functions in the HAL_UART_Init() 00142 and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). 00143 If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit() 00144 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00145 00146 [..] 00147 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only. 00148 Exception done MspInit/MspDeInit that can be registered/unregistered 00149 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user) 00150 MspInit/DeInit callbacks can be used during the Init/DeInit. 00151 In that case first register the MspInit/MspDeInit user callbacks 00152 using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit() 00153 or HAL_UART_Init() function. 00154 00155 [..] 00156 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or 00157 not defined, the callback registration feature is not available 00158 and weak (surcharged) callbacks are used. 00159 00160 00161 @endverbatim 00162 ****************************************************************************** 00163 */ 00164 00165 /* Includes ------------------------------------------------------------------*/ 00166 #include "stm32l4xx_hal.h" 00167 00168 /** @addtogroup STM32L4xx_HAL_Driver 00169 * @{ 00170 */ 00171 00172 /** @defgroup UART UART 00173 * @brief HAL UART module driver 00174 * @{ 00175 */ 00176 00177 #ifdef HAL_UART_MODULE_ENABLED 00178 00179 /* Private typedef -----------------------------------------------------------*/ 00180 /* Private define ------------------------------------------------------------*/ 00181 /** @defgroup UART_Private_Constants UART Private Constants 00182 * @{ 00183 */ 00184 #if defined(USART_CR1_FIFOEN) 00185 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ 00186 USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ 00187 #else 00188 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ 00189 USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ 00190 #endif /* USART_CR1_FIFOEN */ 00191 00192 #if defined(USART_CR1_FIFOEN) 00193 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \ 00194 USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ 00195 #else 00196 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE |\ 00197 USART_CR3_ONEBIT)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ 00198 #endif /* USART_CR1_FIFOEN */ 00199 00200 #define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */ 00201 #define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */ 00202 00203 #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */ 00204 #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */ 00205 /** 00206 * @} 00207 */ 00208 00209 /* Private macros ------------------------------------------------------------*/ 00210 /* Private function prototypes -----------------------------------------------*/ 00211 /** @addtogroup UART_Private_Functions 00212 * @{ 00213 */ 00214 static void UART_EndTxTransfer(UART_HandleTypeDef *huart); 00215 static void UART_EndRxTransfer(UART_HandleTypeDef *huart); 00216 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00217 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00218 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00219 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00220 static void UART_DMAError(DMA_HandleTypeDef *hdma); 00221 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); 00222 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); 00223 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); 00224 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 00225 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 00226 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart); 00227 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart); 00228 #if defined(USART_CR1_FIFOEN) 00229 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); 00230 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); 00231 #endif /* USART_CR1_FIFOEN */ 00232 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart); 00233 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart); 00234 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart); 00235 #if defined(USART_CR1_FIFOEN) 00236 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); 00237 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); 00238 #endif /* USART_CR1_FIFOEN */ 00239 /** 00240 * @} 00241 */ 00242 00243 /* Private variables ---------------------------------------------------------*/ 00244 #if defined(USART_PRESC_PRESCALER) 00245 /** @addtogroup UART_Private_variables 00246 * @{ 00247 */ 00248 const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; 00249 /** 00250 * @} 00251 */ 00252 00253 #endif /* USART_PRESC_PRESCALER */ 00254 /* Exported Constants --------------------------------------------------------*/ 00255 /* Exported functions --------------------------------------------------------*/ 00256 00257 /** @defgroup UART_Exported_Functions UART Exported Functions 00258 * @{ 00259 */ 00260 00261 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions 00262 * @brief Initialization and Configuration functions 00263 * 00264 @verbatim 00265 =============================================================================== 00266 ##### Initialization and Configuration functions ##### 00267 =============================================================================== 00268 [..] 00269 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 00270 in asynchronous mode. 00271 (+) For the asynchronous mode the parameters below can be configured: 00272 (++) Baud Rate 00273 (++) Word Length 00274 (++) Stop Bit 00275 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00276 in the data register is transmitted but is changed by the parity bit. 00277 (++) Hardware flow control 00278 (++) Receiver/transmitter modes 00279 (++) Over Sampling Method 00280 (++) One-Bit Sampling Method 00281 (+) For the asynchronous mode, the following advanced features can be configured as well: 00282 (++) TX and/or RX pin level inversion 00283 (++) data logical level inversion 00284 (++) RX and TX pins swap 00285 (++) RX overrun detection disabling 00286 (++) DMA disabling on RX error 00287 (++) MSB first on communication line 00288 (++) auto Baud rate detection 00289 [..] 00290 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API 00291 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode 00292 and UART multiprocessor mode configuration procedures (details for the procedures 00293 are available in reference manual). 00294 00295 @endverbatim 00296 00297 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00298 8-bit or 9-bit), the possible UART formats are listed in the 00299 following table. 00300 00301 Table 1. UART frame format. 00302 +-----------------------------------------------------------------------+ 00303 | M1 bit | M0 bit | PCE bit | UART frame | 00304 |---------|---------|-----------|---------------------------------------| 00305 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00306 |---------|---------|-----------|---------------------------------------| 00307 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00308 |---------|---------|-----------|---------------------------------------| 00309 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00310 |---------|---------|-----------|---------------------------------------| 00311 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00312 |---------|---------|-----------|---------------------------------------| 00313 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00314 |---------|---------|-----------|---------------------------------------| 00315 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00316 +-----------------------------------------------------------------------+ 00317 00318 * @{ 00319 */ 00320 00321 /** 00322 * @brief Initialize the UART mode according to the specified 00323 * parameters in the UART_InitTypeDef and initialize the associated handle. 00324 * @param huart UART handle. 00325 * @retval HAL status 00326 */ 00327 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) 00328 { 00329 /* Check the UART handle allocation */ 00330 if (huart == NULL) 00331 { 00332 return HAL_ERROR; 00333 } 00334 00335 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) 00336 { 00337 /* Check the parameters */ 00338 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); 00339 } 00340 else 00341 { 00342 /* Check the parameters */ 00343 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); 00344 } 00345 00346 if (huart->gState == HAL_UART_STATE_RESET) 00347 { 00348 /* Allocate lock resource and initialize it */ 00349 huart->Lock = HAL_UNLOCKED; 00350 00351 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00352 UART_InitCallbacksToDefault(huart); 00353 00354 if (huart->MspInitCallback == NULL) 00355 { 00356 huart->MspInitCallback = HAL_UART_MspInit; 00357 } 00358 00359 /* Init the low level hardware */ 00360 huart->MspInitCallback(huart); 00361 #else 00362 /* Init the low level hardware : GPIO, CLOCK */ 00363 HAL_UART_MspInit(huart); 00364 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00365 } 00366 00367 huart->gState = HAL_UART_STATE_BUSY; 00368 00369 __HAL_UART_DISABLE(huart); 00370 00371 /* Set the UART Communication parameters */ 00372 if (UART_SetConfig(huart) == HAL_ERROR) 00373 { 00374 return HAL_ERROR; 00375 } 00376 00377 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00378 { 00379 UART_AdvFeatureConfig(huart); 00380 } 00381 00382 /* In asynchronous mode, the following bits must be kept cleared: 00383 - LINEN and CLKEN bits in the USART_CR2 register, 00384 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ 00385 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 00386 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); 00387 00388 __HAL_UART_ENABLE(huart); 00389 00390 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00391 return (UART_CheckIdleState(huart)); 00392 } 00393 00394 /** 00395 * @brief Initialize the half-duplex mode according to the specified 00396 * parameters in the UART_InitTypeDef and creates the associated handle. 00397 * @param huart UART handle. 00398 * @retval HAL status 00399 */ 00400 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) 00401 { 00402 /* Check the UART handle allocation */ 00403 if (huart == NULL) 00404 { 00405 return HAL_ERROR; 00406 } 00407 00408 /* Check UART instance */ 00409 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); 00410 00411 if (huart->gState == HAL_UART_STATE_RESET) 00412 { 00413 /* Allocate lock resource and initialize it */ 00414 huart->Lock = HAL_UNLOCKED; 00415 00416 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00417 UART_InitCallbacksToDefault(huart); 00418 00419 if (huart->MspInitCallback == NULL) 00420 { 00421 huart->MspInitCallback = HAL_UART_MspInit; 00422 } 00423 00424 /* Init the low level hardware */ 00425 huart->MspInitCallback(huart); 00426 #else 00427 /* Init the low level hardware : GPIO, CLOCK */ 00428 HAL_UART_MspInit(huart); 00429 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00430 } 00431 00432 huart->gState = HAL_UART_STATE_BUSY; 00433 00434 __HAL_UART_DISABLE(huart); 00435 00436 /* Set the UART Communication parameters */ 00437 if (UART_SetConfig(huart) == HAL_ERROR) 00438 { 00439 return HAL_ERROR; 00440 } 00441 00442 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00443 { 00444 UART_AdvFeatureConfig(huart); 00445 } 00446 00447 /* In half-duplex mode, the following bits must be kept cleared: 00448 - LINEN and CLKEN bits in the USART_CR2 register, 00449 - SCEN and IREN bits in the USART_CR3 register.*/ 00450 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 00451 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); 00452 00453 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ 00454 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); 00455 00456 __HAL_UART_ENABLE(huart); 00457 00458 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00459 return (UART_CheckIdleState(huart)); 00460 } 00461 00462 00463 /** 00464 * @brief Initialize the LIN mode according to the specified 00465 * parameters in the UART_InitTypeDef and creates the associated handle. 00466 * @param huart UART handle. 00467 * @param BreakDetectLength Specifies the LIN break detection length. 00468 * This parameter can be one of the following values: 00469 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection 00470 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection 00471 * @retval HAL status 00472 */ 00473 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) 00474 { 00475 /* Check the UART handle allocation */ 00476 if (huart == NULL) 00477 { 00478 return HAL_ERROR; 00479 } 00480 00481 /* Check the LIN UART instance */ 00482 assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); 00483 /* Check the Break detection length parameter */ 00484 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); 00485 00486 /* LIN mode limited to 16-bit oversampling only */ 00487 if (huart->Init.OverSampling == UART_OVERSAMPLING_8) 00488 { 00489 return HAL_ERROR; 00490 } 00491 /* LIN mode limited to 8-bit data length */ 00492 if (huart->Init.WordLength != UART_WORDLENGTH_8B) 00493 { 00494 return HAL_ERROR; 00495 } 00496 00497 if (huart->gState == HAL_UART_STATE_RESET) 00498 { 00499 /* Allocate lock resource and initialize it */ 00500 huart->Lock = HAL_UNLOCKED; 00501 00502 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00503 UART_InitCallbacksToDefault(huart); 00504 00505 if (huart->MspInitCallback == NULL) 00506 { 00507 huart->MspInitCallback = HAL_UART_MspInit; 00508 } 00509 00510 /* Init the low level hardware */ 00511 huart->MspInitCallback(huart); 00512 #else 00513 /* Init the low level hardware : GPIO, CLOCK */ 00514 HAL_UART_MspInit(huart); 00515 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00516 } 00517 00518 huart->gState = HAL_UART_STATE_BUSY; 00519 00520 __HAL_UART_DISABLE(huart); 00521 00522 /* Set the UART Communication parameters */ 00523 if (UART_SetConfig(huart) == HAL_ERROR) 00524 { 00525 return HAL_ERROR; 00526 } 00527 00528 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00529 { 00530 UART_AdvFeatureConfig(huart); 00531 } 00532 00533 /* In LIN mode, the following bits must be kept cleared: 00534 - LINEN and CLKEN bits in the USART_CR2 register, 00535 - SCEN and IREN bits in the USART_CR3 register.*/ 00536 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN); 00537 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); 00538 00539 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ 00540 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); 00541 00542 /* Set the USART LIN Break detection length. */ 00543 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength); 00544 00545 __HAL_UART_ENABLE(huart); 00546 00547 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00548 return (UART_CheckIdleState(huart)); 00549 } 00550 00551 00552 /** 00553 * @brief Initialize the multiprocessor mode according to the specified 00554 * parameters in the UART_InitTypeDef and initialize the associated handle. 00555 * @param huart UART handle. 00556 * @param Address UART node address (4-, 6-, 7- or 8-bit long). 00557 * @param WakeUpMethod Specifies the UART wakeup method. 00558 * This parameter can be one of the following values: 00559 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection 00560 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark 00561 * @note If the user resorts to idle line detection wake up, the Address parameter 00562 * is useless and ignored by the initialization function. 00563 * @note If the user resorts to address mark wake up, the address length detection 00564 * is configured by default to 4 bits only. For the UART to be able to 00565 * manage 6-, 7- or 8-bit long addresses detection, the API 00566 * HAL_MultiProcessorEx_AddressLength_Set() must be called after 00567 * HAL_MultiProcessor_Init(). 00568 * @retval HAL status 00569 */ 00570 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) 00571 { 00572 /* Check the UART handle allocation */ 00573 if (huart == NULL) 00574 { 00575 return HAL_ERROR; 00576 } 00577 00578 /* Check the wake up method parameter */ 00579 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); 00580 00581 if (huart->gState == HAL_UART_STATE_RESET) 00582 { 00583 /* Allocate lock resource and initialize it */ 00584 huart->Lock = HAL_UNLOCKED; 00585 00586 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00587 UART_InitCallbacksToDefault(huart); 00588 00589 if (huart->MspInitCallback == NULL) 00590 { 00591 huart->MspInitCallback = HAL_UART_MspInit; 00592 } 00593 00594 /* Init the low level hardware */ 00595 huart->MspInitCallback(huart); 00596 #else 00597 /* Init the low level hardware : GPIO, CLOCK */ 00598 HAL_UART_MspInit(huart); 00599 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00600 } 00601 00602 huart->gState = HAL_UART_STATE_BUSY; 00603 00604 __HAL_UART_DISABLE(huart); 00605 00606 /* Set the UART Communication parameters */ 00607 if (UART_SetConfig(huart) == HAL_ERROR) 00608 { 00609 return HAL_ERROR; 00610 } 00611 00612 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00613 { 00614 UART_AdvFeatureConfig(huart); 00615 } 00616 00617 /* In multiprocessor mode, the following bits must be kept cleared: 00618 - LINEN and CLKEN bits in the USART_CR2 register, 00619 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ 00620 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); 00621 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); 00622 00623 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) 00624 { 00625 /* If address mark wake up method is chosen, set the USART address node */ 00626 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); 00627 } 00628 00629 /* Set the wake up method by setting the WAKE bit in the CR1 register */ 00630 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); 00631 00632 __HAL_UART_ENABLE(huart); 00633 00634 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00635 return (UART_CheckIdleState(huart)); 00636 } 00637 00638 00639 /** 00640 * @brief DeInitialize the UART peripheral. 00641 * @param huart UART handle. 00642 * @retval HAL status 00643 */ 00644 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) 00645 { 00646 /* Check the UART handle allocation */ 00647 if (huart == NULL) 00648 { 00649 return HAL_ERROR; 00650 } 00651 00652 /* Check the parameters */ 00653 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); 00654 00655 huart->gState = HAL_UART_STATE_BUSY; 00656 00657 __HAL_UART_DISABLE(huart); 00658 00659 huart->Instance->CR1 = 0x0U; 00660 huart->Instance->CR2 = 0x0U; 00661 huart->Instance->CR3 = 0x0U; 00662 00663 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00664 if (huart->MspDeInitCallback == NULL) 00665 { 00666 huart->MspDeInitCallback = HAL_UART_MspDeInit; 00667 } 00668 /* DeInit the low level hardware */ 00669 huart->MspDeInitCallback(huart); 00670 #else 00671 /* DeInit the low level hardware */ 00672 HAL_UART_MspDeInit(huart); 00673 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00674 00675 huart->ErrorCode = HAL_UART_ERROR_NONE; 00676 huart->gState = HAL_UART_STATE_RESET; 00677 huart->RxState = HAL_UART_STATE_RESET; 00678 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 00679 00680 __HAL_UNLOCK(huart); 00681 00682 return HAL_OK; 00683 } 00684 00685 /** 00686 * @brief Initialize the UART MSP. 00687 * @param huart UART handle. 00688 * @retval None 00689 */ 00690 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) 00691 { 00692 /* Prevent unused argument(s) compilation warning */ 00693 UNUSED(huart); 00694 00695 /* NOTE : This function should not be modified, when the callback is needed, 00696 the HAL_UART_MspInit can be implemented in the user file 00697 */ 00698 } 00699 00700 /** 00701 * @brief DeInitialize the UART MSP. 00702 * @param huart UART handle. 00703 * @retval None 00704 */ 00705 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) 00706 { 00707 /* Prevent unused argument(s) compilation warning */ 00708 UNUSED(huart); 00709 00710 /* NOTE : This function should not be modified, when the callback is needed, 00711 the HAL_UART_MspDeInit can be implemented in the user file 00712 */ 00713 } 00714 00715 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00716 /** 00717 * @brief Register a User UART Callback 00718 * To be used instead of the weak predefined callback 00719 * @param huart uart handle 00720 * @param CallbackID ID of the callback to be registered 00721 * This parameter can be one of the following values: 00722 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 00723 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID 00724 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 00725 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID 00726 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID 00727 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 00728 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 00729 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 00730 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID 00731 #if defined(USART_CR1_FIFOEN) 00732 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID 00733 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID 00734 #endif 00735 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID 00736 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID 00737 * @param pCallback pointer to the Callback function 00738 * @retval HAL status 00739 */ 00740 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, 00741 pUART_CallbackTypeDef pCallback) 00742 { 00743 HAL_StatusTypeDef status = HAL_OK; 00744 00745 if (pCallback == NULL) 00746 { 00747 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00748 00749 return HAL_ERROR; 00750 } 00751 00752 __HAL_LOCK(huart); 00753 00754 if (huart->gState == HAL_UART_STATE_READY) 00755 { 00756 switch (CallbackID) 00757 { 00758 case HAL_UART_TX_HALFCOMPLETE_CB_ID : 00759 huart->TxHalfCpltCallback = pCallback; 00760 break; 00761 00762 case HAL_UART_TX_COMPLETE_CB_ID : 00763 huart->TxCpltCallback = pCallback; 00764 break; 00765 00766 case HAL_UART_RX_HALFCOMPLETE_CB_ID : 00767 huart->RxHalfCpltCallback = pCallback; 00768 break; 00769 00770 case HAL_UART_RX_COMPLETE_CB_ID : 00771 huart->RxCpltCallback = pCallback; 00772 break; 00773 00774 case HAL_UART_ERROR_CB_ID : 00775 huart->ErrorCallback = pCallback; 00776 break; 00777 00778 case HAL_UART_ABORT_COMPLETE_CB_ID : 00779 huart->AbortCpltCallback = pCallback; 00780 break; 00781 00782 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : 00783 huart->AbortTransmitCpltCallback = pCallback; 00784 break; 00785 00786 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : 00787 huart->AbortReceiveCpltCallback = pCallback; 00788 break; 00789 00790 case HAL_UART_WAKEUP_CB_ID : 00791 huart->WakeupCallback = pCallback; 00792 break; 00793 00794 #if defined(USART_CR1_FIFOEN) 00795 case HAL_UART_RX_FIFO_FULL_CB_ID : 00796 huart->RxFifoFullCallback = pCallback; 00797 break; 00798 00799 case HAL_UART_TX_FIFO_EMPTY_CB_ID : 00800 huart->TxFifoEmptyCallback = pCallback; 00801 break; 00802 #endif /* USART_CR1_FIFOEN */ 00803 00804 case HAL_UART_MSPINIT_CB_ID : 00805 huart->MspInitCallback = pCallback; 00806 break; 00807 00808 case HAL_UART_MSPDEINIT_CB_ID : 00809 huart->MspDeInitCallback = pCallback; 00810 break; 00811 00812 default : 00813 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00814 00815 status = HAL_ERROR; 00816 break; 00817 } 00818 } 00819 else if (huart->gState == HAL_UART_STATE_RESET) 00820 { 00821 switch (CallbackID) 00822 { 00823 case HAL_UART_MSPINIT_CB_ID : 00824 huart->MspInitCallback = pCallback; 00825 break; 00826 00827 case HAL_UART_MSPDEINIT_CB_ID : 00828 huart->MspDeInitCallback = pCallback; 00829 break; 00830 00831 default : 00832 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00833 00834 status = HAL_ERROR; 00835 break; 00836 } 00837 } 00838 else 00839 { 00840 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00841 00842 status = HAL_ERROR; 00843 } 00844 00845 __HAL_UNLOCK(huart); 00846 00847 return status; 00848 } 00849 00850 /** 00851 * @brief Unregister an UART Callback 00852 * UART callaback is redirected to the weak predefined callback 00853 * @param huart uart handle 00854 * @param CallbackID ID of the callback to be unregistered 00855 * This parameter can be one of the following values: 00856 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 00857 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID 00858 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 00859 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID 00860 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID 00861 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 00862 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 00863 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 00864 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID 00865 #if defined(USART_CR1_FIFOEN) 00866 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID 00867 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID 00868 #endif 00869 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID 00870 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID 00871 * @retval HAL status 00872 */ 00873 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID) 00874 { 00875 HAL_StatusTypeDef status = HAL_OK; 00876 00877 __HAL_LOCK(huart); 00878 00879 if (HAL_UART_STATE_READY == huart->gState) 00880 { 00881 switch (CallbackID) 00882 { 00883 case HAL_UART_TX_HALFCOMPLETE_CB_ID : 00884 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 00885 break; 00886 00887 case HAL_UART_TX_COMPLETE_CB_ID : 00888 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00889 break; 00890 00891 case HAL_UART_RX_HALFCOMPLETE_CB_ID : 00892 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 00893 break; 00894 00895 case HAL_UART_RX_COMPLETE_CB_ID : 00896 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ 00897 break; 00898 00899 case HAL_UART_ERROR_CB_ID : 00900 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ 00901 break; 00902 00903 case HAL_UART_ABORT_COMPLETE_CB_ID : 00904 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 00905 break; 00906 00907 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : 00908 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak 00909 AbortTransmitCpltCallback */ 00910 break; 00911 00912 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : 00913 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak 00914 AbortReceiveCpltCallback */ 00915 break; 00916 00917 case HAL_UART_WAKEUP_CB_ID : 00918 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ 00919 break; 00920 00921 #if defined(USART_CR1_FIFOEN) 00922 case HAL_UART_RX_FIFO_FULL_CB_ID : 00923 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ 00924 break; 00925 00926 case HAL_UART_TX_FIFO_EMPTY_CB_ID : 00927 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ 00928 break; 00929 00930 #endif /* USART_CR1_FIFOEN */ 00931 case HAL_UART_MSPINIT_CB_ID : 00932 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ 00933 break; 00934 00935 case HAL_UART_MSPDEINIT_CB_ID : 00936 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ 00937 break; 00938 00939 default : 00940 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00941 00942 status = HAL_ERROR; 00943 break; 00944 } 00945 } 00946 else if (HAL_UART_STATE_RESET == huart->gState) 00947 { 00948 switch (CallbackID) 00949 { 00950 case HAL_UART_MSPINIT_CB_ID : 00951 huart->MspInitCallback = HAL_UART_MspInit; 00952 break; 00953 00954 case HAL_UART_MSPDEINIT_CB_ID : 00955 huart->MspDeInitCallback = HAL_UART_MspDeInit; 00956 break; 00957 00958 default : 00959 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00960 00961 status = HAL_ERROR; 00962 break; 00963 } 00964 } 00965 else 00966 { 00967 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00968 00969 status = HAL_ERROR; 00970 } 00971 00972 __HAL_UNLOCK(huart); 00973 00974 return status; 00975 } 00976 00977 /** 00978 * @brief Register a User UART Rx Event Callback 00979 * To be used instead of the weak predefined callback 00980 * @param huart Uart handle 00981 * @param pCallback Pointer to the Rx Event Callback function 00982 * @retval HAL status 00983 */ 00984 HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback) 00985 { 00986 HAL_StatusTypeDef status = HAL_OK; 00987 00988 if (pCallback == NULL) 00989 { 00990 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 00991 00992 return HAL_ERROR; 00993 } 00994 00995 /* Process locked */ 00996 __HAL_LOCK(huart); 00997 00998 if (huart->gState == HAL_UART_STATE_READY) 00999 { 01000 huart->RxEventCallback = pCallback; 01001 } 01002 else 01003 { 01004 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 01005 01006 status = HAL_ERROR; 01007 } 01008 01009 /* Release Lock */ 01010 __HAL_UNLOCK(huart); 01011 01012 return status; 01013 } 01014 01015 /** 01016 * @brief UnRegister the UART Rx Event Callback 01017 * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback 01018 * @param huart Uart handle 01019 * @retval HAL status 01020 */ 01021 HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart) 01022 { 01023 HAL_StatusTypeDef status = HAL_OK; 01024 01025 /* Process locked */ 01026 __HAL_LOCK(huart); 01027 01028 if (huart->gState == HAL_UART_STATE_READY) 01029 { 01030 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */ 01031 } 01032 else 01033 { 01034 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; 01035 01036 status = HAL_ERROR; 01037 } 01038 01039 /* Release Lock */ 01040 __HAL_UNLOCK(huart); 01041 return status; 01042 } 01043 01044 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 01045 01046 /** 01047 * @} 01048 */ 01049 01050 /** @defgroup UART_Exported_Functions_Group2 IO operation functions 01051 * @brief UART Transmit/Receive functions 01052 * 01053 @verbatim 01054 =============================================================================== 01055 ##### IO operation functions ##### 01056 =============================================================================== 01057 This subsection provides a set of functions allowing to manage the UART asynchronous 01058 and Half duplex data transfers. 01059 01060 (#) There are two mode of transfer: 01061 (+) Blocking mode: The communication is performed in polling mode. 01062 The HAL status of all data processing is returned by the same function 01063 after finishing transfer. 01064 (+) Non-Blocking mode: The communication is performed using Interrupts 01065 or DMA, These API's return the HAL status. 01066 The end of the data processing will be indicated through the 01067 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when 01068 using DMA mode. 01069 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks 01070 will be executed respectively at the end of the transmit or Receive process 01071 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected 01072 01073 (#) Blocking mode API's are : 01074 (+) HAL_UART_Transmit() 01075 (+) HAL_UART_Receive() 01076 01077 (#) Non-Blocking mode API's with Interrupt are : 01078 (+) HAL_UART_Transmit_IT() 01079 (+) HAL_UART_Receive_IT() 01080 (+) HAL_UART_IRQHandler() 01081 01082 (#) Non-Blocking mode API's with DMA are : 01083 (+) HAL_UART_Transmit_DMA() 01084 (+) HAL_UART_Receive_DMA() 01085 (+) HAL_UART_DMAPause() 01086 (+) HAL_UART_DMAResume() 01087 (+) HAL_UART_DMAStop() 01088 01089 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: 01090 (+) HAL_UART_TxHalfCpltCallback() 01091 (+) HAL_UART_TxCpltCallback() 01092 (+) HAL_UART_RxHalfCpltCallback() 01093 (+) HAL_UART_RxCpltCallback() 01094 (+) HAL_UART_ErrorCallback() 01095 01096 (#) Non-Blocking mode transfers could be aborted using Abort API's : 01097 (+) HAL_UART_Abort() 01098 (+) HAL_UART_AbortTransmit() 01099 (+) HAL_UART_AbortReceive() 01100 (+) HAL_UART_Abort_IT() 01101 (+) HAL_UART_AbortTransmit_IT() 01102 (+) HAL_UART_AbortReceive_IT() 01103 01104 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided: 01105 (+) HAL_UART_AbortCpltCallback() 01106 (+) HAL_UART_AbortTransmitCpltCallback() 01107 (+) HAL_UART_AbortReceiveCpltCallback() 01108 01109 (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced 01110 reception services: 01111 (+) HAL_UARTEx_RxEventCallback() 01112 01113 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. 01114 Errors are handled as follows : 01115 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 01116 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error 01117 in Interrupt mode reception . 01118 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user 01119 to identify error type, and HAL_UART_ErrorCallback() user callback is executed. 01120 Transfer is kept ongoing on UART side. 01121 If user wants to abort it, Abort services should be called by user. 01122 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. 01123 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. 01124 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() 01125 user callback is executed. 01126 01127 -@- In the Half duplex communication, it is forbidden to run the transmit 01128 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. 01129 01130 @endverbatim 01131 * @{ 01132 */ 01133 01134 /** 01135 * @brief Send an amount of data in blocking mode. 01136 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01137 * the sent data is handled as a set of u16. In this case, Size must indicate the number 01138 * of u16 provided through pData. 01139 * @note When FIFO mode is enabled, writing a data in the TDR register adds one 01140 * data to the TXFIFO. Write operations to the TDR register are performed 01141 * when TXFNF flag is set. From hardware perspective, TXFNF flag and 01142 * TXE are mapped on the same bit-field. 01143 * @param huart UART handle. 01144 * @param pData Pointer to data buffer (u8 or u16 data elements). 01145 * @param Size Amount of data elements (u8 or u16) to be sent. 01146 * @param Timeout Timeout duration. 01147 * @retval HAL status 01148 */ 01149 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) 01150 { 01151 const uint8_t *pdata8bits; 01152 const uint16_t *pdata16bits; 01153 uint32_t tickstart; 01154 01155 /* Check that a Tx process is not already ongoing */ 01156 if (huart->gState == HAL_UART_STATE_READY) 01157 { 01158 if ((pData == NULL) || (Size == 0U)) 01159 { 01160 return HAL_ERROR; 01161 } 01162 01163 __HAL_LOCK(huart); 01164 01165 huart->ErrorCode = HAL_UART_ERROR_NONE; 01166 huart->gState = HAL_UART_STATE_BUSY_TX; 01167 01168 /* Init tickstart for timeout management */ 01169 tickstart = HAL_GetTick(); 01170 01171 huart->TxXferSize = Size; 01172 huart->TxXferCount = Size; 01173 01174 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */ 01175 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 01176 { 01177 pdata8bits = NULL; 01178 pdata16bits = (const uint16_t *) pData; 01179 } 01180 else 01181 { 01182 pdata8bits = pData; 01183 pdata16bits = NULL; 01184 } 01185 01186 __HAL_UNLOCK(huart); 01187 01188 while (huart->TxXferCount > 0U) 01189 { 01190 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) 01191 { 01192 return HAL_TIMEOUT; 01193 } 01194 if (pdata8bits == NULL) 01195 { 01196 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU); 01197 pdata16bits++; 01198 } 01199 else 01200 { 01201 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU); 01202 pdata8bits++; 01203 } 01204 huart->TxXferCount--; 01205 } 01206 01207 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 01208 { 01209 return HAL_TIMEOUT; 01210 } 01211 01212 /* At end of Tx process, restore huart->gState to Ready */ 01213 huart->gState = HAL_UART_STATE_READY; 01214 01215 return HAL_OK; 01216 } 01217 else 01218 { 01219 return HAL_BUSY; 01220 } 01221 } 01222 01223 /** 01224 * @brief Receive an amount of data in blocking mode. 01225 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01226 * the received data is handled as a set of u16. In this case, Size must indicate the number 01227 * of u16 available through pData. 01228 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO 01229 * is not empty. Read operations from the RDR register are performed when 01230 * RXFNE flag is set. From hardware perspective, RXFNE flag and 01231 * RXNE are mapped on the same bit-field. 01232 * @param huart UART handle. 01233 * @param pData Pointer to data buffer (u8 or u16 data elements). 01234 * @param Size Amount of data elements (u8 or u16) to be received. 01235 * @param Timeout Timeout duration. 01236 * @retval HAL status 01237 */ 01238 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) 01239 { 01240 uint8_t *pdata8bits; 01241 uint16_t *pdata16bits; 01242 uint16_t uhMask; 01243 uint32_t tickstart; 01244 01245 /* Check that a Rx process is not already ongoing */ 01246 if (huart->RxState == HAL_UART_STATE_READY) 01247 { 01248 if ((pData == NULL) || (Size == 0U)) 01249 { 01250 return HAL_ERROR; 01251 } 01252 01253 __HAL_LOCK(huart); 01254 01255 huart->ErrorCode = HAL_UART_ERROR_NONE; 01256 huart->RxState = HAL_UART_STATE_BUSY_RX; 01257 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 01258 01259 /* Init tickstart for timeout management */ 01260 tickstart = HAL_GetTick(); 01261 01262 huart->RxXferSize = Size; 01263 huart->RxXferCount = Size; 01264 01265 /* Computation of UART mask to apply to RDR register */ 01266 UART_MASK_COMPUTATION(huart); 01267 uhMask = huart->Mask; 01268 01269 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ 01270 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 01271 { 01272 pdata8bits = NULL; 01273 pdata16bits = (uint16_t *) pData; 01274 } 01275 else 01276 { 01277 pdata8bits = pData; 01278 pdata16bits = NULL; 01279 } 01280 01281 __HAL_UNLOCK(huart); 01282 01283 /* as long as data have to be received */ 01284 while (huart->RxXferCount > 0U) 01285 { 01286 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 01287 { 01288 return HAL_TIMEOUT; 01289 } 01290 if (pdata8bits == NULL) 01291 { 01292 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); 01293 pdata16bits++; 01294 } 01295 else 01296 { 01297 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); 01298 pdata8bits++; 01299 } 01300 huart->RxXferCount--; 01301 } 01302 01303 /* At end of Rx process, restore huart->RxState to Ready */ 01304 huart->RxState = HAL_UART_STATE_READY; 01305 01306 return HAL_OK; 01307 } 01308 else 01309 { 01310 return HAL_BUSY; 01311 } 01312 } 01313 01314 /** 01315 * @brief Send an amount of data in interrupt mode. 01316 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01317 * the sent data is handled as a set of u16. In this case, Size must indicate the number 01318 * of u16 provided through pData. 01319 * @param huart UART handle. 01320 * @param pData Pointer to data buffer (u8 or u16 data elements). 01321 * @param Size Amount of data elements (u8 or u16) to be sent. 01322 * @retval HAL status 01323 */ 01324 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) 01325 { 01326 /* Check that a Tx process is not already ongoing */ 01327 if (huart->gState == HAL_UART_STATE_READY) 01328 { 01329 if ((pData == NULL) || (Size == 0U)) 01330 { 01331 return HAL_ERROR; 01332 } 01333 01334 __HAL_LOCK(huart); 01335 01336 huart->pTxBuffPtr = pData; 01337 huart->TxXferSize = Size; 01338 huart->TxXferCount = Size; 01339 huart->TxISR = NULL; 01340 01341 huart->ErrorCode = HAL_UART_ERROR_NONE; 01342 huart->gState = HAL_UART_STATE_BUSY_TX; 01343 01344 #if defined(USART_CR1_FIFOEN) 01345 /* Configure Tx interrupt processing */ 01346 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 01347 { 01348 /* Set the Tx ISR function pointer according to the data word length */ 01349 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 01350 { 01351 huart->TxISR = UART_TxISR_16BIT_FIFOEN; 01352 } 01353 else 01354 { 01355 huart->TxISR = UART_TxISR_8BIT_FIFOEN; 01356 } 01357 01358 __HAL_UNLOCK(huart); 01359 01360 /* Enable the TX FIFO threshold interrupt */ 01361 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); 01362 } 01363 else 01364 { 01365 /* Set the Tx ISR function pointer according to the data word length */ 01366 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 01367 { 01368 huart->TxISR = UART_TxISR_16BIT; 01369 } 01370 else 01371 { 01372 huart->TxISR = UART_TxISR_8BIT; 01373 } 01374 01375 __HAL_UNLOCK(huart); 01376 01377 /* Enable the Transmit Data Register Empty interrupt */ 01378 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); 01379 } 01380 #else 01381 /* Set the Tx ISR function pointer according to the data word length */ 01382 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 01383 { 01384 huart->TxISR = UART_TxISR_16BIT; 01385 } 01386 else 01387 { 01388 huart->TxISR = UART_TxISR_8BIT; 01389 } 01390 01391 __HAL_UNLOCK(huart); 01392 01393 /* Enable the Transmit Data Register Empty interrupt */ 01394 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 01395 #endif /* USART_CR1_FIFOEN */ 01396 01397 return HAL_OK; 01398 } 01399 else 01400 { 01401 return HAL_BUSY; 01402 } 01403 } 01404 01405 /** 01406 * @brief Receive an amount of data in interrupt mode. 01407 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01408 * the received data is handled as a set of u16. In this case, Size must indicate the number 01409 * of u16 available through pData. 01410 * @param huart UART handle. 01411 * @param pData Pointer to data buffer (u8 or u16 data elements). 01412 * @param Size Amount of data elements (u8 or u16) to be received. 01413 * @retval HAL status 01414 */ 01415 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 01416 { 01417 /* Check that a Rx process is not already ongoing */ 01418 if (huart->RxState == HAL_UART_STATE_READY) 01419 { 01420 if ((pData == NULL) || (Size == 0U)) 01421 { 01422 return HAL_ERROR; 01423 } 01424 01425 __HAL_LOCK(huart); 01426 01427 /* Set Reception type to Standard reception */ 01428 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 01429 01430 if (!(IS_LPUART_INSTANCE(huart->Instance))) 01431 { 01432 /* Check that USART RTOEN bit is set */ 01433 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) 01434 { 01435 /* Enable the UART Receiver Timeout Interrupt */ 01436 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); 01437 } 01438 } 01439 01440 return (UART_Start_Receive_IT(huart, pData, Size)); 01441 } 01442 else 01443 { 01444 return HAL_BUSY; 01445 } 01446 } 01447 01448 /** 01449 * @brief Send an amount of data in DMA mode. 01450 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01451 * the sent data is handled as a set of u16. In this case, Size must indicate the number 01452 * of u16 provided through pData. 01453 * @param huart UART handle. 01454 * @param pData Pointer to data buffer (u8 or u16 data elements). 01455 * @param Size Amount of data elements (u8 or u16) to be sent. 01456 * @retval HAL status 01457 */ 01458 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) 01459 { 01460 /* Check that a Tx process is not already ongoing */ 01461 if (huart->gState == HAL_UART_STATE_READY) 01462 { 01463 if ((pData == NULL) || (Size == 0U)) 01464 { 01465 return HAL_ERROR; 01466 } 01467 01468 __HAL_LOCK(huart); 01469 01470 huart->pTxBuffPtr = pData; 01471 huart->TxXferSize = Size; 01472 huart->TxXferCount = Size; 01473 01474 huart->ErrorCode = HAL_UART_ERROR_NONE; 01475 huart->gState = HAL_UART_STATE_BUSY_TX; 01476 01477 if (huart->hdmatx != NULL) 01478 { 01479 /* Set the UART DMA transfer complete callback */ 01480 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; 01481 01482 /* Set the UART DMA Half transfer complete callback */ 01483 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; 01484 01485 /* Set the DMA error callback */ 01486 huart->hdmatx->XferErrorCallback = UART_DMAError; 01487 01488 /* Set the DMA abort callback */ 01489 huart->hdmatx->XferAbortCallback = NULL; 01490 01491 /* Enable the UART transmit DMA channel */ 01492 if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK) 01493 { 01494 /* Set error code to DMA */ 01495 huart->ErrorCode = HAL_UART_ERROR_DMA; 01496 01497 __HAL_UNLOCK(huart); 01498 01499 /* Restore huart->gState to ready */ 01500 huart->gState = HAL_UART_STATE_READY; 01501 01502 return HAL_ERROR; 01503 } 01504 } 01505 /* Clear the TC flag in the ICR register */ 01506 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); 01507 01508 __HAL_UNLOCK(huart); 01509 01510 /* Enable the DMA transfer for transmit request by setting the DMAT bit 01511 in the UART CR3 register */ 01512 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01513 01514 return HAL_OK; 01515 } 01516 else 01517 { 01518 return HAL_BUSY; 01519 } 01520 } 01521 01522 /** 01523 * @brief Receive an amount of data in DMA mode. 01524 * @note When the UART parity is enabled (PCE = 1), the received data contain 01525 * the parity bit (MSB position). 01526 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 01527 * the received data is handled as a set of u16. In this case, Size must indicate the number 01528 * of u16 available through pData. 01529 * @param huart UART handle. 01530 * @param pData Pointer to data buffer (u8 or u16 data elements). 01531 * @param Size Amount of data elements (u8 or u16) to be received. 01532 * @retval HAL status 01533 */ 01534 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 01535 { 01536 /* Check that a Rx process is not already ongoing */ 01537 if (huart->RxState == HAL_UART_STATE_READY) 01538 { 01539 if ((pData == NULL) || (Size == 0U)) 01540 { 01541 return HAL_ERROR; 01542 } 01543 01544 __HAL_LOCK(huart); 01545 01546 /* Set Reception type to Standard reception */ 01547 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 01548 01549 if (!(IS_LPUART_INSTANCE(huart->Instance))) 01550 { 01551 /* Check that USART RTOEN bit is set */ 01552 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) 01553 { 01554 /* Enable the UART Receiver Timeout Interrupt */ 01555 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); 01556 } 01557 } 01558 01559 return (UART_Start_Receive_DMA(huart, pData, Size)); 01560 } 01561 else 01562 { 01563 return HAL_BUSY; 01564 } 01565 } 01566 01567 /** 01568 * @brief Pause the DMA Transfer. 01569 * @param huart UART handle. 01570 * @retval HAL status 01571 */ 01572 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) 01573 { 01574 const HAL_UART_StateTypeDef gstate = huart->gState; 01575 const HAL_UART_StateTypeDef rxstate = huart->RxState; 01576 01577 __HAL_LOCK(huart); 01578 01579 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && 01580 (gstate == HAL_UART_STATE_BUSY_TX)) 01581 { 01582 /* Disable the UART DMA Tx request */ 01583 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01584 } 01585 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && 01586 (rxstate == HAL_UART_STATE_BUSY_RX)) 01587 { 01588 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01589 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 01590 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01591 01592 /* Disable the UART DMA Rx request */ 01593 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01594 } 01595 01596 __HAL_UNLOCK(huart); 01597 01598 return HAL_OK; 01599 } 01600 01601 /** 01602 * @brief Resume the DMA Transfer. 01603 * @param huart UART handle. 01604 * @retval HAL status 01605 */ 01606 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) 01607 { 01608 __HAL_LOCK(huart); 01609 01610 if (huart->gState == HAL_UART_STATE_BUSY_TX) 01611 { 01612 /* Enable the UART DMA Tx request */ 01613 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01614 } 01615 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 01616 { 01617 /* Clear the Overrun flag before resuming the Rx transfer */ 01618 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); 01619 01620 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01621 if (huart->Init.Parity != UART_PARITY_NONE) 01622 { 01623 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 01624 } 01625 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 01626 01627 /* Enable the UART DMA Rx request */ 01628 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01629 } 01630 01631 __HAL_UNLOCK(huart); 01632 01633 return HAL_OK; 01634 } 01635 01636 /** 01637 * @brief Stop the DMA Transfer. 01638 * @param huart UART handle. 01639 * @retval HAL status 01640 */ 01641 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) 01642 { 01643 /* The Lock is not implemented on this API to allow the user application 01644 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / 01645 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback: 01646 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 01647 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 01648 the stream and the corresponding call back is executed. */ 01649 01650 const HAL_UART_StateTypeDef gstate = huart->gState; 01651 const HAL_UART_StateTypeDef rxstate = huart->RxState; 01652 01653 /* Stop UART DMA Tx request if ongoing */ 01654 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && 01655 (gstate == HAL_UART_STATE_BUSY_TX)) 01656 { 01657 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01658 01659 /* Abort the UART DMA Tx channel */ 01660 if (huart->hdmatx != NULL) 01661 { 01662 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) 01663 { 01664 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) 01665 { 01666 /* Set error code to DMA */ 01667 huart->ErrorCode = HAL_UART_ERROR_DMA; 01668 01669 return HAL_TIMEOUT; 01670 } 01671 } 01672 } 01673 01674 UART_EndTxTransfer(huart); 01675 } 01676 01677 /* Stop UART DMA Rx request if ongoing */ 01678 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && 01679 (rxstate == HAL_UART_STATE_BUSY_RX)) 01680 { 01681 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01682 01683 /* Abort the UART DMA Rx channel */ 01684 if (huart->hdmarx != NULL) 01685 { 01686 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) 01687 { 01688 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) 01689 { 01690 /* Set error code to DMA */ 01691 huart->ErrorCode = HAL_UART_ERROR_DMA; 01692 01693 return HAL_TIMEOUT; 01694 } 01695 } 01696 } 01697 01698 UART_EndRxTransfer(huart); 01699 } 01700 01701 return HAL_OK; 01702 } 01703 01704 /** 01705 * @brief Abort ongoing transfers (blocking mode). 01706 * @param huart UART handle. 01707 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 01708 * This procedure performs following operations : 01709 * - Disable UART Interrupts (Tx and Rx) 01710 * - Disable the DMA transfer in the peripheral register (if enabled) 01711 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01712 * - Set handle State to READY 01713 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01714 * @retval HAL status 01715 */ 01716 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) 01717 { 01718 #if defined(USART_CR1_FIFOEN) 01719 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */ 01720 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | 01721 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 01722 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE); 01723 #else 01724 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01725 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 01726 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01727 #endif /* USART_CR1_FIFOEN */ 01728 01729 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 01730 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 01731 { 01732 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 01733 } 01734 01735 /* Abort the UART DMA Tx channel if enabled */ 01736 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 01737 { 01738 /* Disable the UART DMA Tx request if enabled */ 01739 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01740 01741 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ 01742 if (huart->hdmatx != NULL) 01743 { 01744 /* Set the UART DMA Abort callback to Null. 01745 No call back execution at end of DMA abort procedure */ 01746 huart->hdmatx->XferAbortCallback = NULL; 01747 01748 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) 01749 { 01750 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) 01751 { 01752 /* Set error code to DMA */ 01753 huart->ErrorCode = HAL_UART_ERROR_DMA; 01754 01755 return HAL_TIMEOUT; 01756 } 01757 } 01758 } 01759 } 01760 01761 /* Abort the UART DMA Rx channel if enabled */ 01762 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 01763 { 01764 /* Disable the UART DMA Rx request if enabled */ 01765 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01766 01767 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ 01768 if (huart->hdmarx != NULL) 01769 { 01770 /* Set the UART DMA Abort callback to Null. 01771 No call back execution at end of DMA abort procedure */ 01772 huart->hdmarx->XferAbortCallback = NULL; 01773 01774 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) 01775 { 01776 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) 01777 { 01778 /* Set error code to DMA */ 01779 huart->ErrorCode = HAL_UART_ERROR_DMA; 01780 01781 return HAL_TIMEOUT; 01782 } 01783 } 01784 } 01785 } 01786 01787 /* Reset Tx and Rx transfer counters */ 01788 huart->TxXferCount = 0U; 01789 huart->RxXferCount = 0U; 01790 01791 /* Clear the Error flags in the ICR register */ 01792 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 01793 01794 #if defined(USART_CR1_FIFOEN) 01795 /* Flush the whole TX FIFO (if needed) */ 01796 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 01797 { 01798 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 01799 } 01800 #endif /* USART_CR1_FIFOEN */ 01801 01802 /* Discard the received data */ 01803 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 01804 01805 /* Restore huart->gState and huart->RxState to Ready */ 01806 huart->gState = HAL_UART_STATE_READY; 01807 huart->RxState = HAL_UART_STATE_READY; 01808 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 01809 01810 huart->ErrorCode = HAL_UART_ERROR_NONE; 01811 01812 return HAL_OK; 01813 } 01814 01815 /** 01816 * @brief Abort ongoing Transmit transfer (blocking mode). 01817 * @param huart UART handle. 01818 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 01819 * This procedure performs following operations : 01820 * - Disable UART Interrupts (Tx) 01821 * - Disable the DMA transfer in the peripheral register (if enabled) 01822 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01823 * - Set handle State to READY 01824 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01825 * @retval HAL status 01826 */ 01827 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) 01828 { 01829 #if defined(USART_CR1_FIFOEN) 01830 /* Disable TCIE, TXEIE and TXFTIE interrupts */ 01831 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); 01832 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); 01833 #else 01834 /* Disable TXEIE and TCIE interrupts */ 01835 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 01836 #endif /* USART_CR1_FIFOEN */ 01837 01838 /* Abort the UART DMA Tx channel if enabled */ 01839 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 01840 { 01841 /* Disable the UART DMA Tx request if enabled */ 01842 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 01843 01844 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ 01845 if (huart->hdmatx != NULL) 01846 { 01847 /* Set the UART DMA Abort callback to Null. 01848 No call back execution at end of DMA abort procedure */ 01849 huart->hdmatx->XferAbortCallback = NULL; 01850 01851 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) 01852 { 01853 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) 01854 { 01855 /* Set error code to DMA */ 01856 huart->ErrorCode = HAL_UART_ERROR_DMA; 01857 01858 return HAL_TIMEOUT; 01859 } 01860 } 01861 } 01862 } 01863 01864 /* Reset Tx transfer counter */ 01865 huart->TxXferCount = 0U; 01866 01867 #if defined(USART_CR1_FIFOEN) 01868 /* Flush the whole TX FIFO (if needed) */ 01869 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 01870 { 01871 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 01872 } 01873 #endif /* USART_CR1_FIFOEN */ 01874 01875 /* Restore huart->gState to Ready */ 01876 huart->gState = HAL_UART_STATE_READY; 01877 01878 return HAL_OK; 01879 } 01880 01881 /** 01882 * @brief Abort ongoing Receive transfer (blocking mode). 01883 * @param huart UART handle. 01884 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 01885 * This procedure performs following operations : 01886 * - Disable UART Interrupts (Rx) 01887 * - Disable the DMA transfer in the peripheral register (if enabled) 01888 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01889 * - Set handle State to READY 01890 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01891 * @retval HAL status 01892 */ 01893 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) 01894 { 01895 #if defined(USART_CR1_FIFOEN) 01896 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */ 01897 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); 01898 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE); 01899 #else 01900 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01901 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01902 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01903 #endif /* USART_CR1_FIFOEN */ 01904 01905 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 01906 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 01907 { 01908 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 01909 } 01910 01911 /* Abort the UART DMA Rx channel if enabled */ 01912 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 01913 { 01914 /* Disable the UART DMA Rx request if enabled */ 01915 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 01916 01917 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ 01918 if (huart->hdmarx != NULL) 01919 { 01920 /* Set the UART DMA Abort callback to Null. 01921 No call back execution at end of DMA abort procedure */ 01922 huart->hdmarx->XferAbortCallback = NULL; 01923 01924 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) 01925 { 01926 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) 01927 { 01928 /* Set error code to DMA */ 01929 huart->ErrorCode = HAL_UART_ERROR_DMA; 01930 01931 return HAL_TIMEOUT; 01932 } 01933 } 01934 } 01935 } 01936 01937 /* Reset Rx transfer counter */ 01938 huart->RxXferCount = 0U; 01939 01940 /* Clear the Error flags in the ICR register */ 01941 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 01942 01943 /* Discard the received data */ 01944 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 01945 01946 /* Restore huart->RxState to Ready */ 01947 huart->RxState = HAL_UART_STATE_READY; 01948 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 01949 01950 return HAL_OK; 01951 } 01952 01953 /** 01954 * @brief Abort ongoing transfers (Interrupt mode). 01955 * @param huart UART handle. 01956 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 01957 * This procedure performs following operations : 01958 * - Disable UART Interrupts (Tx and Rx) 01959 * - Disable the DMA transfer in the peripheral register (if enabled) 01960 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 01961 * - Set handle State to READY 01962 * - At abort completion, call user abort complete callback 01963 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 01964 * considered as completed only when user abort complete callback is executed (not when exiting function). 01965 * @retval HAL status 01966 */ 01967 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) 01968 { 01969 uint32_t abortcplt = 1U; 01970 01971 /* Disable interrupts */ 01972 #if defined(USART_CR1_FIFOEN) 01973 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | 01974 USART_CR1_TXEIE_TXFNFIE)); 01975 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); 01976 #else 01977 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 01978 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 01979 #endif /* USART_CR1_FIFOEN */ 01980 01981 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 01982 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 01983 { 01984 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 01985 } 01986 01987 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised 01988 before any call to DMA Abort functions */ 01989 /* DMA Tx Handle is valid */ 01990 if (huart->hdmatx != NULL) 01991 { 01992 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. 01993 Otherwise, set it to NULL */ 01994 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 01995 { 01996 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; 01997 } 01998 else 01999 { 02000 huart->hdmatx->XferAbortCallback = NULL; 02001 } 02002 } 02003 /* DMA Rx Handle is valid */ 02004 if (huart->hdmarx != NULL) 02005 { 02006 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. 02007 Otherwise, set it to NULL */ 02008 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 02009 { 02010 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; 02011 } 02012 else 02013 { 02014 huart->hdmarx->XferAbortCallback = NULL; 02015 } 02016 } 02017 02018 /* Abort the UART DMA Tx channel if enabled */ 02019 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 02020 { 02021 /* Disable DMA Tx at UART level */ 02022 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 02023 02024 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ 02025 if (huart->hdmatx != NULL) 02026 { 02027 /* UART Tx DMA Abort callback has already been initialised : 02028 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 02029 02030 /* Abort DMA TX */ 02031 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) 02032 { 02033 huart->hdmatx->XferAbortCallback = NULL; 02034 } 02035 else 02036 { 02037 abortcplt = 0U; 02038 } 02039 } 02040 } 02041 02042 /* Abort the UART DMA Rx channel if enabled */ 02043 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 02044 { 02045 /* Disable the UART DMA Rx request if enabled */ 02046 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 02047 02048 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ 02049 if (huart->hdmarx != NULL) 02050 { 02051 /* UART Rx DMA Abort callback has already been initialised : 02052 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 02053 02054 /* Abort DMA RX */ 02055 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 02056 { 02057 huart->hdmarx->XferAbortCallback = NULL; 02058 abortcplt = 1U; 02059 } 02060 else 02061 { 02062 abortcplt = 0U; 02063 } 02064 } 02065 } 02066 02067 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ 02068 if (abortcplt == 1U) 02069 { 02070 /* Reset Tx and Rx transfer counters */ 02071 huart->TxXferCount = 0U; 02072 huart->RxXferCount = 0U; 02073 02074 /* Clear ISR function pointers */ 02075 huart->RxISR = NULL; 02076 huart->TxISR = NULL; 02077 02078 /* Reset errorCode */ 02079 huart->ErrorCode = HAL_UART_ERROR_NONE; 02080 02081 /* Clear the Error flags in the ICR register */ 02082 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 02083 02084 #if defined(USART_CR1_FIFOEN) 02085 /* Flush the whole TX FIFO (if needed) */ 02086 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 02087 { 02088 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 02089 } 02090 #endif /* USART_CR1_FIFOEN */ 02091 02092 /* Discard the received data */ 02093 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 02094 02095 /* Restore huart->gState and huart->RxState to Ready */ 02096 huart->gState = HAL_UART_STATE_READY; 02097 huart->RxState = HAL_UART_STATE_READY; 02098 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 02099 02100 /* As no DMA to be aborted, call directly user Abort complete callback */ 02101 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02102 /* Call registered Abort complete callback */ 02103 huart->AbortCpltCallback(huart); 02104 #else 02105 /* Call legacy weak Abort complete callback */ 02106 HAL_UART_AbortCpltCallback(huart); 02107 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02108 } 02109 02110 return HAL_OK; 02111 } 02112 02113 /** 02114 * @brief Abort ongoing Transmit transfer (Interrupt mode). 02115 * @param huart UART handle. 02116 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 02117 * This procedure performs following operations : 02118 * - Disable UART Interrupts (Tx) 02119 * - Disable the DMA transfer in the peripheral register (if enabled) 02120 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 02121 * - Set handle State to READY 02122 * - At abort completion, call user abort complete callback 02123 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 02124 * considered as completed only when user abort complete callback is executed (not when exiting function). 02125 * @retval HAL status 02126 */ 02127 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) 02128 { 02129 /* Disable interrupts */ 02130 #if defined(USART_CR1_FIFOEN) 02131 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); 02132 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); 02133 #else 02134 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 02135 #endif /* USART_CR1_FIFOEN */ 02136 02137 /* Abort the UART DMA Tx channel if enabled */ 02138 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) 02139 { 02140 /* Disable the UART DMA Tx request if enabled */ 02141 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 02142 02143 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ 02144 if (huart->hdmatx != NULL) 02145 { 02146 /* Set the UART DMA Abort callback : 02147 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 02148 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; 02149 02150 /* Abort DMA TX */ 02151 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) 02152 { 02153 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ 02154 huart->hdmatx->XferAbortCallback(huart->hdmatx); 02155 } 02156 } 02157 else 02158 { 02159 /* Reset Tx transfer counter */ 02160 huart->TxXferCount = 0U; 02161 02162 /* Clear TxISR function pointers */ 02163 huart->TxISR = NULL; 02164 02165 /* Restore huart->gState to Ready */ 02166 huart->gState = HAL_UART_STATE_READY; 02167 02168 /* As no DMA to be aborted, call directly user Abort complete callback */ 02169 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02170 /* Call registered Abort Transmit Complete Callback */ 02171 huart->AbortTransmitCpltCallback(huart); 02172 #else 02173 /* Call legacy weak Abort Transmit Complete Callback */ 02174 HAL_UART_AbortTransmitCpltCallback(huart); 02175 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02176 } 02177 } 02178 else 02179 { 02180 /* Reset Tx transfer counter */ 02181 huart->TxXferCount = 0U; 02182 02183 /* Clear TxISR function pointers */ 02184 huart->TxISR = NULL; 02185 02186 #if defined(USART_CR1_FIFOEN) 02187 /* Flush the whole TX FIFO (if needed) */ 02188 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 02189 { 02190 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 02191 } 02192 #endif /* USART_CR1_FIFOEN */ 02193 02194 /* Restore huart->gState to Ready */ 02195 huart->gState = HAL_UART_STATE_READY; 02196 02197 /* As no DMA to be aborted, call directly user Abort complete callback */ 02198 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02199 /* Call registered Abort Transmit Complete Callback */ 02200 huart->AbortTransmitCpltCallback(huart); 02201 #else 02202 /* Call legacy weak Abort Transmit Complete Callback */ 02203 HAL_UART_AbortTransmitCpltCallback(huart); 02204 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02205 } 02206 02207 return HAL_OK; 02208 } 02209 02210 /** 02211 * @brief Abort ongoing Receive transfer (Interrupt mode). 02212 * @param huart UART handle. 02213 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 02214 * This procedure performs following operations : 02215 * - Disable UART Interrupts (Rx) 02216 * - Disable the DMA transfer in the peripheral register (if enabled) 02217 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 02218 * - Set handle State to READY 02219 * - At abort completion, call user abort complete callback 02220 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 02221 * considered as completed only when user abort complete callback is executed (not when exiting function). 02222 * @retval HAL status 02223 */ 02224 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) 02225 { 02226 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 02227 #if defined(USART_CR1_FIFOEN) 02228 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); 02229 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); 02230 #else 02231 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 02232 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 02233 #endif /* USART_CR1_FIFOEN */ 02234 02235 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ 02236 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 02237 { 02238 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); 02239 } 02240 02241 /* Abort the UART DMA Rx channel if enabled */ 02242 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 02243 { 02244 /* Disable the UART DMA Rx request if enabled */ 02245 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 02246 02247 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ 02248 if (huart->hdmarx != NULL) 02249 { 02250 /* Set the UART DMA Abort callback : 02251 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ 02252 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; 02253 02254 /* Abort DMA RX */ 02255 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 02256 { 02257 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ 02258 huart->hdmarx->XferAbortCallback(huart->hdmarx); 02259 } 02260 } 02261 else 02262 { 02263 /* Reset Rx transfer counter */ 02264 huart->RxXferCount = 0U; 02265 02266 /* Clear RxISR function pointer */ 02267 huart->pRxBuffPtr = NULL; 02268 02269 /* Clear the Error flags in the ICR register */ 02270 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 02271 02272 /* Discard the received data */ 02273 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 02274 02275 /* Restore huart->RxState to Ready */ 02276 huart->RxState = HAL_UART_STATE_READY; 02277 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 02278 02279 /* As no DMA to be aborted, call directly user Abort complete callback */ 02280 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02281 /* Call registered Abort Receive Complete Callback */ 02282 huart->AbortReceiveCpltCallback(huart); 02283 #else 02284 /* Call legacy weak Abort Receive Complete Callback */ 02285 HAL_UART_AbortReceiveCpltCallback(huart); 02286 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02287 } 02288 } 02289 else 02290 { 02291 /* Reset Rx transfer counter */ 02292 huart->RxXferCount = 0U; 02293 02294 /* Clear RxISR function pointer */ 02295 huart->pRxBuffPtr = NULL; 02296 02297 /* Clear the Error flags in the ICR register */ 02298 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 02299 02300 /* Restore huart->RxState to Ready */ 02301 huart->RxState = HAL_UART_STATE_READY; 02302 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 02303 02304 /* As no DMA to be aborted, call directly user Abort complete callback */ 02305 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02306 /* Call registered Abort Receive Complete Callback */ 02307 huart->AbortReceiveCpltCallback(huart); 02308 #else 02309 /* Call legacy weak Abort Receive Complete Callback */ 02310 HAL_UART_AbortReceiveCpltCallback(huart); 02311 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02312 } 02313 02314 return HAL_OK; 02315 } 02316 02317 /** 02318 * @brief Handle UART interrupt request. 02319 * @param huart UART handle. 02320 * @retval None 02321 */ 02322 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 02323 { 02324 uint32_t isrflags = READ_REG(huart->Instance->ISR); 02325 uint32_t cr1its = READ_REG(huart->Instance->CR1); 02326 uint32_t cr3its = READ_REG(huart->Instance->CR3); 02327 02328 uint32_t errorflags; 02329 uint32_t errorcode; 02330 02331 /* If no error occurs */ 02332 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF)); 02333 if (errorflags == 0U) 02334 { 02335 /* UART in mode Receiver ---------------------------------------------------*/ 02336 #if defined(USART_CR1_FIFOEN) 02337 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) 02338 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) 02339 || ((cr3its & USART_CR3_RXFTIE) != 0U))) 02340 #else 02341 if (((isrflags & USART_ISR_RXNE) != 0U) 02342 && ((cr1its & USART_CR1_RXNEIE) != 0U)) 02343 #endif /* USART_CR1_FIFOEN */ 02344 { 02345 if (huart->RxISR != NULL) 02346 { 02347 huart->RxISR(huart); 02348 } 02349 return; 02350 } 02351 } 02352 02353 /* If some errors occur */ 02354 #if defined(USART_CR1_FIFOEN) 02355 if ((errorflags != 0U) 02356 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U) 02357 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U)))) 02358 #else 02359 if ((errorflags != 0U) 02360 && (((cr3its & USART_CR3_EIE) != 0U) 02361 || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))) 02362 #endif /* USART_CR1_FIFOEN */ 02363 { 02364 /* UART parity error interrupt occurred -------------------------------------*/ 02365 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) 02366 { 02367 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); 02368 02369 huart->ErrorCode |= HAL_UART_ERROR_PE; 02370 } 02371 02372 /* UART frame error interrupt occurred --------------------------------------*/ 02373 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 02374 { 02375 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); 02376 02377 huart->ErrorCode |= HAL_UART_ERROR_FE; 02378 } 02379 02380 /* UART noise error interrupt occurred --------------------------------------*/ 02381 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 02382 { 02383 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); 02384 02385 huart->ErrorCode |= HAL_UART_ERROR_NE; 02386 } 02387 02388 /* UART Over-Run interrupt occurred -----------------------------------------*/ 02389 #if defined(USART_CR1_FIFOEN) 02390 if (((isrflags & USART_ISR_ORE) != 0U) 02391 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || 02392 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U))) 02393 #else 02394 if (((isrflags & USART_ISR_ORE) != 0U) 02395 && (((cr1its & USART_CR1_RXNEIE) != 0U) || 02396 ((cr3its & USART_CR3_EIE) != 0U))) 02397 #endif /* USART_CR1_FIFOEN */ 02398 { 02399 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); 02400 02401 huart->ErrorCode |= HAL_UART_ERROR_ORE; 02402 } 02403 02404 /* UART Receiver Timeout interrupt occurred ---------------------------------*/ 02405 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U)) 02406 { 02407 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); 02408 02409 huart->ErrorCode |= HAL_UART_ERROR_RTO; 02410 } 02411 02412 /* Call UART Error Call back function if need be ----------------------------*/ 02413 if (huart->ErrorCode != HAL_UART_ERROR_NONE) 02414 { 02415 /* UART in mode Receiver --------------------------------------------------*/ 02416 #if defined(USART_CR1_FIFOEN) 02417 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) 02418 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) 02419 || ((cr3its & USART_CR3_RXFTIE) != 0U))) 02420 #else 02421 if (((isrflags & USART_ISR_RXNE) != 0U) 02422 && ((cr1its & USART_CR1_RXNEIE) != 0U)) 02423 #endif /* USART_CR1_FIFOEN */ 02424 { 02425 if (huart->RxISR != NULL) 02426 { 02427 huart->RxISR(huart); 02428 } 02429 } 02430 02431 /* If Error is to be considered as blocking : 02432 - Receiver Timeout error in Reception 02433 - Overrun error in Reception 02434 - any error occurs in DMA mode reception 02435 */ 02436 errorcode = huart->ErrorCode; 02437 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) || 02438 ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U)) 02439 { 02440 /* Blocking error : transfer is aborted 02441 Set the UART state ready to be able to start again the process, 02442 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ 02443 UART_EndRxTransfer(huart); 02444 02445 /* Abort the UART DMA Rx channel if enabled */ 02446 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 02447 { 02448 /* Disable the UART DMA Rx request if enabled */ 02449 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 02450 02451 /* Abort the UART DMA Rx channel */ 02452 if (huart->hdmarx != NULL) 02453 { 02454 /* Set the UART DMA Abort callback : 02455 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ 02456 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; 02457 02458 /* Abort DMA RX */ 02459 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) 02460 { 02461 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ 02462 huart->hdmarx->XferAbortCallback(huart->hdmarx); 02463 } 02464 } 02465 else 02466 { 02467 /* Call user error callback */ 02468 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02469 /*Call registered error callback*/ 02470 huart->ErrorCallback(huart); 02471 #else 02472 /*Call legacy weak error callback*/ 02473 HAL_UART_ErrorCallback(huart); 02474 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02475 02476 } 02477 } 02478 else 02479 { 02480 /* Call user error callback */ 02481 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02482 /*Call registered error callback*/ 02483 huart->ErrorCallback(huart); 02484 #else 02485 /*Call legacy weak error callback*/ 02486 HAL_UART_ErrorCallback(huart); 02487 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02488 } 02489 } 02490 else 02491 { 02492 /* Non Blocking error : transfer could go on. 02493 Error is notified to user through user error callback */ 02494 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02495 /*Call registered error callback*/ 02496 huart->ErrorCallback(huart); 02497 #else 02498 /*Call legacy weak error callback*/ 02499 HAL_UART_ErrorCallback(huart); 02500 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02501 huart->ErrorCode = HAL_UART_ERROR_NONE; 02502 } 02503 } 02504 return; 02505 02506 } /* End if some error occurs */ 02507 02508 /* Check current reception Mode : 02509 If Reception till IDLE event has been selected : */ 02510 if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 02511 && ((isrflags & USART_ISR_IDLE) != 0U) 02512 && ((cr1its & USART_ISR_IDLE) != 0U)) 02513 { 02514 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 02515 02516 /* Check if DMA mode is enabled in UART */ 02517 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) 02518 { 02519 /* DMA mode enabled */ 02520 /* Check received length : If all expected data are received, do nothing, 02521 (DMA cplt callback will be called). 02522 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ 02523 uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx); 02524 if ((nb_remaining_rx_data > 0U) 02525 && (nb_remaining_rx_data < huart->RxXferSize)) 02526 { 02527 /* Reception is not complete */ 02528 huart->RxXferCount = nb_remaining_rx_data; 02529 02530 /* In Normal mode, end DMA xfer and HAL UART Rx process*/ 02531 if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC)) 02532 { 02533 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 02534 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 02535 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 02536 02537 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 02538 in the UART CR3 register */ 02539 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 02540 02541 /* At end of Rx process, restore huart->RxState to Ready */ 02542 huart->RxState = HAL_UART_STATE_READY; 02543 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 02544 02545 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 02546 02547 /* Last bytes received, so no need as the abort is immediate */ 02548 (void)HAL_DMA_Abort(huart->hdmarx); 02549 } 02550 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02551 /*Call registered Rx Event callback*/ 02552 huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); 02553 #else 02554 /*Call legacy weak Rx Event callback*/ 02555 HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); 02556 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 02557 } 02558 return; 02559 } 02560 else 02561 { 02562 /* DMA mode not enabled */ 02563 /* Check received length : If all expected data are received, do nothing. 02564 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ 02565 uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount; 02566 if ((huart->RxXferCount > 0U) 02567 && (nb_rx_data > 0U)) 02568 { 02569 #if defined(USART_CR1_FIFOEN) 02570 /* Disable the UART Parity Error Interrupt and RXNE interrupts */ 02571 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 02572 02573 /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ 02574 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); 02575 #else 02576 /* Disable the UART Parity Error Interrupt and RXNE interrupts */ 02577 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 02578 02579 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 02580 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 02581 #endif 02582 02583 /* Rx process is completed, restore huart->RxState to Ready */ 02584 huart->RxState = HAL_UART_STATE_READY; 02585 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 02586 02587 /* Clear RxISR function pointer */ 02588 huart->RxISR = NULL; 02589 02590 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 02591 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02592 /*Call registered Rx complete callback*/ 02593 huart->RxEventCallback(huart, nb_rx_data); 02594 #else 02595 /*Call legacy weak Rx Event callback*/ 02596 HAL_UARTEx_RxEventCallback(huart, nb_rx_data); 02597 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 02598 } 02599 return; 02600 } 02601 } 02602 02603 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ 02604 if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U)) 02605 { 02606 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF); 02607 02608 /* UART Rx state is not reset as a reception process might be ongoing. 02609 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */ 02610 02611 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02612 /* Call registered Wakeup Callback */ 02613 huart->WakeupCallback(huart); 02614 #else 02615 /* Call legacy weak Wakeup Callback */ 02616 HAL_UARTEx_WakeupCallback(huart); 02617 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02618 return; 02619 } 02620 02621 /* UART in mode Transmitter ------------------------------------------------*/ 02622 #if defined(USART_CR1_FIFOEN) 02623 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) 02624 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) 02625 || ((cr3its & USART_CR3_TXFTIE) != 0U))) 02626 #else 02627 if (((isrflags & USART_ISR_TXE) != 0U) 02628 && ((cr1its & USART_CR1_TXEIE) != 0U)) 02629 #endif /* USART_CR1_FIFOEN */ 02630 { 02631 if (huart->TxISR != NULL) 02632 { 02633 huart->TxISR(huart); 02634 } 02635 return; 02636 } 02637 02638 /* UART in mode Transmitter (transmission end) -----------------------------*/ 02639 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) 02640 { 02641 UART_EndTransmit_IT(huart); 02642 return; 02643 } 02644 02645 #if defined(USART_CR1_FIFOEN) 02646 /* UART TX Fifo Empty occurred ----------------------------------------------*/ 02647 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U)) 02648 { 02649 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02650 /* Call registered Tx Fifo Empty Callback */ 02651 huart->TxFifoEmptyCallback(huart); 02652 #else 02653 /* Call legacy weak Tx Fifo Empty Callback */ 02654 HAL_UARTEx_TxFifoEmptyCallback(huart); 02655 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02656 return; 02657 } 02658 02659 /* UART RX Fifo Full occurred ----------------------------------------------*/ 02660 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U)) 02661 { 02662 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 02663 /* Call registered Rx Fifo Full Callback */ 02664 huart->RxFifoFullCallback(huart); 02665 #else 02666 /* Call legacy weak Rx Fifo Full Callback */ 02667 HAL_UARTEx_RxFifoFullCallback(huart); 02668 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 02669 return; 02670 } 02671 #endif /* USART_CR1_FIFOEN */ 02672 } 02673 02674 /** 02675 * @brief Tx Transfer completed callback. 02676 * @param huart UART handle. 02677 * @retval None 02678 */ 02679 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) 02680 { 02681 /* Prevent unused argument(s) compilation warning */ 02682 UNUSED(huart); 02683 02684 /* NOTE : This function should not be modified, when the callback is needed, 02685 the HAL_UART_TxCpltCallback can be implemented in the user file. 02686 */ 02687 } 02688 02689 /** 02690 * @brief Tx Half Transfer completed callback. 02691 * @param huart UART handle. 02692 * @retval None 02693 */ 02694 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) 02695 { 02696 /* Prevent unused argument(s) compilation warning */ 02697 UNUSED(huart); 02698 02699 /* NOTE: This function should not be modified, when the callback is needed, 02700 the HAL_UART_TxHalfCpltCallback can be implemented in the user file. 02701 */ 02702 } 02703 02704 /** 02705 * @brief Rx Transfer completed callback. 02706 * @param huart UART handle. 02707 * @retval None 02708 */ 02709 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 02710 { 02711 /* Prevent unused argument(s) compilation warning */ 02712 UNUSED(huart); 02713 02714 /* NOTE : This function should not be modified, when the callback is needed, 02715 the HAL_UART_RxCpltCallback can be implemented in the user file. 02716 */ 02717 } 02718 02719 /** 02720 * @brief Rx Half Transfer completed callback. 02721 * @param huart UART handle. 02722 * @retval None 02723 */ 02724 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) 02725 { 02726 /* Prevent unused argument(s) compilation warning */ 02727 UNUSED(huart); 02728 02729 /* NOTE: This function should not be modified, when the callback is needed, 02730 the HAL_UART_RxHalfCpltCallback can be implemented in the user file. 02731 */ 02732 } 02733 02734 /** 02735 * @brief UART error callback. 02736 * @param huart UART handle. 02737 * @retval None 02738 */ 02739 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) 02740 { 02741 /* Prevent unused argument(s) compilation warning */ 02742 UNUSED(huart); 02743 02744 /* NOTE : This function should not be modified, when the callback is needed, 02745 the HAL_UART_ErrorCallback can be implemented in the user file. 02746 */ 02747 } 02748 02749 /** 02750 * @brief UART Abort Complete callback. 02751 * @param huart UART handle. 02752 * @retval None 02753 */ 02754 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) 02755 { 02756 /* Prevent unused argument(s) compilation warning */ 02757 UNUSED(huart); 02758 02759 /* NOTE : This function should not be modified, when the callback is needed, 02760 the HAL_UART_AbortCpltCallback can be implemented in the user file. 02761 */ 02762 } 02763 02764 /** 02765 * @brief UART Abort Complete callback. 02766 * @param huart UART handle. 02767 * @retval None 02768 */ 02769 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) 02770 { 02771 /* Prevent unused argument(s) compilation warning */ 02772 UNUSED(huart); 02773 02774 /* NOTE : This function should not be modified, when the callback is needed, 02775 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. 02776 */ 02777 } 02778 02779 /** 02780 * @brief UART Abort Receive Complete callback. 02781 * @param huart UART handle. 02782 * @retval None 02783 */ 02784 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) 02785 { 02786 /* Prevent unused argument(s) compilation warning */ 02787 UNUSED(huart); 02788 02789 /* NOTE : This function should not be modified, when the callback is needed, 02790 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. 02791 */ 02792 } 02793 02794 /** 02795 * @brief Reception Event Callback (Rx event notification called after use of advanced reception service). 02796 * @param huart UART handle 02797 * @param Size Number of data available in application reception buffer (indicates a position in 02798 * reception buffer until which, data are available) 02799 * @retval None 02800 */ 02801 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) 02802 { 02803 /* Prevent unused argument(s) compilation warning */ 02804 UNUSED(huart); 02805 UNUSED(Size); 02806 02807 /* NOTE : This function should not be modified, when the callback is needed, 02808 the HAL_UARTEx_RxEventCallback can be implemented in the user file. 02809 */ 02810 } 02811 02812 /** 02813 * @} 02814 */ 02815 02816 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions 02817 * @brief UART control functions 02818 * 02819 @verbatim 02820 =============================================================================== 02821 ##### Peripheral Control functions ##### 02822 =============================================================================== 02823 [..] 02824 This subsection provides a set of functions allowing to control the UART. 02825 (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly 02826 (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature 02827 (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature 02828 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode 02829 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode 02830 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode 02831 (+) UART_SetConfig() API configures the UART peripheral 02832 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features 02833 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization 02834 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter 02835 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver 02836 (+) HAL_LIN_SendBreak() API transmits the break characters 02837 @endverbatim 02838 * @{ 02839 */ 02840 02841 /** 02842 * @brief Update on the fly the receiver timeout value in RTOR register. 02843 * @param huart Pointer to a UART_HandleTypeDef structure that contains 02844 * the configuration information for the specified UART module. 02845 * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout 02846 * value must be less or equal to 0x0FFFFFFFF. 02847 * @retval None 02848 */ 02849 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue) 02850 { 02851 if (!(IS_LPUART_INSTANCE(huart->Instance))) 02852 { 02853 assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue)); 02854 MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue); 02855 } 02856 } 02857 02858 /** 02859 * @brief Enable the UART receiver timeout feature. 02860 * @param huart Pointer to a UART_HandleTypeDef structure that contains 02861 * the configuration information for the specified UART module. 02862 * @retval HAL status 02863 */ 02864 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart) 02865 { 02866 if (!(IS_LPUART_INSTANCE(huart->Instance))) 02867 { 02868 if (huart->gState == HAL_UART_STATE_READY) 02869 { 02870 /* Process Locked */ 02871 __HAL_LOCK(huart); 02872 02873 huart->gState = HAL_UART_STATE_BUSY; 02874 02875 /* Set the USART RTOEN bit */ 02876 SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN); 02877 02878 huart->gState = HAL_UART_STATE_READY; 02879 02880 /* Process Unlocked */ 02881 __HAL_UNLOCK(huart); 02882 02883 return HAL_OK; 02884 } 02885 else 02886 { 02887 return HAL_BUSY; 02888 } 02889 } 02890 else 02891 { 02892 return HAL_ERROR; 02893 } 02894 } 02895 02896 /** 02897 * @brief Disable the UART receiver timeout feature. 02898 * @param huart Pointer to a UART_HandleTypeDef structure that contains 02899 * the configuration information for the specified UART module. 02900 * @retval HAL status 02901 */ 02902 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart) 02903 { 02904 if (!(IS_LPUART_INSTANCE(huart->Instance))) 02905 { 02906 if (huart->gState == HAL_UART_STATE_READY) 02907 { 02908 /* Process Locked */ 02909 __HAL_LOCK(huart); 02910 02911 huart->gState = HAL_UART_STATE_BUSY; 02912 02913 /* Clear the USART RTOEN bit */ 02914 CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN); 02915 02916 huart->gState = HAL_UART_STATE_READY; 02917 02918 /* Process Unlocked */ 02919 __HAL_UNLOCK(huart); 02920 02921 return HAL_OK; 02922 } 02923 else 02924 { 02925 return HAL_BUSY; 02926 } 02927 } 02928 else 02929 { 02930 return HAL_ERROR; 02931 } 02932 } 02933 02934 /** 02935 * @brief Enable UART in mute mode (does not mean UART enters mute mode; 02936 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). 02937 * @param huart UART handle. 02938 * @retval HAL status 02939 */ 02940 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) 02941 { 02942 __HAL_LOCK(huart); 02943 02944 huart->gState = HAL_UART_STATE_BUSY; 02945 02946 /* Enable USART mute mode by setting the MME bit in the CR1 register */ 02947 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME); 02948 02949 huart->gState = HAL_UART_STATE_READY; 02950 02951 return (UART_CheckIdleState(huart)); 02952 } 02953 02954 /** 02955 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode 02956 * as it may not have been in mute mode at this very moment). 02957 * @param huart UART handle. 02958 * @retval HAL status 02959 */ 02960 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) 02961 { 02962 __HAL_LOCK(huart); 02963 02964 huart->gState = HAL_UART_STATE_BUSY; 02965 02966 /* Disable USART mute mode by clearing the MME bit in the CR1 register */ 02967 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); 02968 02969 huart->gState = HAL_UART_STATE_READY; 02970 02971 return (UART_CheckIdleState(huart)); 02972 } 02973 02974 /** 02975 * @brief Enter UART mute mode (means UART actually enters mute mode). 02976 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. 02977 * @param huart UART handle. 02978 * @retval None 02979 */ 02980 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) 02981 { 02982 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); 02983 } 02984 02985 /** 02986 * @brief Enable the UART transmitter and disable the UART receiver. 02987 * @param huart UART handle. 02988 * @retval HAL status 02989 */ 02990 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) 02991 { 02992 __HAL_LOCK(huart); 02993 huart->gState = HAL_UART_STATE_BUSY; 02994 02995 /* Clear TE and RE bits */ 02996 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); 02997 02998 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ 02999 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE); 03000 03001 huart->gState = HAL_UART_STATE_READY; 03002 03003 __HAL_UNLOCK(huart); 03004 03005 return HAL_OK; 03006 } 03007 03008 /** 03009 * @brief Enable the UART receiver and disable the UART transmitter. 03010 * @param huart UART handle. 03011 * @retval HAL status. 03012 */ 03013 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) 03014 { 03015 __HAL_LOCK(huart); 03016 huart->gState = HAL_UART_STATE_BUSY; 03017 03018 /* Clear TE and RE bits */ 03019 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); 03020 03021 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ 03022 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE); 03023 03024 huart->gState = HAL_UART_STATE_READY; 03025 03026 __HAL_UNLOCK(huart); 03027 03028 return HAL_OK; 03029 } 03030 03031 03032 /** 03033 * @brief Transmit break characters. 03034 * @param huart UART handle. 03035 * @retval HAL status 03036 */ 03037 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) 03038 { 03039 /* Check the parameters */ 03040 assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); 03041 03042 __HAL_LOCK(huart); 03043 03044 huart->gState = HAL_UART_STATE_BUSY; 03045 03046 /* Send break characters */ 03047 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST); 03048 03049 huart->gState = HAL_UART_STATE_READY; 03050 03051 __HAL_UNLOCK(huart); 03052 03053 return HAL_OK; 03054 } 03055 03056 /** 03057 * @} 03058 */ 03059 03060 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions 03061 * @brief UART Peripheral State functions 03062 * 03063 @verbatim 03064 ============================================================================== 03065 ##### Peripheral State and Error functions ##### 03066 ============================================================================== 03067 [..] 03068 This subsection provides functions allowing to : 03069 (+) Return the UART handle state. 03070 (+) Return the UART handle error code 03071 03072 @endverbatim 03073 * @{ 03074 */ 03075 03076 /** 03077 * @brief Return the UART handle state. 03078 * @param huart Pointer to a UART_HandleTypeDef structure that contains 03079 * the configuration information for the specified UART. 03080 * @retval HAL state 03081 */ 03082 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) 03083 { 03084 uint32_t temp1; 03085 uint32_t temp2; 03086 temp1 = huart->gState; 03087 temp2 = huart->RxState; 03088 03089 return (HAL_UART_StateTypeDef)(temp1 | temp2); 03090 } 03091 03092 /** 03093 * @brief Return the UART handle error code. 03094 * @param huart Pointer to a UART_HandleTypeDef structure that contains 03095 * the configuration information for the specified UART. 03096 * @retval UART Error Code 03097 */ 03098 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) 03099 { 03100 return huart->ErrorCode; 03101 } 03102 /** 03103 * @} 03104 */ 03105 03106 /** 03107 * @} 03108 */ 03109 03110 /** @defgroup UART_Private_Functions UART Private Functions 03111 * @{ 03112 */ 03113 03114 /** 03115 * @brief Initialize the callbacks to their default values. 03116 * @param huart UART handle. 03117 * @retval none 03118 */ 03119 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03120 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart) 03121 { 03122 /* Init the UART Callback settings */ 03123 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 03124 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ 03125 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 03126 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ 03127 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ 03128 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 03129 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ 03130 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ 03131 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ 03132 #if defined(USART_CR1_FIFOEN) 03133 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ 03134 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ 03135 #endif /* USART_CR1_FIFOEN */ 03136 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */ 03137 03138 } 03139 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03140 03141 /** 03142 * @brief Configure the UART peripheral. 03143 * @param huart UART handle. 03144 * @retval HAL status 03145 */ 03146 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) 03147 { 03148 uint32_t tmpreg; 03149 uint16_t brrtemp; 03150 UART_ClockSourceTypeDef clocksource; 03151 uint32_t usartdiv; 03152 HAL_StatusTypeDef ret = HAL_OK; 03153 #if defined(USART_PRESC_PRESCALER) 03154 uint32_t lpuart_ker_ck_pres; 03155 #endif /* USART_PRESC_PRESCALER */ 03156 uint32_t pclk; 03157 03158 /* Check the parameters */ 03159 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); 03160 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); 03161 if (UART_INSTANCE_LOWPOWER(huart)) 03162 { 03163 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits)); 03164 } 03165 else 03166 { 03167 assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); 03168 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling)); 03169 } 03170 03171 assert_param(IS_UART_PARITY(huart->Init.Parity)); 03172 assert_param(IS_UART_MODE(huart->Init.Mode)); 03173 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); 03174 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); 03175 #if defined(USART_PRESC_PRESCALER) 03176 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler)); 03177 #endif /* USART_PRESC_PRESCALER */ 03178 03179 /*-------------------------- USART CR1 Configuration -----------------------*/ 03180 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure 03181 * the UART Word Length, Parity, Mode and oversampling: 03182 * set the M bits according to huart->Init.WordLength value 03183 * set PCE and PS bits according to huart->Init.Parity value 03184 * set TE and RE bits according to huart->Init.Mode value 03185 * set OVER8 bit according to huart->Init.OverSampling value */ 03186 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ; 03187 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg); 03188 03189 /*-------------------------- USART CR2 Configuration -----------------------*/ 03190 /* Configure the UART Stop Bits: Set STOP[13:12] bits according 03191 * to huart->Init.StopBits value */ 03192 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); 03193 03194 /*-------------------------- USART CR3 Configuration -----------------------*/ 03195 /* Configure 03196 * - UART HardWare Flow Control: set CTSE and RTSE bits according 03197 * to huart->Init.HwFlowCtl value 03198 * - one-bit sampling method versus three samples' majority rule according 03199 * to huart->Init.OneBitSampling (not applicable to LPUART) */ 03200 tmpreg = (uint32_t)huart->Init.HwFlowCtl; 03201 03202 if (!(UART_INSTANCE_LOWPOWER(huart))) 03203 { 03204 tmpreg |= huart->Init.OneBitSampling; 03205 } 03206 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg); 03207 03208 #if defined(USART_PRESC_PRESCALER) 03209 /*-------------------------- USART PRESC Configuration -----------------------*/ 03210 /* Configure 03211 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */ 03212 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler); 03213 #endif /* USART_PRESC_PRESCALER */ 03214 03215 /*-------------------------- USART BRR Configuration -----------------------*/ 03216 UART_GETCLOCKSOURCE(huart, clocksource); 03217 03218 /* Check LPUART instance */ 03219 if (UART_INSTANCE_LOWPOWER(huart)) 03220 { 03221 /* Retrieve frequency clock */ 03222 switch (clocksource) 03223 { 03224 case UART_CLOCKSOURCE_PCLK1: 03225 pclk = HAL_RCC_GetPCLK1Freq(); 03226 break; 03227 case UART_CLOCKSOURCE_HSI: 03228 pclk = (uint32_t) HSI_VALUE; 03229 break; 03230 case UART_CLOCKSOURCE_SYSCLK: 03231 pclk = HAL_RCC_GetSysClockFreq(); 03232 break; 03233 case UART_CLOCKSOURCE_LSE: 03234 pclk = (uint32_t) LSE_VALUE; 03235 break; 03236 default: 03237 pclk = 0U; 03238 ret = HAL_ERROR; 03239 break; 03240 } 03241 03242 /* If proper clock source reported */ 03243 if (pclk != 0U) 03244 { 03245 #if defined(USART_PRESC_PRESCALER) 03246 /* Compute clock after Prescaler */ 03247 lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]); 03248 03249 /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ 03250 if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) || 03251 (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate))) 03252 { 03253 ret = HAL_ERROR; 03254 } 03255 else 03256 { 03257 /* Check computed UsartDiv value is in allocated range 03258 (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */ 03259 usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); 03260 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) 03261 { 03262 huart->Instance->BRR = usartdiv; 03263 } 03264 else 03265 { 03266 ret = HAL_ERROR; 03267 } 03268 } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || 03269 (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */ 03270 #else 03271 /* No Prescaler applicable */ 03272 /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ 03273 if ((pclk < (3U * huart->Init.BaudRate)) || 03274 (pclk > (4096U * huart->Init.BaudRate))) 03275 { 03276 ret = HAL_ERROR; 03277 } 03278 else 03279 { 03280 usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate)); 03281 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) 03282 { 03283 huart->Instance->BRR = usartdiv; 03284 } 03285 else 03286 { 03287 ret = HAL_ERROR; 03288 } 03289 } /* if ( (pclk < (3 * huart->Init.BaudRate) ) || (pclk > (4096 * huart->Init.BaudRate) )) */ 03290 #endif /* USART_PRESC_PRESCALER */ 03291 } /* if (pclk != 0) */ 03292 } 03293 /* Check UART Over Sampling to set Baud Rate Register */ 03294 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) 03295 { 03296 switch (clocksource) 03297 { 03298 case UART_CLOCKSOURCE_PCLK1: 03299 pclk = HAL_RCC_GetPCLK1Freq(); 03300 break; 03301 case UART_CLOCKSOURCE_PCLK2: 03302 pclk = HAL_RCC_GetPCLK2Freq(); 03303 break; 03304 case UART_CLOCKSOURCE_HSI: 03305 pclk = (uint32_t) HSI_VALUE; 03306 break; 03307 case UART_CLOCKSOURCE_SYSCLK: 03308 pclk = HAL_RCC_GetSysClockFreq(); 03309 break; 03310 case UART_CLOCKSOURCE_LSE: 03311 pclk = (uint32_t) LSE_VALUE; 03312 break; 03313 default: 03314 pclk = 0U; 03315 ret = HAL_ERROR; 03316 break; 03317 } 03318 03319 /* USARTDIV must be greater than or equal to 0d16 */ 03320 if (pclk != 0U) 03321 { 03322 #if defined(USART_PRESC_PRESCALER) 03323 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); 03324 #else 03325 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate)); 03326 #endif /* USART_PRESC_PRESCALER */ 03327 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) 03328 { 03329 brrtemp = (uint16_t)(usartdiv & 0xFFF0U); 03330 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); 03331 huart->Instance->BRR = brrtemp; 03332 } 03333 else 03334 { 03335 ret = HAL_ERROR; 03336 } 03337 } 03338 } 03339 else 03340 { 03341 switch (clocksource) 03342 { 03343 case UART_CLOCKSOURCE_PCLK1: 03344 pclk = HAL_RCC_GetPCLK1Freq(); 03345 break; 03346 case UART_CLOCKSOURCE_PCLK2: 03347 pclk = HAL_RCC_GetPCLK2Freq(); 03348 break; 03349 case UART_CLOCKSOURCE_HSI: 03350 pclk = (uint32_t) HSI_VALUE; 03351 break; 03352 case UART_CLOCKSOURCE_SYSCLK: 03353 pclk = HAL_RCC_GetSysClockFreq(); 03354 break; 03355 case UART_CLOCKSOURCE_LSE: 03356 pclk = (uint32_t) LSE_VALUE; 03357 break; 03358 default: 03359 pclk = 0U; 03360 ret = HAL_ERROR; 03361 break; 03362 } 03363 03364 if (pclk != 0U) 03365 { 03366 /* USARTDIV must be greater than or equal to 0d16 */ 03367 #if defined(USART_PRESC_PRESCALER) 03368 usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); 03369 #else 03370 usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate)); 03371 #endif /* USART_PRESC_PRESCALER */ 03372 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) 03373 { 03374 huart->Instance->BRR = (uint16_t)usartdiv; 03375 } 03376 else 03377 { 03378 ret = HAL_ERROR; 03379 } 03380 } 03381 } 03382 03383 #if defined(USART_CR1_FIFOEN) 03384 /* Initialize the number of data to process during RX/TX ISR execution */ 03385 huart->NbTxDataToProcess = 1; 03386 huart->NbRxDataToProcess = 1; 03387 #endif /* USART_CR1_FIFOEN */ 03388 03389 /* Clear ISR function pointers */ 03390 huart->RxISR = NULL; 03391 huart->TxISR = NULL; 03392 03393 return ret; 03394 } 03395 03396 /** 03397 * @brief Configure the UART peripheral advanced features. 03398 * @param huart UART handle. 03399 * @retval None 03400 */ 03401 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) 03402 { 03403 /* Check whether the set of advanced features to configure is properly set */ 03404 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); 03405 03406 /* if required, configure TX pin active level inversion */ 03407 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) 03408 { 03409 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); 03410 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); 03411 } 03412 03413 /* if required, configure RX pin active level inversion */ 03414 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) 03415 { 03416 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); 03417 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); 03418 } 03419 03420 /* if required, configure data inversion */ 03421 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) 03422 { 03423 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); 03424 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); 03425 } 03426 03427 /* if required, configure RX/TX pins swap */ 03428 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) 03429 { 03430 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); 03431 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); 03432 } 03433 03434 /* if required, configure RX overrun detection disabling */ 03435 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) 03436 { 03437 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); 03438 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); 03439 } 03440 03441 /* if required, configure DMA disabling on reception error */ 03442 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) 03443 { 03444 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); 03445 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); 03446 } 03447 03448 /* if required, configure auto Baud rate detection scheme */ 03449 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) 03450 { 03451 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); 03452 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); 03453 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); 03454 /* set auto Baudrate detection parameters if detection is enabled */ 03455 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) 03456 { 03457 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); 03458 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); 03459 } 03460 } 03461 03462 /* if required, configure MSB first on communication line */ 03463 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) 03464 { 03465 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); 03466 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); 03467 } 03468 } 03469 03470 /** 03471 * @brief Check the UART Idle State. 03472 * @param huart UART handle. 03473 * @retval HAL status 03474 */ 03475 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) 03476 { 03477 uint32_t tickstart; 03478 03479 /* Initialize the UART ErrorCode */ 03480 huart->ErrorCode = HAL_UART_ERROR_NONE; 03481 03482 /* Init tickstart for timeout management */ 03483 tickstart = HAL_GetTick(); 03484 03485 /* Check if the Transmitter is enabled */ 03486 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 03487 { 03488 /* Wait until TEACK flag is set */ 03489 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 03490 { 03491 /* Timeout occurred */ 03492 return HAL_TIMEOUT; 03493 } 03494 } 03495 03496 /* Check if the Receiver is enabled */ 03497 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 03498 { 03499 /* Wait until REACK flag is set */ 03500 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 03501 { 03502 /* Timeout occurred */ 03503 return HAL_TIMEOUT; 03504 } 03505 } 03506 03507 /* Initialize the UART State */ 03508 huart->gState = HAL_UART_STATE_READY; 03509 huart->RxState = HAL_UART_STATE_READY; 03510 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 03511 03512 __HAL_UNLOCK(huart); 03513 03514 return HAL_OK; 03515 } 03516 03517 /** 03518 * @brief This function handles UART Communication Timeout. It waits 03519 * until a flag is no longer in the specified status. 03520 * @param huart UART handle. 03521 * @param Flag Specifies the UART flag to check 03522 * @param Status The actual Flag status (SET or RESET) 03523 * @param Tickstart Tick start value 03524 * @param Timeout Timeout duration 03525 * @retval HAL status 03526 */ 03527 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, 03528 uint32_t Tickstart, uint32_t Timeout) 03529 { 03530 /* Wait until flag is set */ 03531 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) 03532 { 03533 /* Check for the Timeout */ 03534 if (Timeout != HAL_MAX_DELAY) 03535 { 03536 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 03537 { 03538 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) 03539 interrupts for the interrupt process */ 03540 #if defined(USART_CR1_FIFOEN) 03541 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | 03542 USART_CR1_TXEIE_TXFNFIE)); 03543 #else 03544 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 03545 #endif /* USART_CR1_FIFOEN */ 03546 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 03547 03548 huart->gState = HAL_UART_STATE_READY; 03549 huart->RxState = HAL_UART_STATE_READY; 03550 03551 __HAL_UNLOCK(huart); 03552 03553 return HAL_TIMEOUT; 03554 } 03555 03556 if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) 03557 { 03558 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET) 03559 { 03560 /* Clear Receiver Timeout flag*/ 03561 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); 03562 03563 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) 03564 interrupts for the interrupt process */ 03565 #if defined(USART_CR1_FIFOEN) 03566 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | 03567 USART_CR1_TXEIE_TXFNFIE)); 03568 #else 03569 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 03570 #endif 03571 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 03572 03573 huart->gState = HAL_UART_STATE_READY; 03574 huart->RxState = HAL_UART_STATE_READY; 03575 huart->ErrorCode = HAL_UART_ERROR_RTO; 03576 03577 /* Process Unlocked */ 03578 __HAL_UNLOCK(huart); 03579 03580 return HAL_TIMEOUT; 03581 } 03582 } 03583 } 03584 } 03585 return HAL_OK; 03586 } 03587 03588 /** 03589 * @brief Start Receive operation in interrupt mode. 03590 * @note This function could be called by all HAL UART API providing reception in Interrupt mode. 03591 * @note When calling this function, parameters validity is considered as already checked, 03592 * i.e. Rx State, buffer address, ... 03593 * UART Handle is assumed as Locked. 03594 * @param huart UART handle. 03595 * @param pData Pointer to data buffer (u8 or u16 data elements). 03596 * @param Size Amount of data elements (u8 or u16) to be received. 03597 * @retval HAL status 03598 */ 03599 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 03600 { 03601 huart->pRxBuffPtr = pData; 03602 huart->RxXferSize = Size; 03603 huart->RxXferCount = Size; 03604 huart->RxISR = NULL; 03605 03606 /* Computation of UART mask to apply to RDR register */ 03607 UART_MASK_COMPUTATION(huart); 03608 03609 huart->ErrorCode = HAL_UART_ERROR_NONE; 03610 huart->RxState = HAL_UART_STATE_BUSY_RX; 03611 03612 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 03613 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 03614 03615 #if defined(USART_CR1_FIFOEN) 03616 /* Configure Rx interrupt processing */ 03617 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) 03618 { 03619 /* Set the Rx ISR function pointer according to the data word length */ 03620 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 03621 { 03622 huart->RxISR = UART_RxISR_16BIT_FIFOEN; 03623 } 03624 else 03625 { 03626 huart->RxISR = UART_RxISR_8BIT_FIFOEN; 03627 } 03628 03629 __HAL_UNLOCK(huart); 03630 03631 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ 03632 if (huart->Init.Parity != UART_PARITY_NONE) 03633 { 03634 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 03635 } 03636 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); 03637 } 03638 else 03639 { 03640 /* Set the Rx ISR function pointer according to the data word length */ 03641 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 03642 { 03643 huart->RxISR = UART_RxISR_16BIT; 03644 } 03645 else 03646 { 03647 huart->RxISR = UART_RxISR_8BIT; 03648 } 03649 03650 __HAL_UNLOCK(huart); 03651 03652 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ 03653 if (huart->Init.Parity != UART_PARITY_NONE) 03654 { 03655 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); 03656 } 03657 else 03658 { 03659 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); 03660 } 03661 } 03662 #else 03663 /* Set the Rx ISR function pointer according to the data word length */ 03664 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 03665 { 03666 huart->RxISR = UART_RxISR_16BIT; 03667 } 03668 else 03669 { 03670 huart->RxISR = UART_RxISR_8BIT; 03671 } 03672 03673 __HAL_UNLOCK(huart); 03674 03675 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ 03676 if (huart->Init.Parity != UART_PARITY_NONE) 03677 { 03678 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); 03679 } 03680 else 03681 { 03682 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE); 03683 } 03684 #endif /* USART_CR1_FIFOEN */ 03685 return HAL_OK; 03686 } 03687 03688 /** 03689 * @brief Start Receive operation in DMA mode. 03690 * @note This function could be called by all HAL UART API providing reception in DMA mode. 03691 * @note When calling this function, parameters validity is considered as already checked, 03692 * i.e. Rx State, buffer address, ... 03693 * UART Handle is assumed as Locked. 03694 * @param huart UART handle. 03695 * @param pData Pointer to data buffer (u8 or u16 data elements). 03696 * @param Size Amount of data elements (u8 or u16) to be received. 03697 * @retval HAL status 03698 */ 03699 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 03700 { 03701 huart->pRxBuffPtr = pData; 03702 huart->RxXferSize = Size; 03703 03704 huart->ErrorCode = HAL_UART_ERROR_NONE; 03705 huart->RxState = HAL_UART_STATE_BUSY_RX; 03706 03707 if (huart->hdmarx != NULL) 03708 { 03709 /* Set the UART DMA transfer complete callback */ 03710 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; 03711 03712 /* Set the UART DMA Half transfer complete callback */ 03713 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; 03714 03715 /* Set the DMA error callback */ 03716 huart->hdmarx->XferErrorCallback = UART_DMAError; 03717 03718 /* Set the DMA abort callback */ 03719 huart->hdmarx->XferAbortCallback = NULL; 03720 03721 /* Enable the DMA channel */ 03722 if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK) 03723 { 03724 /* Set error code to DMA */ 03725 huart->ErrorCode = HAL_UART_ERROR_DMA; 03726 03727 __HAL_UNLOCK(huart); 03728 03729 /* Restore huart->RxState to ready */ 03730 huart->RxState = HAL_UART_STATE_READY; 03731 03732 return HAL_ERROR; 03733 } 03734 } 03735 __HAL_UNLOCK(huart); 03736 03737 /* Enable the UART Parity Error Interrupt */ 03738 if (huart->Init.Parity != UART_PARITY_NONE) 03739 { 03740 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); 03741 } 03742 03743 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 03744 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); 03745 03746 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 03747 in the UART CR3 register */ 03748 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); 03749 03750 return HAL_OK; 03751 } 03752 03753 03754 /** 03755 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). 03756 * @param huart UART handle. 03757 * @retval None 03758 */ 03759 static void UART_EndTxTransfer(UART_HandleTypeDef *huart) 03760 { 03761 #if defined(USART_CR1_FIFOEN) 03762 /* Disable TXEIE, TCIE, TXFT interrupts */ 03763 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 03764 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE)); 03765 #else 03766 /* Disable TXEIE and TCIE interrupts */ 03767 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 03768 #endif /* USART_CR1_FIFOEN */ 03769 03770 /* At end of Tx process, restore huart->gState to Ready */ 03771 huart->gState = HAL_UART_STATE_READY; 03772 } 03773 03774 03775 /** 03776 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). 03777 * @param huart UART handle. 03778 * @retval None 03779 */ 03780 static void UART_EndRxTransfer(UART_HandleTypeDef *huart) 03781 { 03782 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 03783 #if defined(USART_CR1_FIFOEN) 03784 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 03785 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); 03786 #else 03787 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 03788 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 03789 #endif /* USART_CR1_FIFOEN */ 03790 03791 /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */ 03792 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 03793 { 03794 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 03795 } 03796 03797 /* At end of Rx process, restore huart->RxState to Ready */ 03798 huart->RxState = HAL_UART_STATE_READY; 03799 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 03800 03801 /* Reset RxIsr function pointer */ 03802 huart->RxISR = NULL; 03803 } 03804 03805 03806 /** 03807 * @brief DMA UART transmit process complete callback. 03808 * @param hdma DMA handle. 03809 * @retval None 03810 */ 03811 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) 03812 { 03813 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03814 03815 /* DMA Normal mode */ 03816 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) 03817 { 03818 huart->TxXferCount = 0U; 03819 03820 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 03821 in the UART CR3 register */ 03822 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); 03823 03824 /* Enable the UART Transmit Complete Interrupt */ 03825 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 03826 } 03827 /* DMA Circular mode */ 03828 else 03829 { 03830 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03831 /*Call registered Tx complete callback*/ 03832 huart->TxCpltCallback(huart); 03833 #else 03834 /*Call legacy weak Tx complete callback*/ 03835 HAL_UART_TxCpltCallback(huart); 03836 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03837 } 03838 } 03839 03840 /** 03841 * @brief DMA UART transmit process half complete callback. 03842 * @param hdma DMA handle. 03843 * @retval None 03844 */ 03845 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 03846 { 03847 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03848 03849 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03850 /*Call registered Tx Half complete callback*/ 03851 huart->TxHalfCpltCallback(huart); 03852 #else 03853 /*Call legacy weak Tx Half complete callback*/ 03854 HAL_UART_TxHalfCpltCallback(huart); 03855 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03856 } 03857 03858 /** 03859 * @brief DMA UART receive process complete callback. 03860 * @param hdma DMA handle. 03861 * @retval None 03862 */ 03863 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 03864 { 03865 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03866 03867 /* DMA Normal mode */ 03868 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) 03869 { 03870 huart->RxXferCount = 0U; 03871 03872 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 03873 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 03874 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 03875 03876 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 03877 in the UART CR3 register */ 03878 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); 03879 03880 /* At end of Rx process, restore huart->RxState to Ready */ 03881 huart->RxState = HAL_UART_STATE_READY; 03882 03883 /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ 03884 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 03885 { 03886 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 03887 } 03888 } 03889 03890 /* Check current reception Mode : 03891 If Reception till IDLE event has been selected : use Rx Event callback */ 03892 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 03893 { 03894 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03895 /*Call registered Rx Event callback*/ 03896 huart->RxEventCallback(huart, huart->RxXferSize); 03897 #else 03898 /*Call legacy weak Rx Event callback*/ 03899 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 03900 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03901 } 03902 else 03903 { 03904 /* In other cases : use Rx Complete callback */ 03905 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03906 /*Call registered Rx complete callback*/ 03907 huart->RxCpltCallback(huart); 03908 #else 03909 /*Call legacy weak Rx complete callback*/ 03910 HAL_UART_RxCpltCallback(huart); 03911 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03912 } 03913 } 03914 03915 /** 03916 * @brief DMA UART receive process half complete callback. 03917 * @param hdma DMA handle. 03918 * @retval None 03919 */ 03920 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 03921 { 03922 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03923 03924 /* Check current reception Mode : 03925 If Reception till IDLE event has been selected : use Rx Event callback */ 03926 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 03927 { 03928 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03929 /*Call registered Rx Event callback*/ 03930 huart->RxEventCallback(huart, huart->RxXferSize / 2U); 03931 #else 03932 /*Call legacy weak Rx Event callback*/ 03933 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U); 03934 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03935 } 03936 else 03937 { 03938 /* In other cases : use Rx Half Complete callback */ 03939 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03940 /*Call registered Rx Half complete callback*/ 03941 huart->RxHalfCpltCallback(huart); 03942 #else 03943 /*Call legacy weak Rx Half complete callback*/ 03944 HAL_UART_RxHalfCpltCallback(huart); 03945 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03946 } 03947 } 03948 03949 /** 03950 * @brief DMA UART communication error callback. 03951 * @param hdma DMA handle. 03952 * @retval None 03953 */ 03954 static void UART_DMAError(DMA_HandleTypeDef *hdma) 03955 { 03956 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03957 03958 const HAL_UART_StateTypeDef gstate = huart->gState; 03959 const HAL_UART_StateTypeDef rxstate = huart->RxState; 03960 03961 /* Stop UART DMA Tx request if ongoing */ 03962 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && 03963 (gstate == HAL_UART_STATE_BUSY_TX)) 03964 { 03965 huart->TxXferCount = 0U; 03966 UART_EndTxTransfer(huart); 03967 } 03968 03969 /* Stop UART DMA Rx request if ongoing */ 03970 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && 03971 (rxstate == HAL_UART_STATE_BUSY_RX)) 03972 { 03973 huart->RxXferCount = 0U; 03974 UART_EndRxTransfer(huart); 03975 } 03976 03977 huart->ErrorCode |= HAL_UART_ERROR_DMA; 03978 03979 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 03980 /*Call registered error callback*/ 03981 huart->ErrorCallback(huart); 03982 #else 03983 /*Call legacy weak error callback*/ 03984 HAL_UART_ErrorCallback(huart); 03985 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 03986 } 03987 03988 /** 03989 * @brief DMA UART communication abort callback, when initiated by HAL services on Error 03990 * (To be called at end of DMA Abort procedure following error occurrence). 03991 * @param hdma DMA handle. 03992 * @retval None 03993 */ 03994 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) 03995 { 03996 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 03997 huart->RxXferCount = 0U; 03998 huart->TxXferCount = 0U; 03999 04000 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04001 /*Call registered error callback*/ 04002 huart->ErrorCallback(huart); 04003 #else 04004 /*Call legacy weak error callback*/ 04005 HAL_UART_ErrorCallback(huart); 04006 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04007 } 04008 04009 /** 04010 * @brief DMA UART Tx communication abort callback, when initiated by user 04011 * (To be called at end of DMA Tx Abort procedure following user abort request). 04012 * @note When this callback is executed, User Abort complete call back is called only if no 04013 * Abort still ongoing for Rx DMA Handle. 04014 * @param hdma DMA handle. 04015 * @retval None 04016 */ 04017 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) 04018 { 04019 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 04020 04021 huart->hdmatx->XferAbortCallback = NULL; 04022 04023 /* Check if an Abort process is still ongoing */ 04024 if (huart->hdmarx != NULL) 04025 { 04026 if (huart->hdmarx->XferAbortCallback != NULL) 04027 { 04028 return; 04029 } 04030 } 04031 04032 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 04033 huart->TxXferCount = 0U; 04034 huart->RxXferCount = 0U; 04035 04036 /* Reset errorCode */ 04037 huart->ErrorCode = HAL_UART_ERROR_NONE; 04038 04039 /* Clear the Error flags in the ICR register */ 04040 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 04041 04042 #if defined(USART_CR1_FIFOEN) 04043 /* Flush the whole TX FIFO (if needed) */ 04044 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 04045 { 04046 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 04047 } 04048 #endif /* USART_CR1_FIFOEN */ 04049 04050 /* Restore huart->gState and huart->RxState to Ready */ 04051 huart->gState = HAL_UART_STATE_READY; 04052 huart->RxState = HAL_UART_STATE_READY; 04053 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04054 04055 /* Call user Abort complete callback */ 04056 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04057 /* Call registered Abort complete callback */ 04058 huart->AbortCpltCallback(huart); 04059 #else 04060 /* Call legacy weak Abort complete callback */ 04061 HAL_UART_AbortCpltCallback(huart); 04062 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04063 } 04064 04065 04066 /** 04067 * @brief DMA UART Rx communication abort callback, when initiated by user 04068 * (To be called at end of DMA Rx Abort procedure following user abort request). 04069 * @note When this callback is executed, User Abort complete call back is called only if no 04070 * Abort still ongoing for Tx DMA Handle. 04071 * @param hdma DMA handle. 04072 * @retval None 04073 */ 04074 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) 04075 { 04076 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 04077 04078 huart->hdmarx->XferAbortCallback = NULL; 04079 04080 /* Check if an Abort process is still ongoing */ 04081 if (huart->hdmatx != NULL) 04082 { 04083 if (huart->hdmatx->XferAbortCallback != NULL) 04084 { 04085 return; 04086 } 04087 } 04088 04089 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 04090 huart->TxXferCount = 0U; 04091 huart->RxXferCount = 0U; 04092 04093 /* Reset errorCode */ 04094 huart->ErrorCode = HAL_UART_ERROR_NONE; 04095 04096 /* Clear the Error flags in the ICR register */ 04097 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 04098 04099 /* Discard the received data */ 04100 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04101 04102 /* Restore huart->gState and huart->RxState to Ready */ 04103 huart->gState = HAL_UART_STATE_READY; 04104 huart->RxState = HAL_UART_STATE_READY; 04105 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04106 04107 /* Call user Abort complete callback */ 04108 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04109 /* Call registered Abort complete callback */ 04110 huart->AbortCpltCallback(huart); 04111 #else 04112 /* Call legacy weak Abort complete callback */ 04113 HAL_UART_AbortCpltCallback(huart); 04114 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04115 } 04116 04117 04118 /** 04119 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to 04120 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) 04121 * (This callback is executed at end of DMA Tx Abort procedure following user abort request, 04122 * and leads to user Tx Abort Complete callback execution). 04123 * @param hdma DMA handle. 04124 * @retval None 04125 */ 04126 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 04127 { 04128 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); 04129 04130 huart->TxXferCount = 0U; 04131 04132 #if defined(USART_CR1_FIFOEN) 04133 /* Flush the whole TX FIFO (if needed) */ 04134 if (huart->FifoMode == UART_FIFOMODE_ENABLE) 04135 { 04136 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); 04137 } 04138 #endif /* USART_CR1_FIFOEN */ 04139 04140 /* Restore huart->gState to Ready */ 04141 huart->gState = HAL_UART_STATE_READY; 04142 04143 /* Call user Abort complete callback */ 04144 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04145 /* Call registered Abort Transmit Complete Callback */ 04146 huart->AbortTransmitCpltCallback(huart); 04147 #else 04148 /* Call legacy weak Abort Transmit Complete Callback */ 04149 HAL_UART_AbortTransmitCpltCallback(huart); 04150 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04151 } 04152 04153 /** 04154 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to 04155 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) 04156 * (This callback is executed at end of DMA Rx Abort procedure following user abort request, 04157 * and leads to user Rx Abort Complete callback execution). 04158 * @param hdma DMA handle. 04159 * @retval None 04160 */ 04161 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 04162 { 04163 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 04164 04165 huart->RxXferCount = 0U; 04166 04167 /* Clear the Error flags in the ICR register */ 04168 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); 04169 04170 /* Discard the received data */ 04171 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04172 04173 /* Restore huart->RxState to Ready */ 04174 huart->RxState = HAL_UART_STATE_READY; 04175 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04176 04177 /* Call user Abort complete callback */ 04178 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04179 /* Call registered Abort Receive Complete Callback */ 04180 huart->AbortReceiveCpltCallback(huart); 04181 #else 04182 /* Call legacy weak Abort Receive Complete Callback */ 04183 HAL_UART_AbortReceiveCpltCallback(huart); 04184 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04185 } 04186 04187 /** 04188 * @brief TX interrupt handler for 7 or 8 bits data word length . 04189 * @note Function is called under interruption only, once 04190 * interruptions have been enabled by HAL_UART_Transmit_IT(). 04191 * @param huart UART handle. 04192 * @retval None 04193 */ 04194 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) 04195 { 04196 /* Check that a Tx process is ongoing */ 04197 if (huart->gState == HAL_UART_STATE_BUSY_TX) 04198 { 04199 if (huart->TxXferCount == 0U) 04200 { 04201 /* Disable the UART Transmit Data Register Empty Interrupt */ 04202 #if defined(USART_CR1_FIFOEN) 04203 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); 04204 #else 04205 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 04206 #endif /* USART_CR1_FIFOEN */ 04207 04208 /* Enable the UART Transmit Complete Interrupt */ 04209 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 04210 } 04211 else 04212 { 04213 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); 04214 huart->pTxBuffPtr++; 04215 huart->TxXferCount--; 04216 } 04217 } 04218 } 04219 04220 /** 04221 * @brief TX interrupt handler for 9 bits data word length. 04222 * @note Function is called under interruption only, once 04223 * interruptions have been enabled by HAL_UART_Transmit_IT(). 04224 * @param huart UART handle. 04225 * @retval None 04226 */ 04227 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) 04228 { 04229 const uint16_t *tmp; 04230 04231 /* Check that a Tx process is ongoing */ 04232 if (huart->gState == HAL_UART_STATE_BUSY_TX) 04233 { 04234 if (huart->TxXferCount == 0U) 04235 { 04236 /* Disable the UART Transmit Data Register Empty Interrupt */ 04237 #if defined(USART_CR1_FIFOEN) 04238 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); 04239 #else 04240 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 04241 #endif /* USART_CR1_FIFOEN */ 04242 04243 /* Enable the UART Transmit Complete Interrupt */ 04244 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 04245 } 04246 else 04247 { 04248 tmp = (const uint16_t *) huart->pTxBuffPtr; 04249 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); 04250 huart->pTxBuffPtr += 2U; 04251 huart->TxXferCount--; 04252 } 04253 } 04254 } 04255 04256 #if defined(USART_CR1_FIFOEN) 04257 /** 04258 * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. 04259 * @note Function is called under interruption only, once 04260 * interruptions have been enabled by HAL_UART_Transmit_IT(). 04261 * @param huart UART handle. 04262 * @retval None 04263 */ 04264 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) 04265 { 04266 uint16_t nb_tx_data; 04267 04268 /* Check that a Tx process is ongoing */ 04269 if (huart->gState == HAL_UART_STATE_BUSY_TX) 04270 { 04271 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) 04272 { 04273 if (huart->TxXferCount == 0U) 04274 { 04275 /* Disable the TX FIFO threshold interrupt */ 04276 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); 04277 04278 /* Enable the UART Transmit Complete Interrupt */ 04279 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 04280 04281 break; /* force exit loop */ 04282 } 04283 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) 04284 { 04285 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); 04286 huart->pTxBuffPtr++; 04287 huart->TxXferCount--; 04288 } 04289 else 04290 { 04291 /* Nothing to do */ 04292 } 04293 } 04294 } 04295 } 04296 04297 /** 04298 * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled. 04299 * @note Function is called under interruption only, once 04300 * interruptions have been enabled by HAL_UART_Transmit_IT(). 04301 * @param huart UART handle. 04302 * @retval None 04303 */ 04304 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) 04305 { 04306 const uint16_t *tmp; 04307 uint16_t nb_tx_data; 04308 04309 /* Check that a Tx process is ongoing */ 04310 if (huart->gState == HAL_UART_STATE_BUSY_TX) 04311 { 04312 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) 04313 { 04314 if (huart->TxXferCount == 0U) 04315 { 04316 /* Disable the TX FIFO threshold interrupt */ 04317 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); 04318 04319 /* Enable the UART Transmit Complete Interrupt */ 04320 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); 04321 04322 break; /* force exit loop */ 04323 } 04324 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) 04325 { 04326 tmp = (const uint16_t *) huart->pTxBuffPtr; 04327 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); 04328 huart->pTxBuffPtr += 2U; 04329 huart->TxXferCount--; 04330 } 04331 else 04332 { 04333 /* Nothing to do */ 04334 } 04335 } 04336 } 04337 } 04338 #endif /* USART_CR1_FIFOEN */ 04339 04340 /** 04341 * @brief Wrap up transmission in non-blocking mode. 04342 * @param huart pointer to a UART_HandleTypeDef structure that contains 04343 * the configuration information for the specified UART module. 04344 * @retval None 04345 */ 04346 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart) 04347 { 04348 /* Disable the UART Transmit Complete Interrupt */ 04349 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); 04350 04351 /* Tx process is ended, restore huart->gState to Ready */ 04352 huart->gState = HAL_UART_STATE_READY; 04353 04354 /* Cleat TxISR function pointer */ 04355 huart->TxISR = NULL; 04356 04357 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04358 /*Call registered Tx complete callback*/ 04359 huart->TxCpltCallback(huart); 04360 #else 04361 /*Call legacy weak Tx complete callback*/ 04362 HAL_UART_TxCpltCallback(huart); 04363 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04364 } 04365 04366 /** 04367 * @brief RX interrupt handler for 7 or 8 bits data word length . 04368 * @param huart UART handle. 04369 * @retval None 04370 */ 04371 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) 04372 { 04373 uint16_t uhMask = huart->Mask; 04374 uint16_t uhdata; 04375 04376 /* Check that a Rx process is ongoing */ 04377 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 04378 { 04379 uhdata = (uint16_t) READ_REG(huart->Instance->RDR); 04380 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); 04381 huart->pRxBuffPtr++; 04382 huart->RxXferCount--; 04383 04384 if (huart->RxXferCount == 0U) 04385 { 04386 /* Disable the UART Parity Error Interrupt and RXNE interrupts */ 04387 #if defined(USART_CR1_FIFOEN) 04388 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 04389 #else 04390 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 04391 #endif /* USART_CR1_FIFOEN */ 04392 04393 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 04394 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 04395 04396 /* Rx process is completed, restore huart->RxState to Ready */ 04397 huart->RxState = HAL_UART_STATE_READY; 04398 04399 /* Clear RxISR function pointer */ 04400 huart->RxISR = NULL; 04401 04402 /* Check current reception Mode : 04403 If Reception till IDLE event has been selected : */ 04404 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 04405 { 04406 /* Set reception type to Standard */ 04407 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04408 04409 /* Disable IDLE interrupt */ 04410 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 04411 04412 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) 04413 { 04414 /* Clear IDLE Flag */ 04415 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 04416 } 04417 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04418 /*Call registered Rx Event callback*/ 04419 huart->RxEventCallback(huart, huart->RxXferSize); 04420 #else 04421 /*Call legacy weak Rx Event callback*/ 04422 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 04423 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 04424 } 04425 else 04426 { 04427 /* Standard reception API called */ 04428 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04429 /*Call registered Rx complete callback*/ 04430 huart->RxCpltCallback(huart); 04431 #else 04432 /*Call legacy weak Rx complete callback*/ 04433 HAL_UART_RxCpltCallback(huart); 04434 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04435 } 04436 } 04437 } 04438 else 04439 { 04440 /* Clear RXNE interrupt flag */ 04441 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04442 } 04443 } 04444 04445 /** 04446 * @brief RX interrupt handler for 9 bits data word length . 04447 * @note Function is called under interruption only, once 04448 * interruptions have been enabled by HAL_UART_Receive_IT() 04449 * @param huart UART handle. 04450 * @retval None 04451 */ 04452 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) 04453 { 04454 uint16_t *tmp; 04455 uint16_t uhMask = huart->Mask; 04456 uint16_t uhdata; 04457 04458 /* Check that a Rx process is ongoing */ 04459 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 04460 { 04461 uhdata = (uint16_t) READ_REG(huart->Instance->RDR); 04462 tmp = (uint16_t *) huart->pRxBuffPtr ; 04463 *tmp = (uint16_t)(uhdata & uhMask); 04464 huart->pRxBuffPtr += 2U; 04465 huart->RxXferCount--; 04466 04467 if (huart->RxXferCount == 0U) 04468 { 04469 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ 04470 #if defined(USART_CR1_FIFOEN) 04471 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 04472 #else 04473 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 04474 #endif /* USART_CR1_FIFOEN */ 04475 04476 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 04477 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); 04478 04479 /* Rx process is completed, restore huart->RxState to Ready */ 04480 huart->RxState = HAL_UART_STATE_READY; 04481 04482 /* Clear RxISR function pointer */ 04483 huart->RxISR = NULL; 04484 04485 /* Check current reception Mode : 04486 If Reception till IDLE event has been selected : */ 04487 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 04488 { 04489 /* Set reception type to Standard */ 04490 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04491 04492 /* Disable IDLE interrupt */ 04493 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 04494 04495 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) 04496 { 04497 /* Clear IDLE Flag */ 04498 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 04499 } 04500 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04501 /*Call registered Rx Event callback*/ 04502 huart->RxEventCallback(huart, huart->RxXferSize); 04503 #else 04504 /*Call legacy weak Rx Event callback*/ 04505 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 04506 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 04507 } 04508 else 04509 { 04510 /* Standard reception API called */ 04511 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04512 /*Call registered Rx complete callback*/ 04513 huart->RxCpltCallback(huart); 04514 #else 04515 /*Call legacy weak Rx complete callback*/ 04516 HAL_UART_RxCpltCallback(huart); 04517 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04518 } 04519 } 04520 } 04521 else 04522 { 04523 /* Clear RXNE interrupt flag */ 04524 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04525 } 04526 } 04527 04528 #if defined(USART_CR1_FIFOEN) 04529 /** 04530 * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. 04531 * @note Function is called under interruption only, once 04532 * interruptions have been enabled by HAL_UART_Receive_IT() 04533 * @param huart UART handle. 04534 * @retval None 04535 */ 04536 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) 04537 { 04538 uint16_t uhMask = huart->Mask; 04539 uint16_t uhdata; 04540 uint16_t nb_rx_data; 04541 uint16_t rxdatacount; 04542 uint32_t isrflags = READ_REG(huart->Instance->ISR); 04543 uint32_t cr1its = READ_REG(huart->Instance->CR1); 04544 uint32_t cr3its = READ_REG(huart->Instance->CR3); 04545 04546 /* Check that a Rx process is ongoing */ 04547 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 04548 { 04549 nb_rx_data = huart->NbRxDataToProcess; 04550 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) 04551 { 04552 uhdata = (uint16_t) READ_REG(huart->Instance->RDR); 04553 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); 04554 huart->pRxBuffPtr++; 04555 huart->RxXferCount--; 04556 isrflags = READ_REG(huart->Instance->ISR); 04557 04558 /* If some non blocking errors occurred */ 04559 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) 04560 { 04561 /* UART parity error interrupt occurred -------------------------------------*/ 04562 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) 04563 { 04564 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); 04565 04566 huart->ErrorCode |= HAL_UART_ERROR_PE; 04567 } 04568 04569 /* UART frame error interrupt occurred --------------------------------------*/ 04570 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 04571 { 04572 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); 04573 04574 huart->ErrorCode |= HAL_UART_ERROR_FE; 04575 } 04576 04577 /* UART noise error interrupt occurred --------------------------------------*/ 04578 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 04579 { 04580 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); 04581 04582 huart->ErrorCode |= HAL_UART_ERROR_NE; 04583 } 04584 04585 /* Call UART Error Call back function if need be ----------------------------*/ 04586 if (huart->ErrorCode != HAL_UART_ERROR_NONE) 04587 { 04588 /* Non Blocking error : transfer could go on. 04589 Error is notified to user through user error callback */ 04590 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04591 /*Call registered error callback*/ 04592 huart->ErrorCallback(huart); 04593 #else 04594 /*Call legacy weak error callback*/ 04595 HAL_UART_ErrorCallback(huart); 04596 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04597 huart->ErrorCode = HAL_UART_ERROR_NONE; 04598 } 04599 } 04600 04601 if (huart->RxXferCount == 0U) 04602 { 04603 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ 04604 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 04605 04606 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) 04607 and RX FIFO Threshold interrupt */ 04608 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); 04609 04610 /* Rx process is completed, restore huart->RxState to Ready */ 04611 huart->RxState = HAL_UART_STATE_READY; 04612 04613 /* Clear RxISR function pointer */ 04614 huart->RxISR = NULL; 04615 04616 /* Check current reception Mode : 04617 If Reception till IDLE event has been selected : */ 04618 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 04619 { 04620 /* Set reception type to Standard */ 04621 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04622 04623 /* Disable IDLE interrupt */ 04624 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 04625 04626 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) 04627 { 04628 /* Clear IDLE Flag */ 04629 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 04630 } 04631 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04632 /*Call registered Rx Event callback*/ 04633 huart->RxEventCallback(huart, huart->RxXferSize); 04634 #else 04635 /*Call legacy weak Rx Event callback*/ 04636 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 04637 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 04638 } 04639 else 04640 { 04641 /* Standard reception API called */ 04642 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04643 /*Call registered Rx complete callback*/ 04644 huart->RxCpltCallback(huart); 04645 #else 04646 /*Call legacy weak Rx complete callback*/ 04647 HAL_UART_RxCpltCallback(huart); 04648 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04649 } 04650 } 04651 } 04652 04653 /* When remaining number of bytes to receive is less than the RX FIFO 04654 threshold, next incoming frames are processed as if FIFO mode was 04655 disabled (i.e. one interrupt per received frame). 04656 */ 04657 rxdatacount = huart->RxXferCount; 04658 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) 04659 { 04660 /* Disable the UART RXFT interrupt*/ 04661 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); 04662 04663 /* Update the RxISR function pointer */ 04664 huart->RxISR = UART_RxISR_8BIT; 04665 04666 /* Enable the UART Data Register Not Empty interrupt */ 04667 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); 04668 } 04669 } 04670 else 04671 { 04672 /* Clear RXNE interrupt flag */ 04673 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04674 } 04675 } 04676 04677 /** 04678 * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled. 04679 * @note Function is called under interruption only, once 04680 * interruptions have been enabled by HAL_UART_Receive_IT() 04681 * @param huart UART handle. 04682 * @retval None 04683 */ 04684 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) 04685 { 04686 uint16_t *tmp; 04687 uint16_t uhMask = huart->Mask; 04688 uint16_t uhdata; 04689 uint16_t nb_rx_data; 04690 uint16_t rxdatacount; 04691 uint32_t isrflags = READ_REG(huart->Instance->ISR); 04692 uint32_t cr1its = READ_REG(huart->Instance->CR1); 04693 uint32_t cr3its = READ_REG(huart->Instance->CR3); 04694 04695 /* Check that a Rx process is ongoing */ 04696 if (huart->RxState == HAL_UART_STATE_BUSY_RX) 04697 { 04698 nb_rx_data = huart->NbRxDataToProcess; 04699 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) 04700 { 04701 uhdata = (uint16_t) READ_REG(huart->Instance->RDR); 04702 tmp = (uint16_t *) huart->pRxBuffPtr ; 04703 *tmp = (uint16_t)(uhdata & uhMask); 04704 huart->pRxBuffPtr += 2U; 04705 huart->RxXferCount--; 04706 isrflags = READ_REG(huart->Instance->ISR); 04707 04708 /* If some non blocking errors occurred */ 04709 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) 04710 { 04711 /* UART parity error interrupt occurred -------------------------------------*/ 04712 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) 04713 { 04714 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); 04715 04716 huart->ErrorCode |= HAL_UART_ERROR_PE; 04717 } 04718 04719 /* UART frame error interrupt occurred --------------------------------------*/ 04720 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 04721 { 04722 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); 04723 04724 huart->ErrorCode |= HAL_UART_ERROR_FE; 04725 } 04726 04727 /* UART noise error interrupt occurred --------------------------------------*/ 04728 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) 04729 { 04730 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); 04731 04732 huart->ErrorCode |= HAL_UART_ERROR_NE; 04733 } 04734 04735 /* Call UART Error Call back function if need be ----------------------------*/ 04736 if (huart->ErrorCode != HAL_UART_ERROR_NONE) 04737 { 04738 /* Non Blocking error : transfer could go on. 04739 Error is notified to user through user error callback */ 04740 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04741 /*Call registered error callback*/ 04742 huart->ErrorCallback(huart); 04743 #else 04744 /*Call legacy weak error callback*/ 04745 HAL_UART_ErrorCallback(huart); 04746 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04747 huart->ErrorCode = HAL_UART_ERROR_NONE; 04748 } 04749 } 04750 04751 if (huart->RxXferCount == 0U) 04752 { 04753 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ 04754 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); 04755 04756 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) 04757 and RX FIFO Threshold interrupt */ 04758 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); 04759 04760 /* Rx process is completed, restore huart->RxState to Ready */ 04761 huart->RxState = HAL_UART_STATE_READY; 04762 04763 /* Clear RxISR function pointer */ 04764 huart->RxISR = NULL; 04765 04766 /* Check current reception Mode : 04767 If Reception till IDLE event has been selected : */ 04768 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 04769 { 04770 /* Set reception type to Standard */ 04771 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; 04772 04773 /* Disable IDLE interrupt */ 04774 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 04775 04776 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) 04777 { 04778 /* Clear IDLE Flag */ 04779 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 04780 } 04781 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04782 /*Call registered Rx Event callback*/ 04783 huart->RxEventCallback(huart, huart->RxXferSize); 04784 #else 04785 /*Call legacy weak Rx Event callback*/ 04786 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); 04787 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 04788 } 04789 else 04790 { 04791 /* Standard reception API called */ 04792 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 04793 /*Call registered Rx complete callback*/ 04794 huart->RxCpltCallback(huart); 04795 #else 04796 /*Call legacy weak Rx complete callback*/ 04797 HAL_UART_RxCpltCallback(huart); 04798 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ 04799 } 04800 } 04801 } 04802 04803 /* When remaining number of bytes to receive is less than the RX FIFO 04804 threshold, next incoming frames are processed as if FIFO mode was 04805 disabled (i.e. one interrupt per received frame). 04806 */ 04807 rxdatacount = huart->RxXferCount; 04808 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) 04809 { 04810 /* Disable the UART RXFT interrupt*/ 04811 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); 04812 04813 /* Update the RxISR function pointer */ 04814 huart->RxISR = UART_RxISR_16BIT; 04815 04816 /* Enable the UART Data Register Not Empty interrupt */ 04817 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); 04818 } 04819 } 04820 else 04821 { 04822 /* Clear RXNE interrupt flag */ 04823 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 04824 } 04825 } 04826 #endif /* USART_CR1_FIFOEN */ 04827 04828 /** 04829 * @} 04830 */ 04831 04832 #endif /* HAL_UART_MODULE_ENABLED */ 04833 /** 04834 * @} 04835 */ 04836 04837 /** 04838 * @} 04839 */ 04840