![]() |
|
|||
File indexing completed on 2025-05-11 08:23:09
0001 /** 0002 ****************************************************************************** 0003 * @file stm32h7xx_hal_uart_ex.c 0004 * @author MCD Application Team 0005 * @brief Extended UART HAL module driver. 0006 * This file provides firmware functions to manage the following extended 0007 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). 0008 * + Initialization and de-initialization functions 0009 * + Peripheral Control functions 0010 * 0011 * 0012 ****************************************************************************** 0013 * @attention 0014 * 0015 * Copyright (c) 2017 STMicroelectronics. 0016 * All rights reserved. 0017 * 0018 * This software is licensed under terms that can be found in the LICENSE file 0019 * in the root directory of this software component. 0020 * If no LICENSE file comes with this software, it is provided AS-IS. 0021 * 0022 ****************************************************************************** 0023 @verbatim 0024 ============================================================================== 0025 ##### UART peripheral extended features ##### 0026 ============================================================================== 0027 0028 (#) Declare a UART_HandleTypeDef handle structure. 0029 0030 (#) For the UART RS485 Driver Enable mode, initialize the UART registers 0031 by calling the HAL_RS485Ex_Init() API. 0032 0033 (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. 0034 0035 -@- When UART operates in FIFO mode, FIFO mode must be enabled prior 0036 starting RX/TX transfers. Also RX/TX FIFO thresholds must be 0037 configured prior starting RX/TX transfers. 0038 0039 @endverbatim 0040 ****************************************************************************** 0041 */ 0042 0043 /* Includes ------------------------------------------------------------------*/ 0044 #include "stm32h7xx_hal.h" 0045 0046 /** @addtogroup STM32H7xx_HAL_Driver 0047 * @{ 0048 */ 0049 0050 /** @defgroup UARTEx UARTEx 0051 * @ingroup RTEMSBSPsARMSTM32H7 0052 * @brief UART Extended HAL module driver 0053 * @{ 0054 */ 0055 0056 #ifdef HAL_UART_MODULE_ENABLED 0057 0058 /* Private typedef -----------------------------------------------------------*/ 0059 /* Private define ------------------------------------------------------------*/ 0060 /** @defgroup UARTEX_Private_Constants UARTEx Private Constants 0061 * @ingroup RTEMSBSPsARMSTM32H7 0062 * @{ 0063 */ 0064 /* UART RX FIFO depth */ 0065 #define RX_FIFO_DEPTH 16U 0066 0067 /* UART TX FIFO depth */ 0068 #define TX_FIFO_DEPTH 16U 0069 /** 0070 * @} 0071 */ 0072 0073 /* Private macros ------------------------------------------------------------*/ 0074 /* Private variables ---------------------------------------------------------*/ 0075 /* Private function prototypes -----------------------------------------------*/ 0076 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions 0077 * @ingroup RTEMSBSPsARMSTM32H7 0078 * @{ 0079 */ 0080 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); 0081 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart); 0082 /** 0083 * @} 0084 */ 0085 0086 /* Exported functions --------------------------------------------------------*/ 0087 0088 /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions 0089 * @ingroup RTEMSBSPsARMSTM32H7 0090 * @{ 0091 */ 0092 0093 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions 0094 * @ingroup RTEMSBSPsARMSTM32H7 0095 * @brief Extended Initialization and Configuration Functions 0096 * 0097 @verbatim 0098 =============================================================================== 0099 ##### Initialization and Configuration functions ##### 0100 =============================================================================== 0101 [..] 0102 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 0103 in asynchronous mode. 0104 (+) For the asynchronous mode the parameters below can be configured: 0105 (++) Baud Rate 0106 (++) Word Length 0107 (++) Stop Bit 0108 (++) Parity: If the parity is enabled, then the MSB bit of the data written 0109 in the data register is transmitted but is changed by the parity bit. 0110 (++) Hardware flow control 0111 (++) Receiver/transmitter modes 0112 (++) Over Sampling Method 0113 (++) One-Bit Sampling Method 0114 (+) For the asynchronous mode, the following advanced features can be configured as well: 0115 (++) TX and/or RX pin level inversion 0116 (++) data logical level inversion 0117 (++) RX and TX pins swap 0118 (++) RX overrun detection disabling 0119 (++) DMA disabling on RX error 0120 (++) MSB first on communication line 0121 (++) auto Baud rate detection 0122 [..] 0123 The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration 0124 procedures (details for the procedures are available in reference manual). 0125 0126 @endverbatim 0127 0128 Depending on the frame length defined by the M1 and M0 bits (7-bit, 0129 8-bit or 9-bit), the possible UART formats are listed in the 0130 following table. 0131 0132 Table 1. UART frame format. 0133 +-----------------------------------------------------------------------+ 0134 | M1 bit | M0 bit | PCE bit | UART frame | 0135 |---------|---------|-----------|---------------------------------------| 0136 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 0137 |---------|---------|-----------|---------------------------------------| 0138 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 0139 |---------|---------|-----------|---------------------------------------| 0140 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 0141 |---------|---------|-----------|---------------------------------------| 0142 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 0143 |---------|---------|-----------|---------------------------------------| 0144 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 0145 |---------|---------|-----------|---------------------------------------| 0146 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 0147 +-----------------------------------------------------------------------+ 0148 0149 * @{ 0150 */ 0151 0152 /** 0153 * @brief Initialize the RS485 Driver enable feature according to the specified 0154 * parameters in the UART_InitTypeDef and creates the associated handle. 0155 * @param huart UART handle. 0156 * @param Polarity Select the driver enable polarity. 0157 * This parameter can be one of the following values: 0158 * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high 0159 * @arg @ref UART_DE_POLARITY_LOW DE signal is active low 0160 * @param AssertionTime Driver Enable assertion time: 0161 * 5-bit value defining the time between the activation of the DE (Driver Enable) 0162 * signal and the beginning of the start bit. It is expressed in sample time 0163 * units (1/8 or 1/16 bit time, depending on the oversampling rate) 0164 * @param DeassertionTime Driver Enable deassertion time: 0165 * 5-bit value defining the time between the end of the last stop bit, in a 0166 * transmitted message, and the de-activation of the DE (Driver Enable) signal. 0167 * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the 0168 * oversampling rate). 0169 * @retval HAL status 0170 */ 0171 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, 0172 uint32_t DeassertionTime) 0173 { 0174 uint32_t temp; 0175 0176 /* Check the UART handle allocation */ 0177 if (huart == NULL) 0178 { 0179 return HAL_ERROR; 0180 } 0181 /* Check the Driver Enable UART instance */ 0182 assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance)); 0183 0184 /* Check the Driver Enable polarity */ 0185 assert_param(IS_UART_DE_POLARITY(Polarity)); 0186 0187 /* Check the Driver Enable assertion time */ 0188 assert_param(IS_UART_ASSERTIONTIME(AssertionTime)); 0189 0190 /* Check the Driver Enable deassertion time */ 0191 assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime)); 0192 0193 if (huart->gState == HAL_UART_STATE_RESET) 0194 { 0195 /* Allocate lock resource and initialize it */ 0196 huart->Lock = HAL_UNLOCKED; 0197 0198 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) 0199 UART_InitCallbacksToDefault(huart); 0200 0201 if (huart->MspInitCallback == NULL) 0202 { 0203 huart->MspInitCallback = HAL_UART_MspInit; 0204 } 0205 0206 /* Init the low level hardware */ 0207 huart->MspInitCallback(huart); 0208 #else 0209 /* Init the low level hardware : GPIO, CLOCK, CORTEX */ 0210 HAL_UART_MspInit(huart); 0211 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ 0212 } 0213 0214 huart->gState = HAL_UART_STATE_BUSY; 0215 0216 /* Disable the Peripheral */ 0217 __HAL_UART_DISABLE(huart); 0218 0219 /* Perform advanced settings configuration */ 0220 /* For some items, configuration requires to be done prior TE and RE bits are set */ 0221 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) 0222 { 0223 UART_AdvFeatureConfig(huart); 0224 } 0225 0226 /* Set the UART Communication parameters */ 0227 if (UART_SetConfig(huart) == HAL_ERROR) 0228 { 0229 return HAL_ERROR; 0230 } 0231 0232 /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */ 0233 SET_BIT(huart->Instance->CR3, USART_CR3_DEM); 0234 0235 /* Set the Driver Enable polarity */ 0236 MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity); 0237 0238 /* Set the Driver Enable assertion and deassertion times */ 0239 temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS); 0240 temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS); 0241 MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp); 0242 0243 /* Enable the Peripheral */ 0244 __HAL_UART_ENABLE(huart); 0245 0246 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ 0247 return (UART_CheckIdleState(huart)); 0248 } 0249 0250 /** 0251 * @} 0252 */ 0253 0254 /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions 0255 * @ingroup RTEMSBSPsARMSTM32H7 0256 * @brief Extended functions 0257 * 0258 @verbatim 0259 =============================================================================== 0260 ##### IO operation functions ##### 0261 =============================================================================== 0262 This subsection provides a set of Wakeup and FIFO mode related callback functions. 0263 0264 (#) Wakeup from Stop mode Callback: 0265 (+) HAL_UARTEx_WakeupCallback() 0266 0267 (#) TX/RX Fifos Callbacks: 0268 (+) HAL_UARTEx_RxFifoFullCallback() 0269 (+) HAL_UARTEx_TxFifoEmptyCallback() 0270 0271 @endverbatim 0272 * @{ 0273 */ 0274 0275 /** 0276 * @brief UART wakeup from Stop mode callback. 0277 * @param huart UART handle. 0278 * @retval None 0279 */ 0280 __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) 0281 { 0282 /* Prevent unused argument(s) compilation warning */ 0283 UNUSED(huart); 0284 0285 /* NOTE : This function should not be modified, when the callback is needed, 0286 the HAL_UARTEx_WakeupCallback can be implemented in the user file. 0287 */ 0288 } 0289 0290 /** 0291 * @brief UART RX Fifo full callback. 0292 * @param huart UART handle. 0293 * @retval None 0294 */ 0295 __weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart) 0296 { 0297 /* Prevent unused argument(s) compilation warning */ 0298 UNUSED(huart); 0299 0300 /* NOTE : This function should not be modified, when the callback is needed, 0301 the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file. 0302 */ 0303 } 0304 0305 /** 0306 * @brief UART TX Fifo empty callback. 0307 * @param huart UART handle. 0308 * @retval None 0309 */ 0310 __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart) 0311 { 0312 /* Prevent unused argument(s) compilation warning */ 0313 UNUSED(huart); 0314 0315 /* NOTE : This function should not be modified, when the callback is needed, 0316 the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file. 0317 */ 0318 } 0319 0320 /** 0321 * @} 0322 */ 0323 0324 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions 0325 * @ingroup RTEMSBSPsARMSTM32H7 0326 * @brief Extended Peripheral Control functions 0327 * 0328 @verbatim 0329 =============================================================================== 0330 ##### Peripheral Control functions ##### 0331 =============================================================================== 0332 [..] This section provides the following functions: 0333 (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address 0334 detection length to more than 4 bits for multiprocessor address mark wake up. 0335 (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode 0336 trigger: address match, Start Bit detection or RXNE bit status. 0337 (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode 0338 (+) HAL_UARTEx_DisableStopMode() API disables the above functionality 0339 (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode 0340 (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode 0341 (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold 0342 (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold 0343 0344 [..] This subsection also provides a set of additional functions providing enhanced reception 0345 services to user. (For example, these functions allow application to handle use cases 0346 where number of data to be received is unknown). 0347 0348 (#) Compared to standard reception services which only consider number of received 0349 data elements as reception completion criteria, these functions also consider additional events 0350 as triggers for updating reception status to caller : 0351 (+) Detection of inactivity period (RX line has not been active for a given period). 0352 (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) 0353 for 1 frame time, after last received byte. 0354 (++) RX inactivity detected by RTO, i.e. line has been in idle state 0355 for a programmable time, after last received byte. 0356 (+) Detection that a specific character has been received. 0357 0358 (#) There are two mode of transfer: 0359 (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received, 0360 or till IDLE event occurs. Reception is handled only during function execution. 0361 When function exits, no data reception could occur. HAL status and number of actually received data elements, 0362 are returned by function after finishing transfer. 0363 (+) Non-Blocking mode: The reception is performed using Interrupts or DMA. 0364 These API's return the HAL status. 0365 The end of the data processing will be indicated through the 0366 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. 0367 The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process 0368 The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected. 0369 0370 (#) Blocking mode API: 0371 (+) HAL_UARTEx_ReceiveToIdle() 0372 0373 (#) Non-Blocking mode API with Interrupt: 0374 (+) HAL_UARTEx_ReceiveToIdle_IT() 0375 0376 (#) Non-Blocking mode API with DMA: 0377 (+) HAL_UARTEx_ReceiveToIdle_DMA() 0378 0379 @endverbatim 0380 * @{ 0381 */ 0382 0383 /** 0384 * @brief By default in multiprocessor mode, when the wake up method is set 0385 * to address mark, the UART handles only 4-bit long addresses detection; 0386 * this API allows to enable longer addresses detection (6-, 7- or 8-bit 0387 * long). 0388 * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode, 0389 * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode. 0390 * @param huart UART handle. 0391 * @param AddressLength This parameter can be one of the following values: 0392 * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address 0393 * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address 0394 * @retval HAL status 0395 */ 0396 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) 0397 { 0398 /* Check the UART handle allocation */ 0399 if (huart == NULL) 0400 { 0401 return HAL_ERROR; 0402 } 0403 0404 /* Check the address length parameter */ 0405 assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); 0406 0407 huart->gState = HAL_UART_STATE_BUSY; 0408 0409 /* Disable the Peripheral */ 0410 __HAL_UART_DISABLE(huart); 0411 0412 /* Set the address length */ 0413 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); 0414 0415 /* Enable the Peripheral */ 0416 __HAL_UART_ENABLE(huart); 0417 0418 /* TEACK and/or REACK to check before moving huart->gState to Ready */ 0419 return (UART_CheckIdleState(huart)); 0420 } 0421 0422 /** 0423 * @brief Set Wakeup from Stop mode interrupt flag selection. 0424 * @note It is the application responsibility to enable the interrupt used as 0425 * usart_wkup interrupt source before entering low-power mode. 0426 * @param huart UART handle. 0427 * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status. 0428 * This parameter can be one of the following values: 0429 * @arg @ref UART_WAKEUP_ON_ADDRESS 0430 * @arg @ref UART_WAKEUP_ON_STARTBIT 0431 * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY 0432 * @retval HAL status 0433 */ 0434 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) 0435 { 0436 HAL_StatusTypeDef status = HAL_OK; 0437 uint32_t tickstart; 0438 0439 /* check the wake-up from stop mode UART instance */ 0440 assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); 0441 /* check the wake-up selection parameter */ 0442 assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); 0443 0444 /* Process Locked */ 0445 __HAL_LOCK(huart); 0446 0447 huart->gState = HAL_UART_STATE_BUSY; 0448 0449 /* Disable the Peripheral */ 0450 __HAL_UART_DISABLE(huart); 0451 0452 /* Set the wake-up selection scheme */ 0453 MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); 0454 0455 if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) 0456 { 0457 UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection); 0458 } 0459 0460 /* Enable the Peripheral */ 0461 __HAL_UART_ENABLE(huart); 0462 0463 /* Init tickstart for timeout management */ 0464 tickstart = HAL_GetTick(); 0465 0466 /* Wait until REACK flag is set */ 0467 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) 0468 { 0469 status = HAL_TIMEOUT; 0470 } 0471 else 0472 { 0473 /* Initialize the UART State */ 0474 huart->gState = HAL_UART_STATE_READY; 0475 } 0476 0477 /* Process Unlocked */ 0478 __HAL_UNLOCK(huart); 0479 0480 return status; 0481 } 0482 0483 /** 0484 * @brief Enable UART Stop Mode. 0485 * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE. 0486 * @param huart UART handle. 0487 * @retval HAL status 0488 */ 0489 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart) 0490 { 0491 /* Process Locked */ 0492 __HAL_LOCK(huart); 0493 0494 /* Set UESM bit */ 0495 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM); 0496 0497 /* Process Unlocked */ 0498 __HAL_UNLOCK(huart); 0499 0500 return HAL_OK; 0501 } 0502 0503 /** 0504 * @brief Disable UART Stop Mode. 0505 * @param huart UART handle. 0506 * @retval HAL status 0507 */ 0508 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) 0509 { 0510 /* Process Locked */ 0511 __HAL_LOCK(huart); 0512 0513 /* Clear UESM bit */ 0514 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM); 0515 0516 /* Process Unlocked */ 0517 __HAL_UNLOCK(huart); 0518 0519 return HAL_OK; 0520 } 0521 0522 /** 0523 * @brief Enable the FIFO mode. 0524 * @param huart UART handle. 0525 * @retval HAL status 0526 */ 0527 HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart) 0528 { 0529 uint32_t tmpcr1; 0530 0531 /* Check parameters */ 0532 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 0533 0534 /* Process Locked */ 0535 __HAL_LOCK(huart); 0536 0537 huart->gState = HAL_UART_STATE_BUSY; 0538 0539 /* Save actual UART configuration */ 0540 tmpcr1 = READ_REG(huart->Instance->CR1); 0541 0542 /* Disable UART */ 0543 __HAL_UART_DISABLE(huart); 0544 0545 /* Enable FIFO mode */ 0546 SET_BIT(tmpcr1, USART_CR1_FIFOEN); 0547 huart->FifoMode = UART_FIFOMODE_ENABLE; 0548 0549 /* Restore UART configuration */ 0550 WRITE_REG(huart->Instance->CR1, tmpcr1); 0551 0552 /* Determine the number of data to process during RX/TX ISR execution */ 0553 UARTEx_SetNbDataToProcess(huart); 0554 0555 huart->gState = HAL_UART_STATE_READY; 0556 0557 /* Process Unlocked */ 0558 __HAL_UNLOCK(huart); 0559 0560 return HAL_OK; 0561 } 0562 0563 /** 0564 * @brief Disable the FIFO mode. 0565 * @param huart UART handle. 0566 * @retval HAL status 0567 */ 0568 HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart) 0569 { 0570 uint32_t tmpcr1; 0571 0572 /* Check parameters */ 0573 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 0574 0575 /* Process Locked */ 0576 __HAL_LOCK(huart); 0577 0578 huart->gState = HAL_UART_STATE_BUSY; 0579 0580 /* Save actual UART configuration */ 0581 tmpcr1 = READ_REG(huart->Instance->CR1); 0582 0583 /* Disable UART */ 0584 __HAL_UART_DISABLE(huart); 0585 0586 /* Enable FIFO mode */ 0587 CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); 0588 huart->FifoMode = UART_FIFOMODE_DISABLE; 0589 0590 /* Restore UART configuration */ 0591 WRITE_REG(huart->Instance->CR1, tmpcr1); 0592 0593 huart->gState = HAL_UART_STATE_READY; 0594 0595 /* Process Unlocked */ 0596 __HAL_UNLOCK(huart); 0597 0598 return HAL_OK; 0599 } 0600 0601 /** 0602 * @brief Set the TXFIFO threshold. 0603 * @param huart UART handle. 0604 * @param Threshold TX FIFO threshold value 0605 * This parameter can be one of the following values: 0606 * @arg @ref UART_TXFIFO_THRESHOLD_1_8 0607 * @arg @ref UART_TXFIFO_THRESHOLD_1_4 0608 * @arg @ref UART_TXFIFO_THRESHOLD_1_2 0609 * @arg @ref UART_TXFIFO_THRESHOLD_3_4 0610 * @arg @ref UART_TXFIFO_THRESHOLD_7_8 0611 * @arg @ref UART_TXFIFO_THRESHOLD_8_8 0612 * @retval HAL status 0613 */ 0614 HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) 0615 { 0616 uint32_t tmpcr1; 0617 0618 /* Check parameters */ 0619 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 0620 assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold)); 0621 0622 /* Process Locked */ 0623 __HAL_LOCK(huart); 0624 0625 huart->gState = HAL_UART_STATE_BUSY; 0626 0627 /* Save actual UART configuration */ 0628 tmpcr1 = READ_REG(huart->Instance->CR1); 0629 0630 /* Disable UART */ 0631 __HAL_UART_DISABLE(huart); 0632 0633 /* Update TX threshold configuration */ 0634 MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold); 0635 0636 /* Determine the number of data to process during RX/TX ISR execution */ 0637 UARTEx_SetNbDataToProcess(huart); 0638 0639 /* Restore UART configuration */ 0640 WRITE_REG(huart->Instance->CR1, tmpcr1); 0641 0642 huart->gState = HAL_UART_STATE_READY; 0643 0644 /* Process Unlocked */ 0645 __HAL_UNLOCK(huart); 0646 0647 return HAL_OK; 0648 } 0649 0650 /** 0651 * @brief Set the RXFIFO threshold. 0652 * @param huart UART handle. 0653 * @param Threshold RX FIFO threshold value 0654 * This parameter can be one of the following values: 0655 * @arg @ref UART_RXFIFO_THRESHOLD_1_8 0656 * @arg @ref UART_RXFIFO_THRESHOLD_1_4 0657 * @arg @ref UART_RXFIFO_THRESHOLD_1_2 0658 * @arg @ref UART_RXFIFO_THRESHOLD_3_4 0659 * @arg @ref UART_RXFIFO_THRESHOLD_7_8 0660 * @arg @ref UART_RXFIFO_THRESHOLD_8_8 0661 * @retval HAL status 0662 */ 0663 HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) 0664 { 0665 uint32_t tmpcr1; 0666 0667 /* Check the parameters */ 0668 assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); 0669 assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold)); 0670 0671 /* Process Locked */ 0672 __HAL_LOCK(huart); 0673 0674 huart->gState = HAL_UART_STATE_BUSY; 0675 0676 /* Save actual UART configuration */ 0677 tmpcr1 = READ_REG(huart->Instance->CR1); 0678 0679 /* Disable UART */ 0680 __HAL_UART_DISABLE(huart); 0681 0682 /* Update RX threshold configuration */ 0683 MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold); 0684 0685 /* Determine the number of data to process during RX/TX ISR execution */ 0686 UARTEx_SetNbDataToProcess(huart); 0687 0688 /* Restore UART configuration */ 0689 WRITE_REG(huart->Instance->CR1, tmpcr1); 0690 0691 huart->gState = HAL_UART_STATE_READY; 0692 0693 /* Process Unlocked */ 0694 __HAL_UNLOCK(huart); 0695 0696 return HAL_OK; 0697 } 0698 0699 /** 0700 * @brief Receive an amount of data in blocking mode till either the expected number of data 0701 * is received or an IDLE event occurs. 0702 * @note HAL_OK is returned if reception is completed (expected number of data has been received) 0703 * or if reception is stopped after IDLE event (less than the expected number of data has been received) 0704 * In this case, RxLen output parameter indicates number of data available in reception buffer. 0705 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 0706 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 0707 * of uint16_t available through pData. 0708 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO 0709 * is not empty. Read operations from the RDR register are performed when 0710 * RXFNE flag is set. From hardware perspective, RXFNE flag and 0711 * RXNE are mapped on the same bit-field. 0712 * @param huart UART handle. 0713 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 0714 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 0715 * @param RxLen Number of data elements finally received 0716 * (could be lower than Size, in case reception ends on IDLE event) 0717 * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence). 0718 * @retval HAL status 0719 */ 0720 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, 0721 uint32_t Timeout) 0722 { 0723 uint8_t *pdata8bits; 0724 uint16_t *pdata16bits; 0725 uint16_t uhMask; 0726 uint32_t tickstart; 0727 0728 /* Check that a Rx process is not already ongoing */ 0729 if (huart->RxState == HAL_UART_STATE_READY) 0730 { 0731 if ((pData == NULL) || (Size == 0U)) 0732 { 0733 return HAL_ERROR; 0734 } 0735 0736 huart->ErrorCode = HAL_UART_ERROR_NONE; 0737 huart->RxState = HAL_UART_STATE_BUSY_RX; 0738 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 0739 huart->RxEventType = HAL_UART_RXEVENT_TC; 0740 0741 /* Init tickstart for timeout management */ 0742 tickstart = HAL_GetTick(); 0743 0744 huart->RxXferSize = Size; 0745 huart->RxXferCount = Size; 0746 0747 /* Computation of UART mask to apply to RDR register */ 0748 UART_MASK_COMPUTATION(huart); 0749 uhMask = huart->Mask; 0750 0751 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ 0752 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) 0753 { 0754 pdata8bits = NULL; 0755 pdata16bits = (uint16_t *) pData; 0756 } 0757 else 0758 { 0759 pdata8bits = pData; 0760 pdata16bits = NULL; 0761 } 0762 0763 /* Initialize output number of received elements */ 0764 *RxLen = 0U; 0765 0766 /* as long as data have to be received */ 0767 while (huart->RxXferCount > 0U) 0768 { 0769 /* Check if IDLE flag is set */ 0770 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) 0771 { 0772 /* Clear IDLE flag in ISR */ 0773 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 0774 0775 /* If Set, but no data ever received, clear flag without exiting loop */ 0776 /* If Set, and data has already been received, this means Idle Event is valid : End reception */ 0777 if (*RxLen > 0U) 0778 { 0779 huart->RxEventType = HAL_UART_RXEVENT_IDLE; 0780 huart->RxState = HAL_UART_STATE_READY; 0781 0782 return HAL_OK; 0783 } 0784 } 0785 0786 /* Check if RXNE flag is set */ 0787 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) 0788 { 0789 if (pdata8bits == NULL) 0790 { 0791 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); 0792 pdata16bits++; 0793 } 0794 else 0795 { 0796 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); 0797 pdata8bits++; 0798 } 0799 /* Increment number of received elements */ 0800 *RxLen += 1U; 0801 huart->RxXferCount--; 0802 } 0803 0804 /* Check for the Timeout */ 0805 if (Timeout != HAL_MAX_DELAY) 0806 { 0807 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 0808 { 0809 huart->RxState = HAL_UART_STATE_READY; 0810 0811 return HAL_TIMEOUT; 0812 } 0813 } 0814 } 0815 0816 /* Set number of received elements in output parameter : RxLen */ 0817 *RxLen = huart->RxXferSize - huart->RxXferCount; 0818 /* At end of Rx process, restore huart->RxState to Ready */ 0819 huart->RxState = HAL_UART_STATE_READY; 0820 0821 return HAL_OK; 0822 } 0823 else 0824 { 0825 return HAL_BUSY; 0826 } 0827 } 0828 0829 /** 0830 * @brief Receive an amount of data in interrupt mode till either the expected number of data 0831 * is received or an IDLE event occurs. 0832 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 0833 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating 0834 * number of received data elements. 0835 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 0836 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 0837 * of uint16_t available through pData. 0838 * @param huart UART handle. 0839 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 0840 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 0841 * @retval HAL status 0842 */ 0843 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 0844 { 0845 HAL_StatusTypeDef status = HAL_OK; 0846 0847 /* Check that a Rx process is not already ongoing */ 0848 if (huart->RxState == HAL_UART_STATE_READY) 0849 { 0850 if ((pData == NULL) || (Size == 0U)) 0851 { 0852 return HAL_ERROR; 0853 } 0854 0855 /* Set Reception type to reception till IDLE Event*/ 0856 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 0857 huart->RxEventType = HAL_UART_RXEVENT_TC; 0858 0859 (void)UART_Start_Receive_IT(huart, pData, Size); 0860 0861 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 0862 { 0863 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 0864 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 0865 } 0866 else 0867 { 0868 /* In case of errors already pending when reception is started, 0869 Interrupts may have already been raised and lead to reception abortion. 0870 (Overrun error for instance). 0871 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 0872 status = HAL_ERROR; 0873 } 0874 0875 return status; 0876 } 0877 else 0878 { 0879 return HAL_BUSY; 0880 } 0881 } 0882 0883 /** 0884 * @brief Receive an amount of data in DMA mode till either the expected number 0885 * of data is received or an IDLE event occurs. 0886 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks 0887 * to DMA services, transferring automatically received data elements in user reception buffer and 0888 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider 0889 * reception phase as ended. In all cases, callback execution will indicate number of received data elements. 0890 * @note When the UART parity is enabled (PCE = 1), the received data contain 0891 * the parity bit (MSB position). 0892 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), 0893 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number 0894 * of uint16_t available through pData. 0895 * @param huart UART handle. 0896 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). 0897 * @param Size Amount of data elements (uint8_t or uint16_t) to be received. 0898 * @retval HAL status 0899 */ 0900 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 0901 { 0902 HAL_StatusTypeDef status; 0903 0904 /* Check that a Rx process is not already ongoing */ 0905 if (huart->RxState == HAL_UART_STATE_READY) 0906 { 0907 if ((pData == NULL) || (Size == 0U)) 0908 { 0909 return HAL_ERROR; 0910 } 0911 0912 /* Set Reception type to reception till IDLE Event*/ 0913 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; 0914 huart->RxEventType = HAL_UART_RXEVENT_TC; 0915 0916 status = UART_Start_Receive_DMA(huart, pData, Size); 0917 0918 /* Check Rx process has been successfully started */ 0919 if (status == HAL_OK) 0920 { 0921 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) 0922 { 0923 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); 0924 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); 0925 } 0926 else 0927 { 0928 /* In case of errors already pending when reception is started, 0929 Interrupts may have already been raised and lead to reception abortion. 0930 (Overrun error for instance). 0931 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ 0932 status = HAL_ERROR; 0933 } 0934 } 0935 0936 return status; 0937 } 0938 else 0939 { 0940 return HAL_BUSY; 0941 } 0942 } 0943 0944 /** 0945 * @brief Provide Rx Event type that has lead to RxEvent callback execution. 0946 * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress 0947 * of reception process is provided to application through calls of Rx Event callback (either default one 0948 * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event, 0949 * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead 0950 * to Rx Event callback execution. 0951 * @note This function is expected to be called within the user implementation of Rx Event Callback, 0952 * in order to provide the accurate value : 0953 * In Interrupt Mode : 0954 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) 0955 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of 0956 * received data is lower than expected one) 0957 * In DMA Mode : 0958 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) 0959 * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received 0960 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of 0961 * received data is lower than expected one). 0962 * In DMA mode, RxEvent callback could be called several times; 0963 * When DMA is configured in Normal Mode, HT event does not stop Reception process; 0964 * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process; 0965 * @param huart UART handle. 0966 * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values) 0967 */ 0968 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart) 0969 { 0970 /* Return Rx Event type value, as stored in UART handle */ 0971 return (huart->RxEventType); 0972 } 0973 0974 /** 0975 * @} 0976 */ 0977 0978 /** 0979 * @} 0980 */ 0981 0982 /** @addtogroup UARTEx_Private_Functions 0983 * @{ 0984 */ 0985 0986 /** 0987 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection. 0988 * @param huart UART handle. 0989 * @param WakeUpSelection UART wake up from stop mode parameters. 0990 * @retval None 0991 */ 0992 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) 0993 { 0994 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength)); 0995 0996 /* Set the USART address length */ 0997 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength); 0998 0999 /* Set the USART address node */ 1000 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS)); 1001 } 1002 1003 /** 1004 * @brief Calculate the number of data to process in RX/TX ISR. 1005 * @note The RX FIFO depth and the TX FIFO depth is extracted from 1006 * the UART configuration registers. 1007 * @param huart UART handle. 1008 * @retval None 1009 */ 1010 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart) 1011 { 1012 uint8_t rx_fifo_depth; 1013 uint8_t tx_fifo_depth; 1014 uint8_t rx_fifo_threshold; 1015 uint8_t tx_fifo_threshold; 1016 static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; 1017 static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; 1018 1019 if (huart->FifoMode == UART_FIFOMODE_DISABLE) 1020 { 1021 huart->NbTxDataToProcess = 1U; 1022 huart->NbRxDataToProcess = 1U; 1023 } 1024 else 1025 { 1026 rx_fifo_depth = RX_FIFO_DEPTH; 1027 tx_fifo_depth = TX_FIFO_DEPTH; 1028 rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); 1029 tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); 1030 huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / 1031 (uint16_t)denominator[tx_fifo_threshold]; 1032 huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / 1033 (uint16_t)denominator[rx_fifo_threshold]; 1034 } 1035 } 1036 /** 1037 * @} 1038 */ 1039 1040 #endif /* HAL_UART_MODULE_ENABLED */ 1041 1042 /** 1043 * @} 1044 */ 1045 1046 /** 1047 * @} 1048 */ 1049
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |