STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_uart_ex.c 00004 * @author MCD Application Team 00005 * @brief Extended UART HAL module driver. 00006 * This file provides firmware functions to manage the following extended 00007 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). 00008 * + Initialization and de-initialization functions 00009 * + Peripheral Control functions 00010 * 00011 * 00012 ****************************************************************************** 00013 * @attention 00014 * 00015 * Copyright (c) 2017 STMicroelectronics. 00016 * All rights reserved. 00017 * 00018 * This software is licensed under terms that can be found in the LICENSE file 00019 * in the root directory of this software component. 00020 * If no LICENSE file comes with this software, it is provided AS-IS. 00021 * 00022 ****************************************************************************** 00023 @verbatim 00024 ============================================================================== 00025 ##### UART peripheral extended features ##### 00026 ============================================================================== 00027 00028 (#) Declare a UART_HandleTypeDef handle structure. 00029 00030 (#) For the UART RS485 Driver Enable mode, initialize the UART registers 00031 by calling the HAL_RS485Ex_Init() API. 00032 00033 (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. 00034 00035 -@- When UART operates in FIFO mode, FIFO mode must be enabled prior 00036 starting RX/TX transfers. Also RX/TX FIFO thresholds must be 00037 configured prior starting RX/TX transfers. 00038 00039 @endverbatim 00040 ****************************************************************************** 00041 */ 00042 00043 /* Includes ------------------------------------------------------------------*/ 00044 #include "stm32h7xx_hal.h" 00045 00046 /** @addtogroup STM32H7xx_HAL_Driver 00047 * @{ 00048 */ 00049 00050 /** @defgroup UARTEx UARTEx 00051 * @brief UART Extended HAL module driver 00052 * @{ 00053 */ 00054 00055 #ifdef HAL_UART_MODULE_ENABLED 00056 00057 /* Private typedef -----------------------------------------------------------*/ 00058 /* Private define ------------------------------------------------------------*/ 00059 /** @defgroup UARTEX_Private_Constants UARTEx Private Constants 00060 * @{ 00061 */ 00062 /* UART RX FIFO depth */ 00063 #define RX_FIFO_DEPTH 16U 00064 00065 /* UART TX FIFO depth */ 00066 #define TX_FIFO_DEPTH 16U 00067 /** 00068 * @} 00069 */ 00070 00071 /* Private macros ------------------------------------------------------------*/ 00072 /* Private variables ---------------------------------------------------------*/ 00073 /* Private function prototypes -----------------------------------------------*/ 00074 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions 00075 * @{ 00076 */ 00077 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); 00078 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart); 00079 /** 00080 * @} 00081 */ 00082 00083 /* Exported functions --------------------------------------------------------*/ 00084 00085 /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions 00086 * @{ 00087 */ 00088 00089 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions 00090 * @brief Extended Initialization and Configuration Functions 00091 * 00092 @verbatim 00093 =============================================================================== 00094 ##### Initialization and Configuration functions ##### 00095 =============================================================================== 00096 [..] 00097 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 00098 in asynchronous mode. 00099 (+) For the asynchronous mode the parameters below can be configured: 00100 (++) Baud Rate 00101 (++) Word Length 00102 (++) Stop Bit 00103 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00104 in the data register is transmitted but is changed by the parity bit. 00105 (++) Hardware flow control 00106 (++) Receiver/transmitter modes 00107 (++) Over Sampling Method 00108 (++) One-Bit Sampling Method 00109 (+) For the asynchronous mode, the following advanced features can be configured as well: 00110 (++) TX and/or RX pin level inversion 00111 (++) data logical level inversion 00112 (++) RX and TX pins swap 00113 (++) RX overrun detection disabling 00114 (++) DMA disabling on RX error 00115 (++) MSB first on communication line 00116 (++) auto Baud rate detection 00117 [..] 00118 The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration 00119 procedures (details for the procedures are available in reference manual). 00120 00121 @endverbatim 00122 00123 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00124 8-bit or 9-bit), the possible UART formats are listed in the 00125 following table. 00126 00127 Table 1. UART frame format. 00128 +-----------------------------------------------------------------------+ 00129 | M1 bit | M0 bit | PCE bit | UART frame | 00130 |---------|---------|-----------|---------------------------------------| 00131 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00132 |---------|---------|-----------|---------------------------------------| 00133 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00134 |---------|---------|-----------|---------------------------------------| 00135 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00136 |---------|---------|-----------|---------------------------------------| 00137 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00138 |---------|---------|-----------|---------------------------------------| 00139 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00140 |---------|---------|-----------|---------------------------------------| 00141 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00142 +-----------------------------------------------------------------------+ 00143 00144 * @{ 00145 */ 00146 00147 /** 00148 * @brief Initialize the RS485 Driver enable feature according to the specified 00149 * parameters in the UART_InitTypeDef and creates the associated handle. 00150 * @param huart UART handle. 00151 * @param Polarity Select the driver enable polarity. 00152 * This parameter can be one of the following values: 00153 * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high 00154 * @arg @ref UART_DE_POLARITY_LOW DE signal is active low 00155 * @param AssertionTime Driver Enable assertion time: 00156 * 5-bit value defining the time between the activation of the DE (Driver Enable) 00157 * signal and the beginning of the start bit. It is expressed in sample time 00158 * units (1/8 or 1/16 bit time, depending on the oversampling rate) 00159 * @param DeassertionTime Driver Enable deassertion time: 00160 * 5-bit value defining the time between the end of the last stop bit, in a 00161 * transmitted message, and the de-activation of the DE (Driver Enable) signal. 00162 * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the 00163 * oversampling rate). 00164 * @retval HAL status 00165 */ 00166 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, 00167 uint32_t DeassertionTime) 00168 { 00169 uint32_t temp; 00170 00171 /* Check the UART handle allocation */ 00172 if (huart == NULL) 00173 { 00174 return HAL_ERROR; 00175 } 00176 /* Check the Driver Enable UART instance */ 00177 assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance)); 00178 00179 /* Check the Driver Enable polarity */ 00180 assert_param(IS_UART_DE_POLARITY(Polarity)); 00181 00182 /* Check the Driver Enable assertion time */ 00183 assert_param(IS_UART_ASSERTIONTIME(AssertionTime)); 00184 00185 /* Check the Driver Enable deassertion time */ 00186 assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime)); 00187 00188 if (huart->gState == HAL_UART_STATE_RESET) 00189 { 00190 /* Allocate lock resource and initialize it */ 00191 huart->Lock = HAL_UNLOCKED; 00192 00193 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 00194 UART_InitCallbacksToDefault(huart); 00195 00196 if (huart->MspInitCallback == NULL) 00197 { 00198 huart->MspInitCallback = HAL_UART_MspInit; 00199 } 00200 00201 /* Init the low level hardware */ 00202 huart->MspInitCallback(huart); 00203 #else 00204 /* Init the low level hardware : GPIO, CLOCK, CORTEX */ 00205 HAL_UART_MspInit(huart); 00206 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 00207 } 00208 00209 huart->gState = HAL_UART_STATE_BUSY; 00210 00211 /* Disable the Peripheral */ 00212 __HAL_UART_DISABLE(huart); 00213 00214 /* Set the UART Communication parameters */ 00215 if (UART_SetConfig(huart) == HAL_ERROR) 00216 { 00217 return HAL_ERROR; 00218 } 00219 00220 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 00221 { 00222 UART_AdvFeatureConfig(huart); 00223 } 00224 00225 /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */ 00226 SET_BIT(huart->Instance->CR3, USART_CR3_DEM); 00227 00228 /* Set the Driver Enable polarity */ 00229 MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity); 00230 00231 /* Set the Driver Enable assertion and deassertion times */ 00232 temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS); 00233 temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS); 00234 MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp); 00235 00236 /* Enable the Peripheral */ 00237 __HAL_UART_ENABLE(huart); 00238 00239 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 00240 return (UART_CheckIdleState(huart)); 00241 } 00242 00243 /** 00244 * @} 00245 */ 00246 00247 /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions 00248 * @brief Extended functions 00249 * 00250 @verbatim 00251 =============================================================================== 00252 ##### IO operation functions ##### 00253 =============================================================================== 00254 This subsection provides a set of Wakeup and FIFO mode related callback functions. 00255 00256 (#) Wakeup from Stop mode Callback: 00257 (+) HAL_UARTEx_WakeupCallback() 00258 00259 (#) TX/RX Fifos Callbacks: 00260 (+) HAL_UARTEx_RxFifoFullCallback() 00261 (+) HAL_UARTEx_TxFifoEmptyCallback() 00262 00263 @endverbatim 00264 * @{ 00265 */ 00266 00267 /** 00268 * @brief UART wakeup from Stop mode callback. 00269 * @param huart UART handle. 00270 * @retval None 00271 */ 00272 __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) 00273 { 00274 /* Prevent unused argument(s) compilation warning */ 00275 UNUSED(huart); 00276 00277 /* NOTE : This function should not be modified, when the callback is needed, 00278 the HAL_UARTEx_WakeupCallback can be implemented in the user file. 00279 */ 00280 } 00281 00282 /** 00283 * @brief UART RX Fifo full callback. 00284 * @param huart UART handle. 00285 * @retval None 00286 */ 00287 __weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart) 00288 { 00289 /* Prevent unused argument(s) compilation warning */ 00290 UNUSED(huart); 00291 00292 /* NOTE : This function should not be modified, when the callback is needed, 00293 the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file. 00294 */ 00295 } 00296 00297 /** 00298 * @brief UART TX Fifo empty callback. 00299 * @param huart UART handle. 00300 * @retval None 00301 */ 00302 __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart) 00303 { 00304 /* Prevent unused argument(s) compilation warning */ 00305 UNUSED(huart); 00306 00307 /* NOTE : This function should not be modified, when the callback is needed, 00308 the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file. 00309 */ 00310 } 00311 00312 /** 00313 * @} 00314 */ 00315 00316 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions 00317 * @brief Extended Peripheral Control functions 00318 * 00319 @verbatim 00320 =============================================================================== 00321 ##### Peripheral Control functions ##### 00322 =============================================================================== 00323 [..] This section provides the following functions: 00324 (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address 00325 detection length to more than 4 bits for multiprocessor address mark wake up. 00326 (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode 00327 trigger: address match, Start Bit detection or RXNE bit status. 00328 (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode 00329 (+) HAL_UARTEx_DisableStopMode() API disables the above functionality 00330 (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode 00331 (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode 00332 (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold 00333 (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold 00334 00335 [..] This subsection also provides a set of additional functions providing enhanced reception 00336 services to user. (For example, these functions allow application to handle use cases 00337 where number of data to be received is unknown). 00338 00339 (#) Compared to standard reception services which only consider number of received 00340 data elements as reception completion criteria, these functions also consider additional events 00341 as triggers for updating reception status to caller : 00342 (+) Detection of inactivity period (RX line has not been active for a given period). 00343 (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) 00344 for 1 frame time, after last received byte. 00345 (++) RX inactivity detected by RTO, i.e. line has been in idle state 00346 for a programmable time, after last received byte. 00347 (+) Detection that a specific character has been received. 00348 00349 (#) There are two mode of transfer: 00350 (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received, 00351 or till IDLE event occurs. Reception is handled only during function execution. 00352 When function exits, no data reception could occur. HAL status and number of actually received data elements, 00353 are returned by function after finishing transfer. 00354 (+) Non-Blocking mode: The reception is performed using Interrupts or DMA. 00355 These API's return the HAL status. 00356 The end of the data processing will be indicated through the 00357 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. 00358 The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process 00359 The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected. 00360 00361 (#) Blocking mode API: 00362 (+) HAL_UARTEx_ReceiveToIdle() 00363 00364 (#) Non-Blocking mode API with Interrupt: 00365 (+) HAL_UARTEx_ReceiveToIdle_IT() 00366 00367 (#) Non-Blocking mode API with DMA: 00368 (+) HAL_UARTEx_ReceiveToIdle_DMA() 00369 00370 @endverbatim 00371 * @{ 00372 */ 00373 00374 /** 00375 * @brief By default in multiprocessor mode, when the wake up method is set 00376 * to address mark, the UART handles only 4-bit long addresses detection; 00377 * this API allows to enable longer addresses detection (6-, 7- or 8-bit 00378 * long). 00379 * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode, 00380 * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode. 00381 * @param huart UART handle. 00382 * @param AddressLength This parameter can be one of the following values: 00383 * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address 00384 * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address 00385 * @retval HAL status 00386 */ 00387 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) 00388 { 00389 /* Check the UART handle allocation */ 00390 if (huart == NULL) 00391 { 00392 return HAL_ERROR; 00393 } 00394 00395 /* Check the address length parameter */ 00396 assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); 00397 00398 huart->gState = HAL_UART_STATE_BUSY; 00399 00400 /* Disable the Peripheral */ 00401 __HAL_UART_DISABLE(huart); 00402 00403 /* Set the address length */ 00404 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); 00405 00406 /* Enable the Peripheral */ 00407 __HAL_UART_ENABLE(huart); 00408 00409 /* TEACK and/or REACK to check before moving huart->gState to Ready */ 00410 return (UART_CheckIdleState(huart)); 00411 } 00412 00413 /** 00414 * @brief Set Wakeup from Stop mode interrupt flag selection. 00415 * @note It is the application responsibility to enable the interrupt used as 00416 * usart_wkup interrupt source before entering low-power mode. 00417 * @param huart UART handle. 00418 * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status. 00419 * This parameter can be one of the following values: 00420 * @arg @ref UART_WAKEUP_ON_ADDRESS 00421 * @arg @ref UART_WAKEUP_ON_STARTBIT 00422 * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY 00423 * @retval HAL status 00424 */ 00425 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) 00426 { 00427 HAL_StatusTypeDef status = HAL_OK; 00428 uint32_t tickstart; 00429 00430 /* check the wake-up from stop mode UART instance */ 00431 assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); 00432 /* check the wake-up selection parameter */ 00433 assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); 00434 00435 /* Process Locked */ 00436 __HAL_LOCK(huart); 00437 00438 huart->gState = HAL_UART_STATE_BUSY; 00439 00440 /* Disable the Peripheral */ 00441 __HAL_UART_DISABLE(huart); 00442 00443 /* Set the wake-up selection scheme */ 00444 MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); 00445 00446 if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) 00447 { 00448 UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection); 00449 } 00450 00451 /* Enable the Peripheral */ 00452 __HAL_UART_ENABLE(huart); 00453 00454 /* Init tickstart for timeout management */ 00455 tickstart = HAL_GetTick(); 00456 00457 /* Wait until REACK flag is set */ 00458 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 00459 { 00460 status = HAL_TIMEOUT; 00461 } 00462 else 00463 { 00464 /* Initialize the UART State */ 00465 huart->gState = HAL_UART_STATE_READY; 00466 } 00467 00468 /* Process Unlocked */ 00469 __HAL_UNLOCK(huart); 00470 00471 return status; 00472 } 00473 00474 /** 00475 * @brief Enable UART Stop Mode. 00476 * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE. 00477 * @param huart UART handle. 00478 * @retval HAL status 00479 */ 00480 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart) 00481 { 00482 /* Process Locked */ 00483 __HAL_LOCK(huart); 00484 00485 /* Set UESM bit */ 00486 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM); 00487 00488 /* Process Unlocked */ 00489 __HAL_UNLOCK(huart); 00490 00491 return HAL_OK; 00492 } 00493 00494 /** 00495 * @brief Disable UART Stop Mode. 00496 * @param huart UART handle. 00497 * @retval HAL status 00498 */ 00499 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) 00500 { 00501 /* Process Locked */ 00502 __HAL_LOCK(huart); 00503 00504 /* Clear UESM bit */ 00505 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM); 00506 00507 /* Process Unlocked */ 00508 __HAL_UNLOCK(huart); 00509 00510 return HAL_OK; 00511 } 00512 00513 /** 00514 * @brief Enable the FIFO mode. 00515 * @param huart UART handle. 00516 * @retval HAL status 00517 */ 00518 HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart) 00519 { 00520 uint32_t tmpcr1; 00521 00522 /* Check parameters */ 00523 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 00524 00525 /* Process Locked */ 00526 __HAL_LOCK(huart); 00527 00528 huart->gState = HAL_UART_STATE_BUSY; 00529 00530 /* Save actual UART configuration */ 00531 tmpcr1 = READ_REG(huart->Instance->CR1); 00532 00533 /* Disable UART */ 00534 __HAL_UART_DISABLE(huart); 00535 00536 /* Enable FIFO mode */ 00537 SET_BIT(tmpcr1, USART_CR1_FIFOEN); 00538 huart->FifoMode = UART_FIFOMODE_ENABLE; 00539 00540 /* Restore UART configuration */ 00541 WRITE_REG(huart->Instance->CR1, tmpcr1); 00542 00543 /* Determine the number of data to process during RX/TX ISR execution */ 00544 UARTEx_SetNbDataToProcess(huart); 00545 00546 huart->gState = HAL_UART_STATE_READY; 00547 00548 /* Process Unlocked */ 00549 __HAL_UNLOCK(huart); 00550 00551 return HAL_OK; 00552 } 00553 00554 /** 00555 * @brief Disable the FIFO mode. 00556 * @param huart UART handle. 00557 * @retval HAL status 00558 */ 00559 HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart) 00560 { 00561 uint32_t tmpcr1; 00562 00563 /* Check parameters */ 00564 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 00565 00566 /* Process Locked */ 00567 __HAL_LOCK(huart); 00568 00569 huart->gState = HAL_UART_STATE_BUSY; 00570 00571 /* Save actual UART configuration */ 00572 tmpcr1 = READ_REG(huart->Instance->CR1); 00573 00574 /* Disable UART */ 00575 __HAL_UART_DISABLE(huart); 00576 00577 /* Enable FIFO mode */ 00578 CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); 00579 huart->FifoMode = UART_FIFOMODE_DISABLE; 00580 00581 /* Restore UART configuration */ 00582 WRITE_REG(huart->Instance->CR1, tmpcr1); 00583 00584 huart->gState = HAL_UART_STATE_READY; 00585 00586 /* Process Unlocked */ 00587 __HAL_UNLOCK(huart); 00588 00589 return HAL_OK; 00590 } 00591 00592 /** 00593 * @brief Set the TXFIFO threshold. 00594 * @param huart UART handle. 00595 * @param Threshold TX FIFO threshold value 00596 * This parameter can be one of the following values: 00597 * @arg @ref UART_TXFIFO_THRESHOLD_1_8 00598 * @arg @ref UART_TXFIFO_THRESHOLD_1_4 00599 * @arg @ref UART_TXFIFO_THRESHOLD_1_2 00600 * @arg @ref UART_TXFIFO_THRESHOLD_3_4 00601 * @arg @ref UART_TXFIFO_THRESHOLD_7_8 00602 * @arg @ref UART_TXFIFO_THRESHOLD_8_8 00603 * @retval HAL status 00604 */ 00605 HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) 00606 { 00607 uint32_t tmpcr1; 00608 00609 /* Check parameters */ 00610 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 00611 assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold)); 00612 00613 /* Process Locked */ 00614 __HAL_LOCK(huart); 00615 00616 huart->gState = HAL_UART_STATE_BUSY; 00617 00618 /* Save actual UART configuration */ 00619 tmpcr1 = READ_REG(huart->Instance->CR1); 00620 00621 /* Disable UART */ 00622 __HAL_UART_DISABLE(huart); 00623 00624 /* Update TX threshold configuration */ 00625 MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold); 00626 00627 /* Determine the number of data to process during RX/TX ISR execution */ 00628 UARTEx_SetNbDataToProcess(huart); 00629 00630 /* Restore UART configuration */ 00631 WRITE_REG(huart->Instance->CR1, tmpcr1); 00632 00633 huart->gState = HAL_UART_STATE_READY; 00634 00635 /* Process Unlocked */ 00636 __HAL_UNLOCK(huart); 00637 00638 return HAL_OK; 00639 } 00640 00641 /** 00642 * @brief Set the RXFIFO threshold. 00643 * @param huart UART handle. 00644 * @param Threshold RX FIFO threshold value 00645 * This parameter can be one of the following values: 00646 * @arg @ref UART_RXFIFO_THRESHOLD_1_8 00647 * @arg @ref UART_RXFIFO_THRESHOLD_1_4 00648 * @arg @ref UART_RXFIFO_THRESHOLD_1_2 00649 * @arg @ref UART_RXFIFO_THRESHOLD_3_4 00650 * @arg @ref UART_RXFIFO_THRESHOLD_7_8 00651 * @arg @ref UART_RXFIFO_THRESHOLD_8_8 00652 * @retval HAL status 00653 */ 00654 HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) 00655 { 00656 uint32_t tmpcr1; 00657 00658 /* Check the parameters */ 00659 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 00660 assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold)); 00661 00662 /* Process Locked */ 00663 __HAL_LOCK(huart); 00664 00665 huart->gState = HAL_UART_STATE_BUSY; 00666 00667 /* Save actual UART configuration */ 00668 tmpcr1 = READ_REG(huart->Instance->CR1); 00669 00670 /* Disable UART */ 00671 __HAL_UART_DISABLE(huart); 00672 00673 /* Update RX threshold configuration */ 00674 MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold); 00675 00676 /* Determine the number of data to process during RX/TX ISR execution */ 00677 UARTEx_SetNbDataToProcess(huart); 00678 00679 /* Restore UART configuration */ 00680 WRITE_REG(huart->Instance->CR1, tmpcr1); 00681 00682 huart->gState = HAL_UART_STATE_READY; 00683 00684 /* Process Unlocked */ 00685 __HAL_UNLOCK(huart); 00686 00687 return HAL_OK; 00688 } 00689 00690 /** 00691 * @brief Receive an amount of data in blocking mode till either the expected number of data 00692 * is received or an IDLE event occurs. 00693 * @note HAL_OK is returned if reception is completed (expected number of data has been received) 00694 * or if reception is stopped after IDLE event (less than the expected number of data has been received) 00695 * In this case, RxLen output parameter indicates number of data available in reception buffer. 00696 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 00697 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 00698 * of uint16_t available through pData. 00699 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO 00700 * is not empty. Read operations from the RDR register are performed when 00701 * RXFNE flag is set. From hardware perspective, RXFNE flag and 00702 * RXNE are mapped on the same bit-field. 00703 * @param huart UART handle. 00704 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 00705 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 00706 * @param RxLen Number of data elements finally received 00707 * (could be lower than Size, in case reception ends on IDLE event) 00708 * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence). 00709 * @retval HAL status 00710 */ 00711 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, 00712 uint32_t Timeout) 00713 { 00714 uint8_t *pdata8bits; 00715 uint16_t *pdata16bits; 00716 uint16_t uhMask; 00717 uint32_t tickstart; 00718 00719 /* Check that a Rx process is not already ongoing */ 00720 if (huart->RxState == HAL_UART_STATE_READY) 00721 { 00722 if ((pData == NULL) || (Size == 0U)) 00723 { 00724 return HAL_ERROR; 00725 } 00726 00727 __HAL_LOCK(huart); 00728 00729 huart->ErrorCode = HAL_UART_ERROR_NONE; 00730 huart->RxState = HAL_UART_STATE_BUSY_RX; 00731 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 00732 00733 /* Init tickstart for timeout management */ 00734 tickstart = HAL_GetTick(); 00735 00736 huart->RxXferSize = Size; 00737 huart->RxXferCount = Size; 00738 00739 /* Computation of UART mask to apply to RDR register */ 00740 UART_MASK_COMPUTATION(huart); 00741 uhMask = huart->Mask; 00742 00743 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ 00744 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 00745 { 00746 pdata8bits = NULL; 00747 pdata16bits = (uint16_t *) pData; 00748 } 00749 else 00750 { 00751 pdata8bits = pData; 00752 pdata16bits = NULL; 00753 } 00754 00755 __HAL_UNLOCK(huart); 00756 00757 /* Initialize output number of received elements */ 00758 *RxLen = 0U; 00759 00760 /* as long as data have to be received */ 00761 while (huart->RxXferCount > 0U) 00762 { 00763 /* Check if IDLE flag is set */ 00764 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) 00765 { 00766 /* Clear IDLE flag in ISR */ 00767 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 00768 00769 /* If Set, but no data ever received, clear flag without exiting loop */ 00770 /* If Set, and data has already been received, this means Idle Event is valid : End reception */ 00771 if (*RxLen > 0U) 00772 { 00773 huart->RxState = HAL_UART_STATE_READY; 00774 00775 return HAL_OK; 00776 } 00777 } 00778 00779 /* Check if RXNE flag is set */ 00780 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) 00781 { 00782 if (pdata8bits == NULL) 00783 { 00784 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); 00785 pdata16bits++; 00786 } 00787 else 00788 { 00789 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); 00790 pdata8bits++; 00791 } 00792 /* Increment number of received elements */ 00793 *RxLen += 1U; 00794 huart->RxXferCount--; 00795 } 00796 00797 /* Check for the Timeout */ 00798 if (Timeout != HAL_MAX_DELAY) 00799 { 00800 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 00801 { 00802 huart->RxState = HAL_UART_STATE_READY; 00803 00804 return HAL_TIMEOUT; 00805 } 00806 } 00807 } 00808 00809 /* Set number of received elements in output parameter : RxLen */ 00810 *RxLen = huart->RxXferSize - huart->RxXferCount; 00811 /* At end of Rx process, restore huart->RxState to Ready */ 00812 huart->RxState = HAL_UART_STATE_READY; 00813 00814 return HAL_OK; 00815 } 00816 else 00817 { 00818 return HAL_BUSY; 00819 } 00820 } 00821 00822 /** 00823 * @brief Receive an amount of data in interrupt mode till either the expected number of data 00824 * is received or an IDLE event occurs. 00825 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 00826 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating 00827 * number of received data elements. 00828 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 00829 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 00830 * of uint16_t available through pData. 00831 * @param huart UART handle. 00832 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 00833 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 00834 * @retval HAL status 00835 */ 00836 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00837 { 00838 HAL_StatusTypeDef status; 00839 00840 /* Check that a Rx process is not already ongoing */ 00841 if (huart->RxState == HAL_UART_STATE_READY) 00842 { 00843 if ((pData == NULL) || (Size == 0U)) 00844 { 00845 return HAL_ERROR; 00846 } 00847 00848 __HAL_LOCK(huart); 00849 00850 /* Set Reception type to reception till IDLE Event*/ 00851 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 00852 00853 status = UART_Start_Receive_IT(huart, pData, Size); 00854 00855 /* Check Rx process has been successfully started */ 00856 if (status == HAL_OK) 00857 { 00858 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 00859 { 00860 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 00861 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 00862 } 00863 else 00864 { 00865 /* In case of errors already pending when reception is started, 00866 Interrupts may have already been raised and lead to reception abortion. 00867 (Overrun error for instance). 00868 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 00869 status = HAL_ERROR; 00870 } 00871 } 00872 00873 return status; 00874 } 00875 else 00876 { 00877 return HAL_BUSY; 00878 } 00879 } 00880 00881 /** 00882 * @brief Receive an amount of data in DMA mode till either the expected number 00883 * of data is received or an IDLE event occurs. 00884 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 00885 * to DMA services, transferring automatically received data elements in user reception buffer and 00886 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider 00887 * reception phase as ended. In all cases, callback execution will indicate number of received data elements. 00888 * @note When the UART parity is enabled (PCE = 1), the received data contain 00889 * the parity bit (MSB position). 00890 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 00891 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 00892 * of uint16_t available through pData. 00893 * @param huart UART handle. 00894 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 00895 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 00896 * @retval HAL status 00897 */ 00898 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 00899 { 00900 HAL_StatusTypeDef status; 00901 00902 /* Check that a Rx process is not already ongoing */ 00903 if (huart->RxState == HAL_UART_STATE_READY) 00904 { 00905 if ((pData == NULL) || (Size == 0U)) 00906 { 00907 return HAL_ERROR; 00908 } 00909 00910 __HAL_LOCK(huart); 00911 00912 /* Set Reception type to reception till IDLE Event*/ 00913 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 00914 00915 status = UART_Start_Receive_DMA(huart, pData, Size); 00916 00917 /* Check Rx process has been successfully started */ 00918 if (status == HAL_OK) 00919 { 00920 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 00921 { 00922 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 00923 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 00924 } 00925 else 00926 { 00927 /* In case of errors already pending when reception is started, 00928 Interrupts may have already been raised and lead to reception abortion. 00929 (Overrun error for instance). 00930 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 00931 status = HAL_ERROR; 00932 } 00933 } 00934 00935 return status; 00936 } 00937 else 00938 { 00939 return HAL_BUSY; 00940 } 00941 } 00942 00943 /** 00944 * @} 00945 */ 00946 00947 /** 00948 * @} 00949 */ 00950 00951 /** @addtogroup UARTEx_Private_Functions 00952 * @{ 00953 */ 00954 00955 /** 00956 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection. 00957 * @param huart UART handle. 00958 * @param WakeUpSelection UART wake up from stop mode parameters. 00959 * @retval None 00960 */ 00961 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) 00962 { 00963 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength)); 00964 00965 /* Set the USART address length */ 00966 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength); 00967 00968 /* Set the USART address node */ 00969 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS)); 00970 } 00971 00972 /** 00973 * @brief Calculate the number of data to process in RX/TX ISR. 00974 * @note The RX FIFO depth and the TX FIFO depth is extracted from 00975 * the UART configuration registers. 00976 * @param huart UART handle. 00977 * @retval None 00978 */ 00979 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart) 00980 { 00981 uint8_t rx_fifo_depth; 00982 uint8_t tx_fifo_depth; 00983 uint8_t rx_fifo_threshold; 00984 uint8_t tx_fifo_threshold; 00985 static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; 00986 static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; 00987 00988 if (huart->FifoMode == UART_FIFOMODE_DISABLE) 00989 { 00990 huart->NbTxDataToProcess = 1U; 00991 huart->NbRxDataToProcess = 1U; 00992 } 00993 else 00994 { 00995 rx_fifo_depth = RX_FIFO_DEPTH; 00996 tx_fifo_depth = TX_FIFO_DEPTH; 00997 rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); 00998 tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); 00999 huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / 01000 (uint16_t)denominator[tx_fifo_threshold]; 01001 huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / 01002 (uint16_t)denominator[rx_fifo_threshold]; 01003 } 01004 } 01005 /** 01006 * @} 01007 */ 01008 01009 #endif /* HAL_UART_MODULE_ENABLED */ 01010 01011 /** 01012 * @} 01013 */ 01014 01015 /** 01016 * @} 01017 */ 01018