1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_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   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                ##### UART peripheral extended features  #####
26   ==============================================================================
27 
28     (#) Declare a UART_HandleTypeDef handle structure.
29 
30     (#) For the UART RS485 Driver Enable mode, initialize the UART registers
31         by calling the HAL_RS485Ex_Init() API.
32 
33     (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
34 
35         -@- When UART operates in FIFO mode, FIFO mode must be enabled prior
36             starting RX/TX transfers. Also RX/TX FIFO thresholds must be
37             configured prior starting RX/TX transfers.
38 
39   @endverbatim
40   ******************************************************************************
41   */
42 
43 /* Includes ------------------------------------------------------------------*/
44 #include "stm32wbaxx_hal.h"
45 
46 /** @addtogroup STM32WBAxx_HAL_Driver
47   * @{
48   */
49 
50 /** @defgroup UARTEx UARTEx
51   * @brief UART Extended HAL module driver
52   * @{
53   */
54 
55 #ifdef HAL_UART_MODULE_ENABLED
56 
57 /* Private typedef -----------------------------------------------------------*/
58 /* Private define ------------------------------------------------------------*/
59 /** @defgroup UARTEX_Private_Constants UARTEx Private Constants
60   * @{
61   */
62 /* UART RX FIFO depth */
63 #define RX_FIFO_DEPTH 8U
64 
65 /* UART TX FIFO depth */
66 #define TX_FIFO_DEPTH 8U
67 /**
68   * @}
69   */
70 
71 /* Private macros ------------------------------------------------------------*/
72 /* Private variables ---------------------------------------------------------*/
73 /* Private function prototypes -----------------------------------------------*/
74 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
75   * @{
76   */
77 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
78 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart);
79 /**
80   * @}
81   */
82 
83 /* Exported functions --------------------------------------------------------*/
84 
85 /** @defgroup UARTEx_Exported_Functions  UARTEx Exported Functions
86   * @{
87   */
88 
89 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
90   * @brief    Extended Initialization and Configuration Functions
91   *
92 @verbatim
93 ===============================================================================
94             ##### Initialization and Configuration functions #####
95  ===============================================================================
96     [..]
97     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
98     in asynchronous mode.
99       (+) For the asynchronous mode the parameters below can be configured:
100         (++) Baud Rate
101         (++) Word Length
102         (++) Stop Bit
103         (++) Parity: If the parity is enabled, then the MSB bit of the data written
104              in the data register is transmitted but is changed by the parity bit.
105         (++) Hardware flow control
106         (++) Receiver/transmitter modes
107         (++) Over Sampling Method
108         (++) One-Bit Sampling Method
109       (+) For the asynchronous mode, the following advanced features can be configured as well:
110         (++) TX and/or RX pin level inversion
111         (++) data logical level inversion
112         (++) RX and TX pins swap
113         (++) RX overrun detection disabling
114         (++) DMA disabling on RX error
115         (++) MSB first on communication line
116         (++) auto Baud rate detection
117     [..]
118     The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
119      procedures (details for the procedures are available in reference manual).
120 
121 @endverbatim
122 
123   Depending on the frame length defined by the M1 and M0 bits (7-bit,
124   8-bit or 9-bit), the possible UART formats are listed in the
125   following table.
126 
127     Table 1. UART frame format.
128     +-----------------------------------------------------------------------+
129     |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
130     |---------|---------|-----------|---------------------------------------|
131     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
132     |---------|---------|-----------|---------------------------------------|
133     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
134     |---------|---------|-----------|---------------------------------------|
135     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
136     |---------|---------|-----------|---------------------------------------|
137     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
138     |---------|---------|-----------|---------------------------------------|
139     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
140     |---------|---------|-----------|---------------------------------------|
141     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
142     +-----------------------------------------------------------------------+
143 
144   * @{
145   */
146 
147 /**
148   * @brief Initialize the RS485 Driver enable feature according to the specified
149   *         parameters in the UART_InitTypeDef and creates the associated handle.
150   * @param huart            UART handle.
151   * @param Polarity         Select the driver enable polarity.
152   *          This parameter can be one of the following values:
153   *          @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
154   *          @arg @ref UART_DE_POLARITY_LOW  DE signal is active low
155   * @param AssertionTime    Driver Enable assertion time:
156   *       5-bit value defining the time between the activation of the DE (Driver Enable)
157   *       signal and the beginning of the start bit. It is expressed in sample time
158   *       units (1/8 or 1/16 bit time, depending on the oversampling rate)
159   * @param DeassertionTime  Driver Enable deassertion time:
160   *       5-bit value defining the time between the end of the last stop bit, in a
161   *       transmitted message, and the de-activation of the DE (Driver Enable) signal.
162   *       It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
163   *       oversampling rate).
164   * @retval HAL status
165   */
HAL_RS485Ex_Init(UART_HandleTypeDef * huart,uint32_t Polarity,uint32_t AssertionTime,uint32_t DeassertionTime)166 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime,
167                                    uint32_t DeassertionTime)
168 {
169   uint32_t temp;
170 
171   /* Check the UART handle allocation */
172   if (huart == NULL)
173   {
174     return HAL_ERROR;
175   }
176   /* Check the Driver Enable UART instance */
177   assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
178 
179   /* Check the Driver Enable polarity */
180   assert_param(IS_UART_DE_POLARITY(Polarity));
181 
182   /* Check the Driver Enable assertion time */
183   assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
184 
185   /* Check the Driver Enable deassertion time */
186   assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
187 
188   if (huart->gState == HAL_UART_STATE_RESET)
189   {
190     /* Allocate lock resource and initialize it */
191     huart->Lock = HAL_UNLOCKED;
192 
193 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
194     UART_InitCallbacksToDefault(huart);
195 
196     if (huart->MspInitCallback == NULL)
197     {
198       huart->MspInitCallback = HAL_UART_MspInit;
199     }
200 
201     /* Init the low level hardware */
202     huart->MspInitCallback(huart);
203 #else
204     /* Init the low level hardware : GPIO, CLOCK, CORTEX */
205     HAL_UART_MspInit(huart);
206 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
207   }
208 
209   huart->gState = HAL_UART_STATE_BUSY;
210 
211   /* Disable the Peripheral */
212   __HAL_UART_DISABLE(huart);
213 
214   /* Perform advanced settings configuration */
215   /* For some items, configuration requires to be done prior TE and RE bits are set */
216   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
217   {
218     UART_AdvFeatureConfig(huart);
219   }
220 
221   /* Set the UART Communication parameters */
222   if (UART_SetConfig(huart) == HAL_ERROR)
223   {
224     return HAL_ERROR;
225   }
226 
227   /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
228   SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
229 
230   /* Set the Driver Enable polarity */
231   MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
232 
233   /* Set the Driver Enable assertion and deassertion times */
234   temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
235   temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
236   MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
237 
238   /* Enable the Peripheral */
239   __HAL_UART_ENABLE(huart);
240 
241   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
242   return (UART_CheckIdleState(huart));
243 }
244 
245 /**
246   * @}
247   */
248 
249 /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
250   *  @brief Extended functions
251   *
252 @verbatim
253  ===============================================================================
254                       ##### IO operation functions #####
255  ===============================================================================
256     This subsection provides a set of Wakeup and FIFO mode related callback functions.
257 
258     (#) TX/RX Fifos Callbacks:
259         (+) HAL_UARTEx_RxFifoFullCallback()
260         (+) HAL_UARTEx_TxFifoEmptyCallback()
261 
262 @endverbatim
263   * @{
264   */
265 
266 /**
267   * @brief  UART RX Fifo full callback.
268   * @param  huart UART handle.
269   * @retval None
270   */
HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef * huart)271 __weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart)
272 {
273   /* Prevent unused argument(s) compilation warning */
274   UNUSED(huart);
275 
276   /* NOTE : This function should not be modified, when the callback is needed,
277             the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file.
278    */
279 }
280 
281 /**
282   * @brief  UART TX Fifo empty callback.
283   * @param  huart UART handle.
284   * @retval None
285   */
HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef * huart)286 __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
287 {
288   /* Prevent unused argument(s) compilation warning */
289   UNUSED(huart);
290 
291   /* NOTE : This function should not be modified, when the callback is needed,
292             the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file.
293    */
294 }
295 
296 /**
297   * @}
298   */
299 
300 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
301   * @brief    Extended Peripheral Control functions
302   *
303 @verbatim
304  ===============================================================================
305                       ##### Peripheral Control functions #####
306  ===============================================================================
307     [..] This section provides the following functions:
308      (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
309          detection length to more than 4 bits for multiprocessor address mark wake up.
310      (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
311          trigger: address match, Start Bit detection or RXNE bit status.
312      (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
313      (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
314      (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode
315      (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode
316      (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
317      (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
318 
319     [..] This subsection also provides a set of additional functions providing enhanced reception
320     services to user. (For example, these functions allow application to handle use cases
321     where number of data to be received is unknown).
322 
323     (#) Compared to standard reception services which only consider number of received
324         data elements as reception completion criteria, these functions also consider additional events
325         as triggers for updating reception status to caller :
326        (+) Detection of inactivity period (RX line has not been active for a given period).
327           (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
328                for 1 frame time, after last received byte.
329           (++) RX inactivity detected by RTO, i.e. line has been in idle state
330                for a programmable time, after last received byte.
331        (+) Detection that a specific character has been received.
332 
333     (#) There are two mode of transfer:
334        (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
335            or till IDLE event occurs. Reception is handled only during function execution.
336            When function exits, no data reception could occur. HAL status and number of actually received data elements,
337            are returned by function after finishing transfer.
338        (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
339            These API's return the HAL status.
340            The end of the data processing will be indicated through the
341            dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
342            The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
343            The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
344 
345     (#) Blocking mode API:
346         (+) HAL_UARTEx_ReceiveToIdle()
347 
348     (#) Non-Blocking mode API with Interrupt:
349         (+) HAL_UARTEx_ReceiveToIdle_IT()
350 
351     (#) Non-Blocking mode API with DMA:
352         (+) HAL_UARTEx_ReceiveToIdle_DMA()
353 
354 @endverbatim
355   * @{
356   */
357 
358 /**
359   * @brief By default in multiprocessor mode, when the wake up method is set
360   *        to address mark, the UART handles only 4-bit long addresses detection;
361   *        this API allows to enable longer addresses detection (6-, 7- or 8-bit
362   *        long).
363   * @note  Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
364   *        7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
365   * @param huart         UART handle.
366   * @param AddressLength This parameter can be one of the following values:
367   *          @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
368   *          @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
369   * @retval HAL status
370   */
HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef * huart,uint32_t AddressLength)371 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
372 {
373   /* Check the UART handle allocation */
374   if (huart == NULL)
375   {
376     return HAL_ERROR;
377   }
378 
379   /* Check the address length parameter */
380   assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
381 
382   huart->gState = HAL_UART_STATE_BUSY;
383 
384   /* Disable the Peripheral */
385   __HAL_UART_DISABLE(huart);
386 
387   /* Set the address length */
388   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
389 
390   /* Enable the Peripheral */
391   __HAL_UART_ENABLE(huart);
392 
393   /* TEACK and/or REACK to check before moving huart->gState to Ready */
394   return (UART_CheckIdleState(huart));
395 }
396 
397 /**
398   * @brief Set Wakeup from Stop mode interrupt flag selection.
399   * @note It is the application responsibility to enable the interrupt used as
400   *       usart_wkup interrupt source before entering low-power mode.
401   * @param huart           UART handle.
402   * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
403   *          This parameter can be one of the following values:
404   *          @arg @ref UART_WAKEUP_ON_ADDRESS
405   *          @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
406   * @retval HAL status
407   */
HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)408 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
409 {
410   HAL_StatusTypeDef status = HAL_OK;
411   uint32_t tickstart;
412 
413   /* check the wake-up from stop mode UART instance */
414   assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
415   /* check the wake-up selection parameter */
416   assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
417 
418   /* Process Locked */
419   __HAL_LOCK(huart);
420 
421   huart->gState = HAL_UART_STATE_BUSY;
422 
423   /* Disable the Peripheral */
424   __HAL_UART_DISABLE(huart);
425 
426 
427   if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
428   {
429     UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
430   }
431 
432   /* Enable the Peripheral */
433   __HAL_UART_ENABLE(huart);
434 
435   /* Init tickstart for timeout management */
436   tickstart = HAL_GetTick();
437 
438   /* Wait until REACK flag is set */
439   if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
440   {
441     status = HAL_TIMEOUT;
442   }
443   else
444   {
445     /* Initialize the UART State */
446     huart->gState = HAL_UART_STATE_READY;
447   }
448 
449   /* Process Unlocked */
450   __HAL_UNLOCK(huart);
451 
452   return status;
453 }
454 
455 /**
456   * @brief Enable UART Stop Mode.
457   * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
458   * @param huart UART handle.
459   * @retval HAL status
460   */
HAL_UARTEx_EnableStopMode(UART_HandleTypeDef * huart)461 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
462 {
463   /* Process Locked */
464   __HAL_LOCK(huart);
465 
466   /* Set UESM bit */
467   ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
468 
469   /* Process Unlocked */
470   __HAL_UNLOCK(huart);
471 
472   return HAL_OK;
473 }
474 
475 /**
476   * @brief Disable UART Stop Mode.
477   * @param huart UART handle.
478   * @retval HAL status
479   */
HAL_UARTEx_DisableStopMode(UART_HandleTypeDef * huart)480 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
481 {
482   /* Process Locked */
483   __HAL_LOCK(huart);
484 
485   /* Clear UESM bit */
486   ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
487 
488   /* Process Unlocked */
489   __HAL_UNLOCK(huart);
490 
491   return HAL_OK;
492 }
493 
494 /**
495   * @brief  Enable the FIFO mode.
496   * @param huart      UART handle.
497   * @retval HAL status
498   */
HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef * huart)499 HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart)
500 {
501   uint32_t tmpcr1;
502 
503   /* Check parameters */
504   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
505 
506   /* Process Locked */
507   __HAL_LOCK(huart);
508 
509   huart->gState = HAL_UART_STATE_BUSY;
510 
511   /* Save actual UART configuration */
512   tmpcr1 = READ_REG(huart->Instance->CR1);
513 
514   /* Disable UART */
515   __HAL_UART_DISABLE(huart);
516 
517   /* Enable FIFO mode */
518   SET_BIT(tmpcr1, USART_CR1_FIFOEN);
519   huart->FifoMode = UART_FIFOMODE_ENABLE;
520 
521   /* Restore UART configuration */
522   WRITE_REG(huart->Instance->CR1, tmpcr1);
523 
524   /* Determine the number of data to process during RX/TX ISR execution */
525   UARTEx_SetNbDataToProcess(huart);
526 
527   huart->gState = HAL_UART_STATE_READY;
528 
529   /* Process Unlocked */
530   __HAL_UNLOCK(huart);
531 
532   return HAL_OK;
533 }
534 
535 /**
536   * @brief  Disable the FIFO mode.
537   * @param huart      UART handle.
538   * @retval HAL status
539   */
HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef * huart)540 HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart)
541 {
542   uint32_t tmpcr1;
543 
544   /* Check parameters */
545   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
546 
547   /* Process Locked */
548   __HAL_LOCK(huart);
549 
550   huart->gState = HAL_UART_STATE_BUSY;
551 
552   /* Save actual UART configuration */
553   tmpcr1 = READ_REG(huart->Instance->CR1);
554 
555   /* Disable UART */
556   __HAL_UART_DISABLE(huart);
557 
558   /* Enable FIFO mode */
559   CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
560   huart->FifoMode = UART_FIFOMODE_DISABLE;
561 
562   /* Restore UART configuration */
563   WRITE_REG(huart->Instance->CR1, tmpcr1);
564 
565   huart->gState = HAL_UART_STATE_READY;
566 
567   /* Process Unlocked */
568   __HAL_UNLOCK(huart);
569 
570   return HAL_OK;
571 }
572 
573 /**
574   * @brief  Set the TXFIFO threshold.
575   * @param huart      UART handle.
576   * @param Threshold  TX FIFO threshold value
577   *          This parameter can be one of the following values:
578   *            @arg @ref UART_TXFIFO_THRESHOLD_1_8
579   *            @arg @ref UART_TXFIFO_THRESHOLD_1_4
580   *            @arg @ref UART_TXFIFO_THRESHOLD_1_2
581   *            @arg @ref UART_TXFIFO_THRESHOLD_3_4
582   *            @arg @ref UART_TXFIFO_THRESHOLD_7_8
583   *            @arg @ref UART_TXFIFO_THRESHOLD_8_8
584   * @retval HAL status
585   */
HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef * huart,uint32_t Threshold)586 HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
587 {
588   uint32_t tmpcr1;
589 
590   /* Check parameters */
591   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
592   assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold));
593 
594   /* Process Locked */
595   __HAL_LOCK(huart);
596 
597   huart->gState = HAL_UART_STATE_BUSY;
598 
599   /* Save actual UART configuration */
600   tmpcr1 = READ_REG(huart->Instance->CR1);
601 
602   /* Disable UART */
603   __HAL_UART_DISABLE(huart);
604 
605   /* Update TX threshold configuration */
606   MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
607 
608   /* Determine the number of data to process during RX/TX ISR execution */
609   UARTEx_SetNbDataToProcess(huart);
610 
611   /* Restore UART configuration */
612   WRITE_REG(huart->Instance->CR1, tmpcr1);
613 
614   huart->gState = HAL_UART_STATE_READY;
615 
616   /* Process Unlocked */
617   __HAL_UNLOCK(huart);
618 
619   return HAL_OK;
620 }
621 
622 /**
623   * @brief  Set the RXFIFO threshold.
624   * @param huart      UART handle.
625   * @param Threshold  RX FIFO threshold value
626   *          This parameter can be one of the following values:
627   *            @arg @ref UART_RXFIFO_THRESHOLD_1_8
628   *            @arg @ref UART_RXFIFO_THRESHOLD_1_4
629   *            @arg @ref UART_RXFIFO_THRESHOLD_1_2
630   *            @arg @ref UART_RXFIFO_THRESHOLD_3_4
631   *            @arg @ref UART_RXFIFO_THRESHOLD_7_8
632   *            @arg @ref UART_RXFIFO_THRESHOLD_8_8
633   * @retval HAL status
634   */
HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef * huart,uint32_t Threshold)635 HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
636 {
637   uint32_t tmpcr1;
638 
639   /* Check the parameters */
640   assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
641   assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold));
642 
643   /* Process Locked */
644   __HAL_LOCK(huart);
645 
646   huart->gState = HAL_UART_STATE_BUSY;
647 
648   /* Save actual UART configuration */
649   tmpcr1 = READ_REG(huart->Instance->CR1);
650 
651   /* Disable UART */
652   __HAL_UART_DISABLE(huart);
653 
654   /* Update RX threshold configuration */
655   MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
656 
657   /* Determine the number of data to process during RX/TX ISR execution */
658   UARTEx_SetNbDataToProcess(huart);
659 
660   /* Restore UART configuration */
661   WRITE_REG(huart->Instance->CR1, tmpcr1);
662 
663   huart->gState = HAL_UART_STATE_READY;
664 
665   /* Process Unlocked */
666   __HAL_UNLOCK(huart);
667 
668   return HAL_OK;
669 }
670 
671 /**
672   * @brief Receive an amount of data in blocking mode till either the expected number of data
673   *        is received or an IDLE event occurs.
674   * @note  HAL_OK is returned if reception is completed (expected number of data has been received)
675   *        or if reception is stopped after IDLE event (less than the expected number of data has been received)
676   *        In this case, RxLen output parameter indicates number of data available in reception buffer.
677   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
678   *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
679   *        of uint16_t available through pData.
680   * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
681   *       is not empty. Read operations from the RDR register are performed when
682   *       RXFNE flag is set. From hardware perspective, RXFNE flag and
683   *       RXNE are mapped on the same bit-field.
684   * @param huart   UART handle.
685   * @param pData   Pointer to data buffer (uint8_t or uint16_t data elements).
686   * @param Size    Amount of data elements (uint8_t or uint16_t) to be received.
687   * @param RxLen   Number of data elements finally received
688   *                (could be lower than Size, in case reception ends on IDLE event)
689   * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
690   * @retval HAL status
691   */
HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint16_t * RxLen,uint32_t Timeout)692 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
693                                            uint32_t Timeout)
694 {
695   uint8_t  *pdata8bits;
696   uint16_t *pdata16bits;
697   uint16_t uhMask;
698   uint32_t tickstart;
699 
700   /* Check that a Rx process is not already ongoing */
701   if (huart->RxState == HAL_UART_STATE_READY)
702   {
703     if ((pData == NULL) || (Size == 0U))
704     {
705       return  HAL_ERROR;
706     }
707 
708     huart->ErrorCode = HAL_UART_ERROR_NONE;
709     huart->RxState = HAL_UART_STATE_BUSY_RX;
710     huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
711     huart->RxEventType = HAL_UART_RXEVENT_TC;
712 
713     /* Init tickstart for timeout management */
714     tickstart = HAL_GetTick();
715 
716     huart->RxXferSize  = Size;
717     huart->RxXferCount = Size;
718 
719     /* Computation of UART mask to apply to RDR register */
720     UART_MASK_COMPUTATION(huart);
721     uhMask = huart->Mask;
722 
723     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
724     if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
725     {
726       pdata8bits  = NULL;
727       pdata16bits = (uint16_t *) pData;
728     }
729     else
730     {
731       pdata8bits  = pData;
732       pdata16bits = NULL;
733     }
734 
735     /* Initialize output number of received elements */
736     *RxLen = 0U;
737 
738     /* as long as data have to be received */
739     while (huart->RxXferCount > 0U)
740     {
741       /* Check if IDLE flag is set */
742       if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
743       {
744         /* Clear IDLE flag in ISR */
745         __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
746 
747         /* If Set, but no data ever received, clear flag without exiting loop */
748         /* If Set, and data has already been received, this means Idle Event is valid : End reception */
749         if (*RxLen > 0U)
750         {
751           huart->RxEventType = HAL_UART_RXEVENT_IDLE;
752           huart->RxState = HAL_UART_STATE_READY;
753 
754           return HAL_OK;
755         }
756       }
757 
758       /* Check if RXNE flag is set */
759       if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
760       {
761         if (pdata8bits == NULL)
762         {
763           *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
764           pdata16bits++;
765         }
766         else
767         {
768           *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
769           pdata8bits++;
770         }
771         /* Increment number of received elements */
772         *RxLen += 1U;
773         huart->RxXferCount--;
774       }
775 
776       /* Check for the Timeout */
777       if (Timeout != HAL_MAX_DELAY)
778       {
779         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
780         {
781           huart->RxState = HAL_UART_STATE_READY;
782 
783           return HAL_TIMEOUT;
784         }
785       }
786     }
787 
788     /* Set number of received elements in output parameter : RxLen */
789     *RxLen = huart->RxXferSize - huart->RxXferCount;
790     /* At end of Rx process, restore huart->RxState to Ready */
791     huart->RxState = HAL_UART_STATE_READY;
792 
793     return HAL_OK;
794   }
795   else
796   {
797     return HAL_BUSY;
798   }
799 }
800 
801 /**
802   * @brief Receive an amount of data in interrupt mode till either the expected number of data
803   *        is received or an IDLE event occurs.
804   * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
805   *        to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
806   *        number of received data elements.
807   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
808   *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
809   *        of uint16_t available through pData.
810   * @param huart UART handle.
811   * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
812   * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
813   * @retval HAL status
814   */
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)815 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
816 {
817   HAL_StatusTypeDef status = HAL_OK;
818 
819   /* Check that a Rx process is not already ongoing */
820   if (huart->RxState == HAL_UART_STATE_READY)
821   {
822     if ((pData == NULL) || (Size == 0U))
823     {
824       return HAL_ERROR;
825     }
826 
827     /* Set Reception type to reception till IDLE Event*/
828     huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
829     huart->RxEventType = HAL_UART_RXEVENT_TC;
830 
831     (void)UART_Start_Receive_IT(huart, pData, Size);
832 
833     if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
834     {
835       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
836       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
837     }
838     else
839     {
840       /* In case of errors already pending when reception is started,
841          Interrupts may have already been raised and lead to reception abortion.
842          (Overrun error for instance).
843          In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
844       status = HAL_ERROR;
845     }
846 
847     return status;
848   }
849   else
850   {
851     return HAL_BUSY;
852   }
853 }
854 
855 #if defined(HAL_DMA_MODULE_ENABLED)
856 /**
857   * @brief Receive an amount of data in DMA mode till either the expected number
858   *        of data is received or an IDLE event occurs.
859   * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
860   *        to DMA services, transferring automatically received data elements in user reception buffer and
861   *        calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
862   *        reception phase as ended. In all cases, callback execution will indicate number of received data elements.
863   * @note  When the UART parity is enabled (PCE = 1), the received data contain
864   *        the parity bit (MSB position).
865   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
866   *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
867   *        of uint16_t available through pData.
868   * @param huart UART handle.
869   * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
870   * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
871   * @retval HAL status
872   */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)873 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
874 {
875   HAL_StatusTypeDef status;
876 
877   /* Check that a Rx process is not already ongoing */
878   if (huart->RxState == HAL_UART_STATE_READY)
879   {
880     if ((pData == NULL) || (Size == 0U))
881     {
882       return HAL_ERROR;
883     }
884 
885     /* Set Reception type to reception till IDLE Event*/
886     huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
887     huart->RxEventType = HAL_UART_RXEVENT_TC;
888 
889     status =  UART_Start_Receive_DMA(huart, pData, Size);
890 
891     /* Check Rx process has been successfully started */
892     if (status == HAL_OK)
893     {
894       if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
895       {
896         __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
897         ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
898       }
899       else
900       {
901         /* In case of errors already pending when reception is started,
902            Interrupts may have already been raised and lead to reception abortion.
903            (Overrun error for instance).
904            In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
905         status = HAL_ERROR;
906       }
907     }
908 
909     return status;
910   }
911   else
912   {
913     return HAL_BUSY;
914   }
915 }
916 #endif /* HAL_DMA_MODULE_ENABLED */
917 
918 /**
919   * @brief Provide Rx Event type that has lead to RxEvent callback execution.
920   * @note  When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
921   *        of reception process is provided to application through calls of Rx Event callback (either default one
922   *        HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
923   *        Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
924   *        to Rx Event callback execution.
925   * @note  This function is expected to be called within the user implementation of Rx Event Callback,
926   *        in order to provide the accurate value :
927   *        In Interrupt Mode :
928   *           - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
929   *           - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
930   *             received data is lower than expected one)
931   *        In DMA Mode :
932   *           - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
933   *           - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
934   *           - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
935   *             received data is lower than expected one).
936   *        In DMA mode, RxEvent callback could be called several times;
937   *        When DMA is configured in Normal Mode, HT event does not stop Reception process;
938   *        When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
939   * @param  huart UART handle.
940   * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
941   */
HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef * huart)942 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart)
943 {
944   /* Return Rx Event type value, as stored in UART handle */
945   return (huart->RxEventType);
946 }
947 
948 /**
949   * @brief Set autonomous mode Configuration.
950   * @param huart     UART handle.
951   * @param sConfig   Autonomous mode structure parameters.
952   * @retval HAL status
953   */
HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef * huart,const UART_AutonomousModeConfTypeDef * sConfig)954 HAL_StatusTypeDef HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef *huart,
955                                                      const UART_AutonomousModeConfTypeDef *sConfig)
956 {
957   uint32_t tmpreg;
958 
959   if (huart->gState == HAL_UART_STATE_READY)
960   {
961     /* Check the parameters */
962     assert_param(IS_UART_TRIGGER_POLARITY(sConfig->TriggerPolarity));
963     assert_param(IS_UART_IDLE_FRAME_TRANSMIT(sConfig->IdleFrame));
964     assert_param(IS_UART_TX_DATA_SIZE(sConfig->DataSize));
965     if (IS_LPUART_INSTANCE(huart->Instance))
966     {
967       assert_param(IS_LPUART_TRIGGER_SELECTION(sConfig->TriggerSelection));
968     }
969     else
970     {
971       assert_param(IS_UART_TRIGGER_SELECTION(sConfig->TriggerSelection));
972     }
973 
974     /* Process Locked */
975     __HAL_LOCK(huart);
976 
977     huart->gState = HAL_UART_STATE_BUSY;
978 
979     /* Disable UART */
980     __HAL_UART_DISABLE(huart);
981 
982     /* Disable Transmitter */
983     CLEAR_BIT(huart->Instance->CR1, USART_CR1_TE);
984 
985     /* Clear AUTOCR register */
986     CLEAR_REG(huart->Instance->AUTOCR);
987 
988     /* UART AUTOCR Configuration */
989     tmpreg = ((sConfig->DataSize << USART_AUTOCR_TDN_Pos) | (sConfig->TriggerPolarity) | \
990               (sConfig->AutonomousModeState) | (sConfig->IdleFrame) | \
991               (sConfig->TriggerSelection << USART_AUTOCR_TRIGSEL_Pos));
992 
993     WRITE_REG(huart->Instance->AUTOCR, tmpreg);
994 
995     /* Enable UART */
996     __HAL_UART_ENABLE(huart);
997 
998     huart->gState = HAL_UART_STATE_READY;
999 
1000     /* Process Unlocked */
1001     __HAL_UNLOCK(huart);
1002 
1003     return HAL_OK;
1004   }
1005   else
1006   {
1007     return HAL_BUSY;
1008   }
1009 }
1010 
1011 /**
1012   * @brief Get autonomous mode Configuration.
1013   * @param huart     UART handle.
1014   * @param sConfig   Autonomous mode structure parameters.
1015   * @retval HAL status
1016   */
HAL_UARTEx_GetConfigAutonomousMode(const UART_HandleTypeDef * huart,UART_AutonomousModeConfTypeDef * sConfig)1017 HAL_StatusTypeDef HAL_UARTEx_GetConfigAutonomousMode(const UART_HandleTypeDef *huart,
1018                                                      UART_AutonomousModeConfTypeDef *sConfig)
1019 {
1020   uint32_t tmpreg;
1021 
1022   /* Read AUTOCR register */
1023   tmpreg = READ_REG(huart->Instance->AUTOCR);
1024 
1025   /* Fill Autonomous structure parameter */
1026   sConfig->AutonomousModeState = (tmpreg & USART_AUTOCR_TRIGEN);
1027   sConfig->TriggerSelection = ((tmpreg & USART_AUTOCR_TRIGSEL) >> USART_AUTOCR_TRIGSEL_Pos);
1028   sConfig->TriggerPolarity = (tmpreg & USART_AUTOCR_TRIGPOL);
1029   sConfig->IdleFrame = (tmpreg & USART_AUTOCR_IDLEDIS);
1030   sConfig->DataSize = (tmpreg & USART_AUTOCR_TDN);
1031 
1032   return HAL_OK;
1033 }
1034 
1035 /**
1036   * @brief Clear autonomous mode Configuration.
1037   * @param huart  UART handle.
1038   * @retval HAL status
1039   */
HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef * huart)1040 HAL_StatusTypeDef HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef *huart)
1041 {
1042   if (huart->gState == HAL_UART_STATE_READY)
1043   {
1044     /* Process Locked */
1045     __HAL_LOCK(huart);
1046 
1047     huart->gState = HAL_UART_STATE_BUSY;
1048 
1049     /* Disable UART */
1050     __HAL_UART_DISABLE(huart);
1051 
1052     /* Clear AUTOCR register */
1053     CLEAR_REG(huart->Instance->AUTOCR);
1054 
1055     /* Enable UART */
1056     __HAL_UART_ENABLE(huart);
1057 
1058     huart->gState = HAL_UART_STATE_READY;
1059 
1060     /* Process Unlocked */
1061     __HAL_UNLOCK(huart);
1062 
1063     return HAL_OK;
1064   }
1065   else
1066   {
1067     return HAL_BUSY;
1068   }
1069 }
1070 /**
1071   * @}
1072   */
1073 
1074 /**
1075   * @}
1076   */
1077 
1078 /** @addtogroup UARTEx_Private_Functions
1079   * @{
1080   */
1081 
1082 /**
1083   * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
1084   * @param huart           UART handle.
1085   * @param WakeUpSelection UART wake up from stop mode parameters.
1086   * @retval None
1087   */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)1088 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
1089 {
1090   assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
1091 
1092   /* Set the USART address length */
1093   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
1094 
1095   /* Set the USART address node */
1096   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
1097 }
1098 
1099 /**
1100   * @brief Calculate the number of data to process in RX/TX ISR.
1101   * @note The RX FIFO depth and the TX FIFO depth is extracted from
1102   *       the UART configuration registers.
1103   * @param huart UART handle.
1104   * @retval None
1105   */
UARTEx_SetNbDataToProcess(UART_HandleTypeDef * huart)1106 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
1107 {
1108   uint8_t rx_fifo_depth;
1109   uint8_t tx_fifo_depth;
1110   uint8_t rx_fifo_threshold;
1111   uint8_t tx_fifo_threshold;
1112   static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
1113   static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
1114 
1115   if (huart->FifoMode == UART_FIFOMODE_DISABLE)
1116   {
1117     huart->NbTxDataToProcess = 1U;
1118     huart->NbRxDataToProcess = 1U;
1119   }
1120   else
1121   {
1122     rx_fifo_depth = RX_FIFO_DEPTH;
1123     tx_fifo_depth = TX_FIFO_DEPTH;
1124     rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
1125     tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
1126     huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
1127                                (uint16_t)denominator[tx_fifo_threshold];
1128     huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
1129                                (uint16_t)denominator[rx_fifo_threshold];
1130   }
1131 }
1132 /**
1133   * @}
1134   */
1135 
1136 #endif /* HAL_UART_MODULE_ENABLED */
1137 
1138 /**
1139   * @}
1140   */
1141 
1142 /**
1143   * @}
1144   */
1145 
1146