1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_uart_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended UART HAL module driver.
6   *          This file provides firmware functions to manage the following extended
7   *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   *
12   @verbatim
13   ==============================================================================
14                ##### UART peripheral extended features  #####
15   ==============================================================================
16 
17     (#) Declare a UART_HandleTypeDef handle structure.
18 
19     (#) For the UART RS485 Driver Enable mode, initialize the UART registers
20         by calling the HAL_RS485Ex_Init() API.
21 
22     (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
23 
24         -@- When UART operates in FIFO mode, FIFO mode must be enabled prior
25             starting RX/TX transfers. Also RX/TX FIFO thresholds must be
26             configured prior starting RX/TX transfers.
27 
28   @endverbatim
29   ******************************************************************************
30   * @attention
31   *
32   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
33   *
34   * Redistribution and use in source and binary forms, with or without modification,
35   * are permitted provided that the following conditions are met:
36   *   1. Redistributions of source code must retain the above copyright notice,
37   *      this list of conditions and the following disclaimer.
38   *   2. Redistributions in binary form must reproduce the above copyright notice,
39   *      this list of conditions and the following disclaimer in the documentation
40   *      and/or other materials provided with the distribution.
41   *   3. Neither the name of STMicroelectronics nor the names of its contributors
42   *      may be used to endorse or promote products derived from this software
43   *      without specific prior written permission.
44   *
45   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
49   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55   *
56   ******************************************************************************
57   */
58 
59 /* Includes ------------------------------------------------------------------*/
60 #include "stm32l4xx_hal.h"
61 
62 /** @addtogroup STM32L4xx_HAL_Driver
63   * @{
64   */
65 
66 /** @defgroup UARTEx UARTEx
67   * @brief UART Extended HAL module driver
68   * @{
69   */
70 
71 #ifdef HAL_UART_MODULE_ENABLED
72 
73 /* Private typedef -----------------------------------------------------------*/
74 /* Private define ------------------------------------------------------------*/
75 #if defined(USART_CR1_FIFOEN)
76 /* UART RX FIFO depth */
77 #define RX_FIFO_DEPTH 8U
78 
79 /* UART TX FIFO depth */
80 #define TX_FIFO_DEPTH 8U
81 #endif
82 
83 /* Private macros ------------------------------------------------------------*/
84 /* Private variables ---------------------------------------------------------*/
85 /* Private function prototypes -----------------------------------------------*/
86 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
87   * @{
88   */
89 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
90 extern void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
91 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
92 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
93 #if defined(USART_CR1_FIFOEN)
94 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart);
95 #endif
96 /**
97   * @}
98   */
99 
100 /* Exported functions --------------------------------------------------------*/
101 
102 /** @defgroup UARTEx_Exported_Functions  UARTEx Exported Functions
103   * @{
104   */
105 
106 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
107   * @brief    Extended Initialization and Configuration Functions
108   *
109 @verbatim
110 ===============================================================================
111             ##### Initialization and Configuration functions #####
112  ===============================================================================
113     [..]
114     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
115     in asynchronous mode.
116       (+) For the asynchronous mode the parameters below can be configured:
117         (++) Baud Rate
118         (++) Word Length
119         (++) Stop Bit
120         (++) Parity: If the parity is enabled, then the MSB bit of the data written
121              in the data register is transmitted but is changed by the parity bit.
122         (++) Hardware flow control
123         (++) Receiver/transmitter modes
124         (++) Over Sampling Method
125         (++) One-Bit Sampling Method
126       (+) For the asynchronous mode, the following advanced features can be configured as well:
127         (++) TX and/or RX pin level inversion
128         (++) data logical level inversion
129         (++) RX and TX pins swap
130         (++) RX overrun detection disabling
131         (++) DMA disabling on RX error
132         (++) MSB first on communication line
133         (++) auto Baud rate detection
134     [..]
135     The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
136      procedures (details for the procedures are available in reference manual).
137 
138 @endverbatim
139 
140   Depending on the frame length defined by the M1 and M0 bits (7-bit,
141   8-bit or 9-bit), the possible UART formats are listed in the
142   following table.
143 
144     Table 1. UART frame format.
145     +-----------------------------------------------------------------------+
146     |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
147     |---------|---------|-----------|---------------------------------------|
148     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
149     |---------|---------|-----------|---------------------------------------|
150     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
151     |---------|---------|-----------|---------------------------------------|
152     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
153     |---------|---------|-----------|---------------------------------------|
154     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
155     |---------|---------|-----------|---------------------------------------|
156     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
157     |---------|---------|-----------|---------------------------------------|
158     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
159     +-----------------------------------------------------------------------+
160 
161   * @{
162   */
163 
164 /**
165   * @brief Initialize the RS485 Driver enable feature according to the specified
166   *         parameters in the UART_InitTypeDef and creates the associated handle.
167   * @param huart            UART handle.
168   * @param Polarity         Select the driver enable polarity.
169   *          This parameter can be one of the following values:
170   *          @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
171   *          @arg @ref UART_DE_POLARITY_LOW  DE signal is active low
172   * @param AssertionTime    Driver Enable assertion time:
173   *       5-bit value defining the time between the activation of the DE (Driver Enable)
174   *       signal and the beginning of the start bit. It is expressed in sample time
175   *       units (1/8 or 1/16 bit time, depending on the oversampling rate)
176   * @param DeassertionTime  Driver Enable deassertion time:
177   *       5-bit value defining the time between the end of the last stop bit, in a
178   *       transmitted message, and the de-activation of the DE (Driver Enable) signal.
179   *       It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
180   *       oversampling rate).
181   * @retval HAL status
182   */
HAL_RS485Ex_Init(UART_HandleTypeDef * huart,uint32_t Polarity,uint32_t AssertionTime,uint32_t DeassertionTime)183 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime)
184 {
185   uint32_t temp = 0x0U;
186 
187   /* Check the UART handle allocation */
188   if (huart == NULL)
189   {
190     return HAL_ERROR;
191   }
192   /* Check the Driver Enable UART instance */
193   assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
194 
195   /* Check the Driver Enable polarity */
196   assert_param(IS_UART_DE_POLARITY(Polarity));
197 
198   /* Check the Driver Enable assertion time */
199   assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
200 
201   /* Check the Driver Enable deassertion time */
202   assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
203 
204   if (huart->gState == HAL_UART_STATE_RESET)
205   {
206     /* Allocate lock resource and initialize it */
207     huart->Lock = HAL_UNLOCKED;
208 
209 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
210     UART_InitCallbacksToDefault(huart);
211 
212     if (huart->MspInitCallback == NULL)
213     {
214       huart->MspInitCallback = HAL_UART_MspInit;
215     }
216 
217     /* Init the low level hardware */
218     huart->MspInitCallback(huart);
219 #else
220     /* Init the low level hardware : GPIO, CLOCK, CORTEX */
221     HAL_UART_MspInit(huart);
222 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
223   }
224 
225   huart->gState = HAL_UART_STATE_BUSY;
226 
227   /* Disable the Peripheral */
228   __HAL_UART_DISABLE(huart);
229 
230   /* Set the UART Communication parameters */
231   if (UART_SetConfig(huart) == HAL_ERROR)
232   {
233     return HAL_ERROR;
234   }
235 
236   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
237   {
238     UART_AdvFeatureConfig(huart);
239   }
240 
241   /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
242   SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
243 
244   /* Set the Driver Enable polarity */
245   MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
246 
247   /* Set the Driver Enable assertion and deassertion times */
248   temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
249   temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
250   MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
251 
252   /* Enable the Peripheral */
253   __HAL_UART_ENABLE(huart);
254 
255   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
256   return (UART_CheckIdleState(huart));
257 }
258 
259 
260 /**
261   * @}
262   */
263 
264 /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
265   *  @brief Extended functions
266   *
267 @verbatim
268  ===============================================================================
269                       ##### IO operation functions #####
270  ===============================================================================
271     This subsection provides a set of Wakeup and FIFO mode related callback functions.
272 
273     (#) Wakeup from Stop mode Callback:
274         (+) HAL_UARTEx_WakeupCallback()
275 
276     (#) TX/RX Fifos Callbacks:
277         (+) HAL_UARTEx_RxFifoFullCallback()
278         (+) HAL_UARTEx_TxFifoEmptyCallback()
279 
280 @endverbatim
281   * @{
282   */
283 
284 /**
285   * @brief UART wakeup from Stop mode callback.
286   * @param huart UART handle.
287   * @retval None
288   */
HAL_UARTEx_WakeupCallback(UART_HandleTypeDef * huart)289 __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
290 {
291   /* Prevent unused argument(s) compilation warning */
292   UNUSED(huart);
293 
294   /* NOTE : This function should not be modified, when the callback is needed,
295             the HAL_UARTEx_WakeupCallback can be implemented in the user file.
296    */
297 }
298 
299 #if defined(USART_CR1_FIFOEN)
300 /**
301   * @brief  UART RX Fifo full callback.
302   * @param  huart UART handle.
303   * @retval None
304   */
HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef * huart)305 __weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart)
306 {
307   /* Prevent unused argument(s) compilation warning */
308   UNUSED(huart);
309 
310   /* NOTE : This function should not be modified, when the callback is needed,
311             the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file.
312    */
313 }
314 
315 /**
316   * @brief  UART TX Fifo empty callback.
317   * @param  huart UART handle.
318   * @retval None
319   */
HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef * huart)320 __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
321 {
322   /* Prevent unused argument(s) compilation warning */
323   UNUSED(huart);
324 
325   /* NOTE : This function should not be modified, when the callback is needed,
326             the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file.
327    */
328 }
329 #endif
330 
331 /**
332   * @}
333   */
334 
335 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
336   * @brief    Extended Peripheral Control functions
337  *
338 @verbatim
339  ===============================================================================
340                       ##### Peripheral Control functions #####
341  ===============================================================================
342     [..] This section provides the following functions:
343      (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
344      (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
345      (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
346          detection length to more than 4 bits for multiprocessor address mark wake up.
347      (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
348          trigger: address match, Start Bit detection or RXNE bit status.
349      (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
350      (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
351      (+) HAL_UARTEx_WakeupCallback() called upon UART wakeup interrupt
352      (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode
353      (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode
354      (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
355      (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
356 
357 @endverbatim
358   * @{
359   */
360 
361 
362 
363 #if defined(USART_CR3_UCESM)
364 /**
365   * @brief  Keep UART Clock enabled when in Stop Mode.
366   * @note   When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled
367   *         this clock during STOP mode by setting the UCESM bit in USART_CR3 control register.
368   * @note   When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source,
369   *         and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set.
370   * @param  huart UART handle.
371   * @retval HAL status
372   */
HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef * huart)373 HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart)
374 {
375   /* Process Locked */
376   __HAL_LOCK(huart);
377 
378   /* Set UCESM bit */
379   SET_BIT(huart->Instance->CR3, USART_CR3_UCESM);
380 
381   /* Process Unlocked */
382   __HAL_UNLOCK(huart);
383 
384   return HAL_OK;
385 }
386 
387 /**
388   * @brief  Disable UART Clock when in Stop Mode.
389   * @param  huart UART handle.
390   * @retval HAL status
391   */
HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef * huart)392 HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart)
393 {
394   /* Process Locked */
395   __HAL_LOCK(huart);
396 
397   /* Clear UCESM bit */
398   CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM);
399 
400   /* Process Unlocked */
401   __HAL_UNLOCK(huart);
402 
403   return HAL_OK;
404 }
405 #endif /* USART_CR3_UCESM */
406 
407 /**
408   * @brief By default in multiprocessor mode, when the wake up method is set
409   *        to address mark, the UART handles only 4-bit long addresses detection;
410   *        this API allows to enable longer addresses detection (6-, 7- or 8-bit
411   *        long).
412   * @note  Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
413   *        7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
414   * @param huart         UART handle.
415   * @param AddressLength This parameter can be one of the following values:
416   *          @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
417   *          @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
418   * @retval HAL status
419   */
HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef * huart,uint32_t AddressLength)420 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
421 {
422   /* Check the UART handle allocation */
423   if (huart == NULL)
424   {
425     return HAL_ERROR;
426   }
427 
428   /* Check the address length parameter */
429   assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
430 
431   huart->gState = HAL_UART_STATE_BUSY;
432 
433   /* Disable the Peripheral */
434   __HAL_UART_DISABLE(huart);
435 
436   /* Set the address length */
437   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
438 
439   /* Enable the Peripheral */
440   __HAL_UART_ENABLE(huart);
441 
442   /* TEACK and/or REACK to check before moving huart->gState to Ready */
443   return (UART_CheckIdleState(huart));
444 }
445 
446 
447 /**
448   * @brief Set Wakeup from Stop mode interrupt flag selection.
449   * @note It is the application responsibility to enable the interrupt used as
450   *       usart_wkup interrupt source before entering low-power mode.
451   * @param huart           UART handle.
452   * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
453   *          This parameter can be one of the following values:
454   *          @arg @ref UART_WAKEUP_ON_ADDRESS
455   *          @arg @ref UART_WAKEUP_ON_STARTBIT
456   *          @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
457   * @retval HAL status
458   */
HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)459 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
460 {
461   HAL_StatusTypeDef status = HAL_OK;
462   uint32_t tickstart = 0U;
463 
464   /* check the wake-up from stop mode UART instance */
465   assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
466   /* check the wake-up selection parameter */
467   assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
468 
469   /* Process Locked */
470   __HAL_LOCK(huart);
471 
472   huart->gState = HAL_UART_STATE_BUSY;
473 
474   /* Disable the Peripheral */
475   __HAL_UART_DISABLE(huart);
476 
477   /* Set the wake-up selection scheme */
478   MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
479 
480   if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
481   {
482     UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
483   }
484 
485   /* Enable the Peripheral */
486   __HAL_UART_ENABLE(huart);
487 
488   /* Init tickstart for timeout managment*/
489   tickstart = HAL_GetTick();
490 
491   /* Wait until REACK flag is set */
492   if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
493   {
494     status = HAL_TIMEOUT;
495   }
496   else
497   {
498     /* Initialize the UART State */
499     huart->gState = HAL_UART_STATE_READY;
500   }
501 
502   /* Process Unlocked */
503   __HAL_UNLOCK(huart);
504 
505   return status;
506 }
507 
508 
509 /**
510   * @brief Enable UART Stop Mode.
511   * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
512   * @param huart UART handle.
513   * @retval HAL status
514   */
HAL_UARTEx_EnableStopMode(UART_HandleTypeDef * huart)515 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
516 {
517   /* Process Locked */
518   __HAL_LOCK(huart);
519 
520   /* Set UESM bit */
521   SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
522 
523   /* Process Unlocked */
524   __HAL_UNLOCK(huart);
525 
526   return HAL_OK;
527 }
528 
529 /**
530   * @brief Disable UART Stop Mode.
531   * @param huart UART handle.
532   * @retval HAL status
533   */
HAL_UARTEx_DisableStopMode(UART_HandleTypeDef * huart)534 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
535 {
536   /* Process Locked */
537   __HAL_LOCK(huart);
538 
539   /* Clear UESM bit */
540   CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
541 
542   /* Process Unlocked */
543   __HAL_UNLOCK(huart);
544 
545   return HAL_OK;
546 }
547 
548 #if defined(USART_CR1_FIFOEN)
549 /**
550   * @brief  Enable the FIFO mode.
551   * @param huart      UART handle.
552   * @retval HAL status
553   */
HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef * huart)554 HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart)
555 {
556   uint32_t tmpcr1 = 0U;
557 
558   /* Check parameters */
559   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
560 
561   /* Process Locked */
562   __HAL_LOCK(huart);
563 
564   huart->gState = HAL_UART_STATE_BUSY;
565 
566   /* Save actual UART configuration */
567   tmpcr1 = READ_REG(huart->Instance->CR1);
568 
569   /* Disable UART */
570   __HAL_UART_DISABLE(huart);
571 
572   /* Enable FIFO mode */
573   SET_BIT(tmpcr1, USART_CR1_FIFOEN);
574   huart->FifoMode = UART_FIFOMODE_ENABLE;
575 
576   /* Restore UART configuration */
577   WRITE_REG(huart->Instance->CR1, tmpcr1);
578 
579   /* Determine the number of data to process during RX/TX ISR execution */
580   UARTEx_SetNbDataToProcess(huart);
581 
582   huart->gState = HAL_UART_STATE_READY;
583 
584   /* Process Unlocked */
585   __HAL_UNLOCK(huart);
586 
587   return HAL_OK;
588 }
589 
590 /**
591   * @brief  Disable the FIFO mode.
592   * @param huart      UART handle.
593   * @retval HAL status
594   */
HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef * huart)595 HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart)
596 {
597   uint32_t tmpcr1 = 0U;
598 
599   /* Check parameters */
600   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
601 
602   /* Process Locked */
603   __HAL_LOCK(huart);
604 
605   huart->gState = HAL_UART_STATE_BUSY;
606 
607   /* Save actual UART configuration */
608   tmpcr1 = READ_REG(huart->Instance->CR1);
609 
610   /* Disable UART */
611   __HAL_UART_DISABLE(huart);
612 
613   /* Enable FIFO mode */
614   CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
615   huart->FifoMode = UART_FIFOMODE_DISABLE;
616 
617   /* Restore UART configuration */
618   WRITE_REG(huart->Instance->CR1, tmpcr1);
619 
620   huart->gState = HAL_UART_STATE_READY;
621 
622   /* Process Unlocked */
623   __HAL_UNLOCK(huart);
624 
625   return HAL_OK;
626 }
627 
628 /**
629   * @brief  Set the TXFIFO threshold.
630   * @param huart      UART handle.
631   * @param Threshold  TX FIFO threshold value
632   *          This parameter can be one of the following values:
633   *            @arg @ref UART_TXFIFO_THRESHOLD_1_8
634   *            @arg @ref UART_TXFIFO_THRESHOLD_1_4
635   *            @arg @ref UART_TXFIFO_THRESHOLD_1_2
636   *            @arg @ref UART_TXFIFO_THRESHOLD_3_4
637   *            @arg @ref UART_TXFIFO_THRESHOLD_7_8
638   *            @arg @ref UART_TXFIFO_THRESHOLD_8_8
639   * @retval HAL status
640   */
HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef * huart,uint32_t Threshold)641 HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
642 {
643   uint32_t tmpcr1 = 0U;
644 
645   /* Check parameters */
646   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
647   assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold));
648 
649   /* Process Locked */
650   __HAL_LOCK(huart);
651 
652   huart->gState = HAL_UART_STATE_BUSY;
653 
654   /* Save actual UART configuration */
655   tmpcr1 = READ_REG(huart->Instance->CR1);
656 
657   /* Disable UART */
658   __HAL_UART_DISABLE(huart);
659 
660   /* Update TX threshold configuration */
661   MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
662 
663   /* Determine the number of data to process during RX/TX ISR execution */
664   UARTEx_SetNbDataToProcess(huart);
665 
666   /* Restore UART configuration */
667   WRITE_REG(huart->Instance->CR1, tmpcr1);
668 
669   huart->gState = HAL_UART_STATE_READY;
670 
671   /* Process Unlocked */
672   __HAL_UNLOCK(huart);
673 
674   return HAL_OK;
675 }
676 
677 /**
678   * @brief  Set the RXFIFO threshold.
679   * @param huart      UART handle.
680   * @param Threshold  RX FIFO threshold value
681   *          This parameter can be one of the following values:
682   *            @arg @ref UART_RXFIFO_THRESHOLD_1_8
683   *            @arg @ref UART_RXFIFO_THRESHOLD_1_4
684   *            @arg @ref UART_RXFIFO_THRESHOLD_1_2
685   *            @arg @ref UART_RXFIFO_THRESHOLD_3_4
686   *            @arg @ref UART_RXFIFO_THRESHOLD_7_8
687   *            @arg @ref UART_RXFIFO_THRESHOLD_8_8
688   * @retval HAL status
689   */
HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef * huart,uint32_t Threshold)690 HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
691 {
692   uint32_t tmpcr1 = 0U;
693 
694   /* Check the parameters */
695   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
696   assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold));
697 
698   /* Process Locked */
699   __HAL_LOCK(huart);
700 
701   huart->gState = HAL_UART_STATE_BUSY;
702 
703   /* Save actual UART configuration */
704   tmpcr1 = READ_REG(huart->Instance->CR1);
705 
706   /* Disable UART */
707   __HAL_UART_DISABLE(huart);
708 
709   /* Update RX threshold configuration */
710   MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
711 
712   /* Determine the number of data to process during RX/TX ISR execution */
713   UARTEx_SetNbDataToProcess(huart);
714 
715   /* Restore UART configuration */
716   WRITE_REG(huart->Instance->CR1, tmpcr1);
717 
718   huart->gState = HAL_UART_STATE_READY;
719 
720   /* Process Unlocked */
721   __HAL_UNLOCK(huart);
722 
723   return HAL_OK;
724 }
725 #endif
726 
727 /**
728   * @}
729   */
730 
731 /**
732   * @}
733   */
734 
735 /** @addtogroup UARTEx_Private_Functions
736   * @{
737   */
738 
739 /**
740   * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
741   * @param huart           UART handle.
742   * @param WakeUpSelection UART wake up from stop mode parameters.
743   * @retval None
744   */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)745 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
746 {
747   assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
748 
749   /* Set the USART address length */
750   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
751 
752   /* Set the USART address node */
753   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
754 }
755 
756 #if defined(USART_CR1_FIFOEN)
757 /**
758   * @brief Calculate the number of data to process in RX/TX ISR.
759   * @note The RX FIFO depth and the TX FIFO depth is extracted from
760   *       the UART configuration registers.
761   * @param huart UART handle.
762   * @retval None
763   */
UARTEx_SetNbDataToProcess(UART_HandleTypeDef * huart)764 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
765 {
766   uint8_t rx_fifo_depth;
767   uint8_t tx_fifo_depth;
768   uint8_t rx_fifo_threshold;
769   uint8_t tx_fifo_threshold;
770   uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U};
771   uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U};
772 
773   if (huart->FifoMode == UART_FIFOMODE_DISABLE)
774   {
775     huart->NbTxDataToProcess = 1U;
776     huart->NbRxDataToProcess = 1U;
777   }
778   else
779   {
780     rx_fifo_depth = RX_FIFO_DEPTH;
781     tx_fifo_depth = TX_FIFO_DEPTH;
782     rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
783     tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
784     huart->NbTxDataToProcess = (uint8_t)(tx_fifo_depth * numerator[tx_fifo_threshold]) / denominator[tx_fifo_threshold];
785     huart->NbRxDataToProcess = (uint8_t)(rx_fifo_depth * numerator[rx_fifo_threshold]) / denominator[rx_fifo_threshold];
786   }
787 }
788 #endif
789 /**
790   * @}
791   */
792 
793 #endif /* HAL_UART_MODULE_ENABLED */
794 
795 /**
796   * @}
797   */
798 
799 /**
800   * @}
801   */
802 
803 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
804