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 /* 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 /* Disable 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 #if defined(USART_DMAREQUESTS_SW_WA)
709 /* Disable the UART DMA Rx request if enabled */
710 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
711 {
712 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
713 }
714
715 #endif /* USART_DMAREQUESTS_SW_WA */
716 huart->ErrorCode = HAL_UART_ERROR_NONE;
717 huart->RxState = HAL_UART_STATE_BUSY_RX;
718 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
719 huart->RxEventType = HAL_UART_RXEVENT_TC;
720
721 /* Init tickstart for timeout management */
722 tickstart = HAL_GetTick();
723
724 huart->RxXferSize = Size;
725 huart->RxXferCount = Size;
726
727 /* Computation of UART mask to apply to RDR register */
728 UART_MASK_COMPUTATION(huart);
729 uhMask = huart->Mask;
730
731 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
732 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
733 {
734 pdata8bits = NULL;
735 pdata16bits = (uint16_t *) pData;
736 }
737 else
738 {
739 pdata8bits = pData;
740 pdata16bits = NULL;
741 }
742
743 /* Initialize output number of received elements */
744 *RxLen = 0U;
745
746 /* as long as data have to be received */
747 while (huart->RxXferCount > 0U)
748 {
749 /* Check if IDLE flag is set */
750 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
751 {
752 /* Clear IDLE flag in ISR */
753 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
754
755 /* If Set, but no data ever received, clear flag without exiting loop */
756 /* If Set, and data has already been received, this means Idle Event is valid : End reception */
757 if (*RxLen > 0U)
758 {
759 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
760 huart->RxState = HAL_UART_STATE_READY;
761
762 return HAL_OK;
763 }
764 }
765
766 /* Check if RXNE flag is set */
767 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
768 {
769 if (pdata8bits == NULL)
770 {
771 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
772 pdata16bits++;
773 }
774 else
775 {
776 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
777 pdata8bits++;
778 }
779 /* Increment number of received elements */
780 *RxLen += 1U;
781 huart->RxXferCount--;
782 }
783
784 /* Check for the Timeout */
785 if (Timeout != HAL_MAX_DELAY)
786 {
787 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
788 {
789 huart->RxState = HAL_UART_STATE_READY;
790
791 return HAL_TIMEOUT;
792 }
793 }
794 }
795
796 /* Set number of received elements in output parameter : RxLen */
797 *RxLen = huart->RxXferSize - huart->RxXferCount;
798 /* At end of Rx process, restore huart->RxState to Ready */
799 huart->RxState = HAL_UART_STATE_READY;
800
801 return HAL_OK;
802 }
803 else
804 {
805 return HAL_BUSY;
806 }
807 }
808
809 /**
810 * @brief Receive an amount of data in interrupt mode till either the expected number of data
811 * is received or an IDLE event occurs.
812 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
813 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
814 * number of received data elements.
815 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
816 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
817 * of uint16_t available through pData.
818 * @param huart UART handle.
819 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
820 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
821 * @retval HAL status
822 */
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)823 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
824 {
825 HAL_StatusTypeDef status = HAL_OK;
826
827 /* Check that a Rx process is not already ongoing */
828 if (huart->RxState == HAL_UART_STATE_READY)
829 {
830 if ((pData == NULL) || (Size == 0U))
831 {
832 return HAL_ERROR;
833 }
834
835 #if defined(USART_DMAREQUESTS_SW_WA)
836 /* Disable the UART DMA Rx request if enabled */
837 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
838 {
839 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
840 }
841
842 #endif /* USART_DMAREQUESTS_SW_WA */
843 /* Set Reception type to reception till IDLE Event*/
844 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
845 huart->RxEventType = HAL_UART_RXEVENT_TC;
846
847 (void)UART_Start_Receive_IT(huart, pData, Size);
848
849 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
850 {
851 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
852 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
853 }
854 else
855 {
856 /* In case of errors already pending when reception is started,
857 Interrupts may have already been raised and lead to reception abortion.
858 (Overrun error for instance).
859 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
860 status = HAL_ERROR;
861 }
862
863 return status;
864 }
865 else
866 {
867 return HAL_BUSY;
868 }
869 }
870
871 #if defined(HAL_DMA_MODULE_ENABLED)
872 /**
873 * @brief Receive an amount of data in DMA mode till either the expected number
874 * of data is received or an IDLE event occurs.
875 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
876 * to DMA services, transferring automatically received data elements in user reception buffer and
877 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
878 * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
879 * @note When the UART parity is enabled (PCE = 1), the received data contain
880 * the parity bit (MSB position).
881 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
882 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
883 * of uint16_t available through pData.
884 * @param huart UART handle.
885 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
886 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
887 * @retval HAL status
888 */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)889 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
890 {
891 HAL_StatusTypeDef status;
892
893 /* Check that a Rx process is not already ongoing */
894 if (huart->RxState == HAL_UART_STATE_READY)
895 {
896 if ((pData == NULL) || (Size == 0U))
897 {
898 return HAL_ERROR;
899 }
900
901 /* Set Reception type to reception till IDLE Event*/
902 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
903 huart->RxEventType = HAL_UART_RXEVENT_TC;
904
905 status = UART_Start_Receive_DMA(huart, pData, Size);
906
907 /* Check Rx process has been successfully started */
908 if (status == HAL_OK)
909 {
910 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
911 {
912 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
913 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
914 }
915 else
916 {
917 /* In case of errors already pending when reception is started,
918 Interrupts may have already been raised and lead to reception abortion.
919 (Overrun error for instance).
920 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
921 status = HAL_ERROR;
922 }
923 }
924
925 return status;
926 }
927 else
928 {
929 return HAL_BUSY;
930 }
931 }
932 #endif /* HAL_DMA_MODULE_ENABLED */
933
934 /**
935 * @brief Provide Rx Event type that has lead to RxEvent callback execution.
936 * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
937 * of reception process is provided to application through calls of Rx Event callback (either default one
938 * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
939 * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
940 * to Rx Event callback execution.
941 * @note This function is expected to be called within the user implementation of Rx Event Callback,
942 * in order to provide the accurate value :
943 * In Interrupt Mode :
944 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
945 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
946 * received data is lower than expected one)
947 * In DMA Mode :
948 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
949 * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
950 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
951 * received data is lower than expected one).
952 * In DMA mode, RxEvent callback could be called several times;
953 * When DMA is configured in Normal Mode, HT event does not stop Reception process;
954 * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
955 * @param huart UART handle.
956 * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
957 */
HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef * huart)958 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart)
959 {
960 /* Return Rx Event type value, as stored in UART handle */
961 return (huart->RxEventType);
962 }
963
964 /**
965 * @brief Set autonomous mode Configuration.
966 * @param huart UART handle.
967 * @param sConfig Autonomous mode structure parameters.
968 * @retval HAL status
969 */
HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef * huart,const UART_AutonomousModeConfTypeDef * sConfig)970 HAL_StatusTypeDef HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef *huart,
971 const UART_AutonomousModeConfTypeDef *sConfig)
972 {
973 uint32_t tmpreg;
974
975 if (huart->gState == HAL_UART_STATE_READY)
976 {
977 /* Check the parameters */
978 assert_param(IS_UART_TRIGGER_POLARITY(sConfig->TriggerPolarity));
979 assert_param(IS_UART_IDLE_FRAME_TRANSMIT(sConfig->IdleFrame));
980 assert_param(IS_UART_TX_DATA_SIZE(sConfig->DataSize));
981 if (IS_LPUART_INSTANCE(huart->Instance))
982 {
983 assert_param(IS_LPUART_TRIGGER_SELECTION(sConfig->TriggerSelection));
984 }
985 else
986 {
987 assert_param(IS_UART_TRIGGER_SELECTION(sConfig->TriggerSelection));
988 }
989
990 /* Process Locked */
991 __HAL_LOCK(huart);
992
993 huart->gState = HAL_UART_STATE_BUSY;
994
995 /* Disable UART */
996 __HAL_UART_DISABLE(huart);
997
998 /* Disable Transmitter */
999 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TE);
1000
1001 /* Clear AUTOCR register */
1002 CLEAR_REG(huart->Instance->AUTOCR);
1003
1004 /* UART AUTOCR Configuration */
1005 tmpreg = ((sConfig->DataSize << USART_AUTOCR_TDN_Pos) | (sConfig->TriggerPolarity) | \
1006 (sConfig->AutonomousModeState) | (sConfig->IdleFrame) | \
1007 (sConfig->TriggerSelection << USART_AUTOCR_TRIGSEL_Pos));
1008
1009 WRITE_REG(huart->Instance->AUTOCR, tmpreg);
1010
1011 /* Enable UART */
1012 __HAL_UART_ENABLE(huart);
1013
1014 huart->gState = HAL_UART_STATE_READY;
1015
1016 /* Process Unlocked */
1017 __HAL_UNLOCK(huart);
1018
1019 return HAL_OK;
1020 }
1021 else
1022 {
1023 return HAL_BUSY;
1024 }
1025 }
1026
1027 /**
1028 * @brief Get autonomous mode Configuration.
1029 * @param huart UART handle.
1030 * @param sConfig Autonomous mode structure parameters.
1031 * @retval HAL status
1032 */
HAL_UARTEx_GetConfigAutonomousMode(const UART_HandleTypeDef * huart,UART_AutonomousModeConfTypeDef * sConfig)1033 HAL_StatusTypeDef HAL_UARTEx_GetConfigAutonomousMode(const UART_HandleTypeDef *huart,
1034 UART_AutonomousModeConfTypeDef *sConfig)
1035 {
1036 uint32_t tmpreg;
1037
1038 /* Read AUTOCR register */
1039 tmpreg = READ_REG(huart->Instance->AUTOCR);
1040
1041 /* Fill Autonomous structure parameter */
1042 sConfig->AutonomousModeState = (tmpreg & USART_AUTOCR_TRIGEN);
1043 sConfig->TriggerSelection = ((tmpreg & USART_AUTOCR_TRIGSEL) >> USART_AUTOCR_TRIGSEL_Pos);
1044 sConfig->TriggerPolarity = (tmpreg & USART_AUTOCR_TRIGPOL);
1045 sConfig->IdleFrame = (tmpreg & USART_AUTOCR_IDLEDIS);
1046 sConfig->DataSize = (tmpreg & USART_AUTOCR_TDN);
1047
1048 return HAL_OK;
1049 }
1050
1051 /**
1052 * @brief Clear autonomous mode Configuration.
1053 * @param huart UART handle.
1054 * @retval HAL status
1055 */
HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef * huart)1056 HAL_StatusTypeDef HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef *huart)
1057 {
1058 if (huart->gState == HAL_UART_STATE_READY)
1059 {
1060 /* Process Locked */
1061 __HAL_LOCK(huart);
1062
1063 huart->gState = HAL_UART_STATE_BUSY;
1064
1065 /* Disable UART */
1066 __HAL_UART_DISABLE(huart);
1067
1068 /* Clear AUTOCR register */
1069 CLEAR_REG(huart->Instance->AUTOCR);
1070
1071 /* Enable UART */
1072 __HAL_UART_ENABLE(huart);
1073
1074 huart->gState = HAL_UART_STATE_READY;
1075
1076 /* Process Unlocked */
1077 __HAL_UNLOCK(huart);
1078
1079 return HAL_OK;
1080 }
1081 else
1082 {
1083 return HAL_BUSY;
1084 }
1085 }
1086 /**
1087 * @}
1088 */
1089
1090 /**
1091 * @}
1092 */
1093
1094 /** @addtogroup UARTEx_Private_Functions
1095 * @{
1096 */
1097
1098 /**
1099 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
1100 * @param huart UART handle.
1101 * @param WakeUpSelection UART wake up from stop mode parameters.
1102 * @retval None
1103 */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)1104 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
1105 {
1106 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
1107
1108 /* Set the USART address length */
1109 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
1110
1111 /* Set the USART address node */
1112 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
1113 }
1114
1115 /**
1116 * @brief Calculate the number of data to process in RX/TX ISR.
1117 * @note The RX FIFO depth and the TX FIFO depth is extracted from
1118 * the UART configuration registers.
1119 * @param huart UART handle.
1120 * @retval None
1121 */
UARTEx_SetNbDataToProcess(UART_HandleTypeDef * huart)1122 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
1123 {
1124 uint8_t rx_fifo_depth;
1125 uint8_t tx_fifo_depth;
1126 uint8_t rx_fifo_threshold;
1127 uint8_t tx_fifo_threshold;
1128 static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
1129 static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
1130
1131 if (huart->FifoMode == UART_FIFOMODE_DISABLE)
1132 {
1133 huart->NbTxDataToProcess = 1U;
1134 huart->NbRxDataToProcess = 1U;
1135 }
1136 else
1137 {
1138 rx_fifo_depth = RX_FIFO_DEPTH;
1139 tx_fifo_depth = TX_FIFO_DEPTH;
1140 rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
1141 tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
1142 huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
1143 (uint16_t)denominator[tx_fifo_threshold];
1144 huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
1145 (uint16_t)denominator[rx_fifo_threshold];
1146 }
1147 }
1148 /**
1149 * @}
1150 */
1151
1152 #endif /* HAL_UART_MODULE_ENABLED */
1153
1154 /**
1155 * @}
1156 */
1157
1158 /**
1159 * @}
1160 */
1161