Back to home page

LXR

 
 

    


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