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