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