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