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