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 component is licensed by ST under BSD 3-Clause license,
19 * the "License"; You may not use this file except in compliance with the
20 * License. You may obtain a copy of the License at:
21 * opensource.org/licenses/BSD-3-Clause
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### UART peripheral extended features #####
27 ==============================================================================
28
29 (#) Declare a UART_HandleTypeDef handle structure.
30
31 (#) For the UART RS485 Driver Enable mode, initialize the UART registers
32 by calling the HAL_RS485Ex_Init() API.
33
34 (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
35
36 -@- When UART operates in FIFO mode, FIFO mode must be enabled prior
37 starting RX/TX transfers. Also RX/TX FIFO thresholds must be
38 configured prior starting RX/TX transfers.
39
40 @endverbatim
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 __HAL_LOCK(huart);
707
708 huart->ErrorCode = HAL_UART_ERROR_NONE;
709 huart->RxState = HAL_UART_STATE_BUSY_RX;
710 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
711
712 /* Init tickstart for timeout management */
713 tickstart = HAL_GetTick();
714
715 huart->RxXferSize = Size;
716 huart->RxXferCount = Size;
717
718 /* Computation of UART mask to apply to RDR register */
719 UART_MASK_COMPUTATION(huart);
720 uhMask = huart->Mask;
721
722 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
723 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
724 {
725 pdata8bits = NULL;
726 pdata16bits = (uint16_t *) pData;
727 }
728 else
729 {
730 pdata8bits = pData;
731 pdata16bits = NULL;
732 }
733
734 __HAL_UNLOCK(huart);
735
736 /* Initialize output number of received elements */
737 *RxLen = 0U;
738
739 /* as long as data have to be received */
740 while (huart->RxXferCount > 0U)
741 {
742 /* Check if IDLE flag is set */
743 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
744 {
745 /* Clear IDLE flag in ISR */
746 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
747
748 /* If Set, but no data ever received, clear flag without exiting loop */
749 /* If Set, and data has already been received, this means Idle Event is valid : End reception */
750 if (*RxLen > 0U)
751 {
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;
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 __HAL_LOCK(huart);
828
829 /* Set Reception type to reception till IDLE Event*/
830 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
831
832 status = UART_Start_Receive_IT(huart, pData, Size);
833
834 /* Check Rx process has been successfully started */
835 if (status == HAL_OK)
836 {
837 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
838 {
839 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
840 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
841 }
842 else
843 {
844 /* In case of errors already pending when reception is started,
845 Interrupts may have already been raised and lead to reception abortion.
846 (Overrun error for instance).
847 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
848 status = HAL_ERROR;
849 }
850 }
851
852 return status;
853 }
854 else
855 {
856 return HAL_BUSY;
857 }
858 }
859
860 /**
861 * @brief Receive an amount of data in DMA mode till either the expected number
862 * of data is received or an IDLE event occurs.
863 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
864 * to DMA services, transferring automatically received data elements in user reception buffer and
865 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
866 * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
867 * @note When the UART parity is enabled (PCE = 1), the received data contain
868 * the parity bit (MSB position).
869 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
870 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
871 * of uint16_t available through pData.
872 * @param huart UART handle.
873 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
874 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
875 * @retval HAL status
876 */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)877 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
878 {
879 HAL_StatusTypeDef status;
880
881 /* Check that a Rx process is not already ongoing */
882 if (huart->RxState == HAL_UART_STATE_READY)
883 {
884 if ((pData == NULL) || (Size == 0U))
885 {
886 return HAL_ERROR;
887 }
888
889 __HAL_LOCK(huart);
890
891 /* Set Reception type to reception till IDLE Event*/
892 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
893
894 status = UART_Start_Receive_DMA(huart, pData, Size);
895
896 /* Check Rx process has been successfully started */
897 if (status == HAL_OK)
898 {
899 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
900 {
901 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
902 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
903 }
904 else
905 {
906 /* In case of errors already pending when reception is started,
907 Interrupts may have already been raised and lead to reception abortion.
908 (Overrun error for instance).
909 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
910 status = HAL_ERROR;
911 }
912 }
913
914 return status;
915 }
916 else
917 {
918 return HAL_BUSY;
919 }
920 }
921
922 /**
923 * @brief Set autonomous mode Configuration.
924 * @param huart UART handle.
925 * @param sConfig Autonomous mode structure parameters.
926 * @retval HAL status
927 */
HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef * huart,UART_AutonomousModeConfTypeDef * sConfig)928 HAL_StatusTypeDef HAL_UARTEx_SetConfigAutonomousMode(UART_HandleTypeDef *huart, UART_AutonomousModeConfTypeDef *sConfig)
929 {
930 uint32_t tmpreg;
931
932 if (huart->gState == HAL_UART_STATE_READY)
933 {
934 /* Check the parameters */
935 assert_param(IS_UART_TRIGGER_POLARITY(sConfig->TriggerPolarity));
936 assert_param(IS_UART_IDLE_FRAME_TRANSMIT(sConfig->IdleFrame));
937 assert_param(IS_UART_TX_DATA_SIZE(sConfig->DataSize));
938 if (IS_LPUART_INSTANCE(huart->Instance))
939 {
940 assert_param(IS_LPUART_TRIGGER_SELECTION(sConfig->TriggerSelection));
941 }
942 else
943 {
944 assert_param(IS_UART_TRIGGER_SELECTION(sConfig->TriggerSelection));
945 }
946
947 /* Process Locked */
948 __HAL_LOCK(huart);
949
950 huart->gState = HAL_UART_STATE_BUSY;
951
952 /* Disable UART */
953 __HAL_UART_DISABLE(huart);
954
955 /* Disable Transmitter */
956 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TE);
957
958 /* Clear AUTOCR register */
959 CLEAR_REG(huart->Instance->AUTOCR);
960
961 /* UART AUTOCR Configuration */
962 tmpreg = ((sConfig->DataSize << USART_AUTOCR_TDN_Pos) | (sConfig->TriggerPolarity) | \
963 (sConfig->AutonomousModeState) | (sConfig->IdleFrame) | \
964 (sConfig->TriggerSelection << USART_AUTOCR_TRIGSEL_Pos));
965
966 WRITE_REG(huart->Instance->AUTOCR, tmpreg);
967
968 /* Enable UART */
969 __HAL_UART_ENABLE(huart);
970
971 huart->gState = HAL_UART_STATE_READY;
972
973 /* Process Unlocked */
974 __HAL_UNLOCK(huart);
975
976 return HAL_OK;
977 }
978 else
979 {
980 return HAL_BUSY;
981 }
982 }
983
984 /**
985 * @brief Get autonomous mode Configuration.
986 * @param huart UART handle.
987 * @param sConfig Autonomous mode structure parameters.
988 * @retval HAL status
989 */
HAL_UARTEx_GetConfigAutonomousMode(UART_HandleTypeDef * huart,UART_AutonomousModeConfTypeDef * sConfig)990 HAL_StatusTypeDef HAL_UARTEx_GetConfigAutonomousMode(UART_HandleTypeDef *huart, UART_AutonomousModeConfTypeDef *sConfig)
991 {
992 uint32_t tmpreg;
993
994 /* Read AUTOCR register */
995 tmpreg = READ_REG(huart->Instance->AUTOCR);
996
997 /* Fill Autonomous structure parameter */
998 sConfig->AutonomousModeState = (tmpreg & USART_AUTOCR_TRIGEN);
999 sConfig->TriggerSelection = ((tmpreg & USART_AUTOCR_TRIGSEL) >> USART_AUTOCR_TRIGSEL_Pos);
1000 sConfig->TriggerPolarity = (tmpreg & USART_AUTOCR_TRIGPOL);
1001 sConfig->IdleFrame = (tmpreg & USART_AUTOCR_IDLEDIS);
1002 sConfig->DataSize = (tmpreg & USART_AUTOCR_TDN);
1003
1004 return HAL_OK;
1005 }
1006
1007 /**
1008 * @brief Clear autonomous mode Configuration.
1009 * @param huart UART handle.
1010 * @retval HAL status
1011 */
HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef * huart)1012 HAL_StatusTypeDef HAL_UARTEx_ClearConfigAutonomousMode(UART_HandleTypeDef *huart)
1013 {
1014 if (huart->gState == HAL_UART_STATE_READY)
1015 {
1016 /* Process Locked */
1017 __HAL_LOCK(huart);
1018
1019 huart->gState = HAL_UART_STATE_BUSY;
1020
1021 /* Disable UART */
1022 __HAL_UART_DISABLE(huart);
1023
1024 /* Clear AUTOCR register */
1025 CLEAR_REG(huart->Instance->AUTOCR);
1026
1027 /* Enable UART */
1028 __HAL_UART_ENABLE(huart);
1029
1030 huart->gState = HAL_UART_STATE_READY;
1031
1032 /* Process Unlocked */
1033 __HAL_UNLOCK(huart);
1034
1035 return HAL_OK;
1036 }
1037 else
1038 {
1039 return HAL_BUSY;
1040 }
1041 }
1042 /**
1043 * @}
1044 */
1045
1046 /**
1047 * @}
1048 */
1049
1050 /** @addtogroup UARTEx_Private_Functions
1051 * @{
1052 */
1053
1054 /**
1055 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
1056 * @param huart UART handle.
1057 * @param WakeUpSelection UART wake up from stop mode parameters.
1058 * @retval None
1059 */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)1060 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
1061 {
1062 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
1063
1064 /* Set the USART address length */
1065 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
1066
1067 /* Set the USART address node */
1068 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
1069 }
1070
1071 /**
1072 * @brief Calculate the number of data to process in RX/TX ISR.
1073 * @note The RX FIFO depth and the TX FIFO depth is extracted from
1074 * the UART configuration registers.
1075 * @param huart UART handle.
1076 * @retval None
1077 */
UARTEx_SetNbDataToProcess(UART_HandleTypeDef * huart)1078 static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
1079 {
1080 uint8_t rx_fifo_depth;
1081 uint8_t tx_fifo_depth;
1082 uint8_t rx_fifo_threshold;
1083 uint8_t tx_fifo_threshold;
1084 static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
1085 static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
1086
1087 if (huart->FifoMode == UART_FIFOMODE_DISABLE)
1088 {
1089 huart->NbTxDataToProcess = 1U;
1090 huart->NbRxDataToProcess = 1U;
1091 }
1092 else
1093 {
1094 rx_fifo_depth = RX_FIFO_DEPTH;
1095 tx_fifo_depth = TX_FIFO_DEPTH;
1096 rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
1097 tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
1098 huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
1099 (uint16_t)denominator[tx_fifo_threshold];
1100 huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
1101 (uint16_t)denominator[rx_fifo_threshold];
1102 }
1103 }
1104 /**
1105 * @}
1106 */
1107
1108 #endif /* HAL_UART_MODULE_ENABLED */
1109
1110 /**
1111 * @}
1112 */
1113
1114 /**
1115 * @}
1116 */
1117