1 /**
2 ******************************************************************************
3 * @file stm32f7xx_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) 2017 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 @endverbatim
34 ******************************************************************************
35 */
36
37 /* Includes ------------------------------------------------------------------*/
38 #include "stm32f7xx_hal.h"
39
40 /** @addtogroup STM32F7xx_HAL_Driver
41 * @{
42 */
43
44 /** @defgroup UARTEx UARTEx
45 * @brief UART Extended HAL module driver
46 * @{
47 */
48
49 #ifdef HAL_UART_MODULE_ENABLED
50
51 /* Private typedef -----------------------------------------------------------*/
52 /* Private define ------------------------------------------------------------*/
53
54 /* Private macros ------------------------------------------------------------*/
55 /* Private variables ---------------------------------------------------------*/
56 /* Private function prototypes -----------------------------------------------*/
57 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
58 * @{
59 */
60 #if defined(USART_CR1_UESM)
61 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
62 #endif /* USART_CR1_UESM */
63 /**
64 * @}
65 */
66
67 /* Exported functions --------------------------------------------------------*/
68
69 /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions
70 * @{
71 */
72
73 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
74 * @brief Extended Initialization and Configuration Functions
75 *
76 @verbatim
77 ===============================================================================
78 ##### Initialization and Configuration functions #####
79 ===============================================================================
80 [..]
81 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
82 in asynchronous mode.
83 (+) For the asynchronous mode the parameters below can be configured:
84 (++) Baud Rate
85 (++) Word Length
86 (++) Stop Bit
87 (++) Parity: If the parity is enabled, then the MSB bit of the data written
88 in the data register is transmitted but is changed by the parity bit.
89 (++) Hardware flow control
90 (++) Receiver/transmitter modes
91 (++) Over Sampling Method
92 (++) One-Bit Sampling Method
93 (+) For the asynchronous mode, the following advanced features can be configured as well:
94 (++) TX and/or RX pin level inversion
95 (++) data logical level inversion
96 (++) RX and TX pins swap
97 (++) RX overrun detection disabling
98 (++) DMA disabling on RX error
99 (++) MSB first on communication line
100 (++) auto Baud rate detection
101 [..]
102 The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
103 procedures (details for the procedures are available in reference manual).
104
105 @endverbatim
106
107 Depending on the frame length defined by the M1 and M0 bits (7-bit,
108 8-bit or 9-bit), the possible UART formats are listed in the
109 following table.
110
111 Table 1. UART frame format.
112 +-----------------------------------------------------------------------+
113 | M1 bit | M0 bit | PCE bit | UART frame |
114 |---------|---------|-----------|---------------------------------------|
115 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
116 |---------|---------|-----------|---------------------------------------|
117 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
118 |---------|---------|-----------|---------------------------------------|
119 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
120 |---------|---------|-----------|---------------------------------------|
121 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
122 |---------|---------|-----------|---------------------------------------|
123 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
124 |---------|---------|-----------|---------------------------------------|
125 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
126 +-----------------------------------------------------------------------+
127
128 * @{
129 */
130
131 /**
132 * @brief Initialize the RS485 Driver enable feature according to the specified
133 * parameters in the UART_InitTypeDef and creates the associated handle.
134 * @param huart UART handle.
135 * @param Polarity Select the driver enable polarity.
136 * This parameter can be one of the following values:
137 * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
138 * @arg @ref UART_DE_POLARITY_LOW DE signal is active low
139 * @param AssertionTime Driver Enable assertion time:
140 * 5-bit value defining the time between the activation of the DE (Driver Enable)
141 * signal and the beginning of the start bit. It is expressed in sample time
142 * units (1/8 or 1/16 bit time, depending on the oversampling rate)
143 * @param DeassertionTime Driver Enable deassertion time:
144 * 5-bit value defining the time between the end of the last stop bit, in a
145 * transmitted message, and the de-activation of the DE (Driver Enable) signal.
146 * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
147 * oversampling rate).
148 * @retval HAL status
149 */
HAL_RS485Ex_Init(UART_HandleTypeDef * huart,uint32_t Polarity,uint32_t AssertionTime,uint32_t DeassertionTime)150 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime,
151 uint32_t DeassertionTime)
152 {
153 uint32_t temp;
154
155 /* Check the UART handle allocation */
156 if (huart == NULL)
157 {
158 return HAL_ERROR;
159 }
160 /* Check the Driver Enable UART instance */
161 assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
162
163 /* Check the Driver Enable polarity */
164 assert_param(IS_UART_DE_POLARITY(Polarity));
165
166 /* Check the Driver Enable assertion time */
167 assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
168
169 /* Check the Driver Enable deassertion time */
170 assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
171
172 if (huart->gState == HAL_UART_STATE_RESET)
173 {
174 /* Allocate lock resource and initialize it */
175 huart->Lock = HAL_UNLOCKED;
176
177 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
178 UART_InitCallbacksToDefault(huart);
179
180 if (huart->MspInitCallback == NULL)
181 {
182 huart->MspInitCallback = HAL_UART_MspInit;
183 }
184
185 /* Init the low level hardware */
186 huart->MspInitCallback(huart);
187 #else
188 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
189 HAL_UART_MspInit(huart);
190 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
191 }
192
193 huart->gState = HAL_UART_STATE_BUSY;
194
195 /* Disable the Peripheral */
196 __HAL_UART_DISABLE(huart);
197
198 /* Perform advanced settings configuration */
199 /* For some items, configuration requires to be done prior TE and RE bits are set */
200 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
201 {
202 UART_AdvFeatureConfig(huart);
203 }
204
205 /* Set the UART Communication parameters */
206 if (UART_SetConfig(huart) == HAL_ERROR)
207 {
208 return HAL_ERROR;
209 }
210
211 /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
212 SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
213
214 /* Set the Driver Enable polarity */
215 MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
216
217 /* Set the Driver Enable assertion and deassertion times */
218 temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
219 temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
220 MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
221
222 /* Enable the Peripheral */
223 __HAL_UART_ENABLE(huart);
224
225 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
226 return (UART_CheckIdleState(huart));
227 }
228
229 /**
230 * @}
231 */
232
233
234 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
235 * @brief Extended Peripheral Control functions
236 *
237 @verbatim
238 ===============================================================================
239 ##### Peripheral Control functions #####
240 ===============================================================================
241 [..] This section provides the following functions:
242 (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
243 (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
244 (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
245 detection length to more than 4 bits for multiprocessor address mark wake up.
246 #if defined(USART_CR1_UESM)
247 (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
248 trigger: address match, Start Bit detection or RXNE bit status.
249 (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
250 (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
251 #endif
252
253 [..] This subsection also provides a set of additional functions providing enhanced reception
254 services to user. (For example, these functions allow application to handle use cases
255 where number of data to be received is unknown).
256
257 (#) Compared to standard reception services which only consider number of received
258 data elements as reception completion criteria, these functions also consider additional events
259 as triggers for updating reception status to caller :
260 (+) Detection of inactivity period (RX line has not been active for a given period).
261 (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
262 for 1 frame time, after last received byte.
263 (++) RX inactivity detected by RTO, i.e. line has been in idle state
264 for a programmable time, after last received byte.
265 (+) Detection that a specific character has been received.
266
267 (#) There are two mode of transfer:
268 (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
269 or till IDLE event occurs. Reception is handled only during function execution.
270 When function exits, no data reception could occur. HAL status and number of actually received data elements,
271 are returned by function after finishing transfer.
272 (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
273 These API's return the HAL status.
274 The end of the data processing will be indicated through the
275 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
276 The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
277 The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
278
279 (#) Blocking mode API:
280 (+) HAL_UARTEx_ReceiveToIdle()
281
282 (#) Non-Blocking mode API with Interrupt:
283 (+) HAL_UARTEx_ReceiveToIdle_IT()
284
285 (#) Non-Blocking mode API with DMA:
286 (+) HAL_UARTEx_ReceiveToIdle_DMA()
287
288 @endverbatim
289 * @{
290 */
291
292 #if defined(USART_CR3_UCESM)
293 /**
294 * @brief Keep UART Clock enabled when in Stop Mode.
295 * @note When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled
296 * this clock during STOP mode by setting the UCESM bit in USART_CR3 control register.
297 * @note When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source,
298 * and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set.
299 * @param huart UART handle.
300 * @retval HAL status
301 */
HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef * huart)302 HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart)
303 {
304 /* Process Locked */
305 __HAL_LOCK(huart);
306
307 /* Set UCESM bit */
308 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_UCESM);
309
310 /* Process Unlocked */
311 __HAL_UNLOCK(huart);
312
313 return HAL_OK;
314 }
315
316 /**
317 * @brief Disable UART Clock when in Stop Mode.
318 * @param huart UART handle.
319 * @retval HAL status
320 */
HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef * huart)321 HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart)
322 {
323 /* Process Locked */
324 __HAL_LOCK(huart);
325
326 /* Clear UCESM bit */
327 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM);
328
329 /* Process Unlocked */
330 __HAL_UNLOCK(huart);
331
332 return HAL_OK;
333 }
334
335 #endif /* USART_CR3_UCESM */
336 /**
337 * @brief By default in multiprocessor mode, when the wake up method is set
338 * to address mark, the UART handles only 4-bit long addresses detection;
339 * this API allows to enable longer addresses detection (6-, 7- or 8-bit
340 * long).
341 * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
342 * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
343 * @param huart UART handle.
344 * @param AddressLength This parameter can be one of the following values:
345 * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
346 * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
347 * @retval HAL status
348 */
HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef * huart,uint32_t AddressLength)349 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
350 {
351 /* Check the UART handle allocation */
352 if (huart == NULL)
353 {
354 return HAL_ERROR;
355 }
356
357 /* Check the address length parameter */
358 assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
359
360 huart->gState = HAL_UART_STATE_BUSY;
361
362 /* Disable the Peripheral */
363 __HAL_UART_DISABLE(huart);
364
365 /* Set the address length */
366 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
367
368 /* Enable the Peripheral */
369 __HAL_UART_ENABLE(huart);
370
371 /* TEACK and/or REACK to check before moving huart->gState to Ready */
372 return (UART_CheckIdleState(huart));
373 }
374
375 #if defined(USART_CR1_UESM)
376 /**
377 * @brief Set Wakeup from Stop mode interrupt flag selection.
378 * @note It is the application responsibility to enable the interrupt used as
379 * usart_wkup interrupt source before entering low-power mode.
380 * @param huart UART handle.
381 * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
382 * This parameter can be one of the following values:
383 * @arg @ref UART_WAKEUP_ON_ADDRESS
384 * @arg @ref UART_WAKEUP_ON_STARTBIT
385 * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
386 * @retval HAL status
387 */
HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)388 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
389 {
390 HAL_StatusTypeDef status = HAL_OK;
391 uint32_t tickstart;
392
393 /* check the wake-up from stop mode UART instance */
394 assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
395 /* check the wake-up selection parameter */
396 assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
397
398 /* Process Locked */
399 __HAL_LOCK(huart);
400
401 huart->gState = HAL_UART_STATE_BUSY;
402
403 /* Disable the Peripheral */
404 __HAL_UART_DISABLE(huart);
405
406 #if defined(USART_CR3_WUS)
407 /* Set the wake-up selection scheme */
408 MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
409 #endif /* USART_CR3_WUS */
410
411 if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
412 {
413 UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
414 }
415
416 /* Enable the Peripheral */
417 __HAL_UART_ENABLE(huart);
418
419 /* Init tickstart for timeout management */
420 tickstart = HAL_GetTick();
421
422 /* Wait until REACK flag is set */
423 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
424 {
425 status = HAL_TIMEOUT;
426 }
427 else
428 {
429 /* Initialize the UART State */
430 huart->gState = HAL_UART_STATE_READY;
431 }
432
433 /* Process Unlocked */
434 __HAL_UNLOCK(huart);
435
436 return status;
437 }
438
439 /**
440 * @brief Enable UART Stop Mode.
441 * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
442 * @param huart UART handle.
443 * @retval HAL status
444 */
HAL_UARTEx_EnableStopMode(UART_HandleTypeDef * huart)445 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
446 {
447 /* Process Locked */
448 __HAL_LOCK(huart);
449
450 /* Set UESM bit */
451 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
452
453 /* Process Unlocked */
454 __HAL_UNLOCK(huart);
455
456 return HAL_OK;
457 }
458
459 /**
460 * @brief Disable UART Stop Mode.
461 * @param huart UART handle.
462 * @retval HAL status
463 */
HAL_UARTEx_DisableStopMode(UART_HandleTypeDef * huart)464 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
465 {
466 /* Process Locked */
467 __HAL_LOCK(huart);
468
469 /* Clear UESM bit */
470 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
471
472 /* Process Unlocked */
473 __HAL_UNLOCK(huart);
474
475 return HAL_OK;
476 }
477
478 #endif /* USART_CR1_UESM */
479 /**
480 * @brief Receive an amount of data in blocking mode till either the expected number of data
481 * is received or an IDLE event occurs.
482 * @note HAL_OK is returned if reception is completed (expected number of data has been received)
483 * or if reception is stopped after IDLE event (less than the expected number of data has been received)
484 * In this case, RxLen output parameter indicates number of data available in reception buffer.
485 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
486 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
487 * of uint16_t available through pData.
488 * @param huart UART handle.
489 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
490 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
491 * @param RxLen Number of data elements finally received
492 * (could be lower than Size, in case reception ends on IDLE event)
493 * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
494 * @retval HAL status
495 */
HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint16_t * RxLen,uint32_t Timeout)496 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
497 uint32_t Timeout)
498 {
499 uint8_t *pdata8bits;
500 uint16_t *pdata16bits;
501 uint16_t uhMask;
502 uint32_t tickstart;
503
504 /* Check that a Rx process is not already ongoing */
505 if (huart->RxState == HAL_UART_STATE_READY)
506 {
507 if ((pData == NULL) || (Size == 0U))
508 {
509 return HAL_ERROR;
510 }
511
512 huart->ErrorCode = HAL_UART_ERROR_NONE;
513 huart->RxState = HAL_UART_STATE_BUSY_RX;
514 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
515 huart->RxEventType = HAL_UART_RXEVENT_TC;
516
517 /* Init tickstart for timeout management */
518 tickstart = HAL_GetTick();
519
520 huart->RxXferSize = Size;
521 huart->RxXferCount = Size;
522
523 /* Computation of UART mask to apply to RDR register */
524 UART_MASK_COMPUTATION(huart);
525 uhMask = huart->Mask;
526
527 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
528 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
529 {
530 pdata8bits = NULL;
531 pdata16bits = (uint16_t *) pData;
532 }
533 else
534 {
535 pdata8bits = pData;
536 pdata16bits = NULL;
537 }
538
539 /* Initialize output number of received elements */
540 *RxLen = 0U;
541
542 /* as long as data have to be received */
543 while (huart->RxXferCount > 0U)
544 {
545 /* Check if IDLE flag is set */
546 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
547 {
548 /* Clear IDLE flag in ISR */
549 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
550
551 /* If Set, but no data ever received, clear flag without exiting loop */
552 /* If Set, and data has already been received, this means Idle Event is valid : End reception */
553 if (*RxLen > 0U)
554 {
555 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
556 huart->RxState = HAL_UART_STATE_READY;
557
558 return HAL_OK;
559 }
560 }
561
562 /* Check if RXNE flag is set */
563 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
564 {
565 if (pdata8bits == NULL)
566 {
567 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
568 pdata16bits++;
569 }
570 else
571 {
572 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
573 pdata8bits++;
574 }
575 /* Increment number of received elements */
576 *RxLen += 1U;
577 huart->RxXferCount--;
578 }
579
580 /* Check for the Timeout */
581 if (Timeout != HAL_MAX_DELAY)
582 {
583 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
584 {
585 huart->RxState = HAL_UART_STATE_READY;
586
587 return HAL_TIMEOUT;
588 }
589 }
590 }
591
592 /* Set number of received elements in output parameter : RxLen */
593 *RxLen = huart->RxXferSize - huart->RxXferCount;
594 /* At end of Rx process, restore huart->RxState to Ready */
595 huart->RxState = HAL_UART_STATE_READY;
596
597 return HAL_OK;
598 }
599 else
600 {
601 return HAL_BUSY;
602 }
603 }
604
605 /**
606 * @brief Receive an amount of data in interrupt mode till either the expected number of data
607 * is received or an IDLE event occurs.
608 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
609 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
610 * number of received data elements.
611 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
612 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
613 * of uint16_t available through pData.
614 * @param huart UART handle.
615 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
616 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
617 * @retval HAL status
618 */
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)619 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
620 {
621 HAL_StatusTypeDef status = HAL_OK;
622
623 /* Check that a Rx process is not already ongoing */
624 if (huart->RxState == HAL_UART_STATE_READY)
625 {
626 if ((pData == NULL) || (Size == 0U))
627 {
628 return HAL_ERROR;
629 }
630
631 /* Set Reception type to reception till IDLE Event*/
632 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
633 huart->RxEventType = HAL_UART_RXEVENT_TC;
634
635 (void)UART_Start_Receive_IT(huart, pData, Size);
636
637 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
638 {
639 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
640 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
641 }
642 else
643 {
644 /* In case of errors already pending when reception is started,
645 Interrupts may have already been raised and lead to reception abortion.
646 (Overrun error for instance).
647 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
648 status = HAL_ERROR;
649 }
650
651 return status;
652 }
653 else
654 {
655 return HAL_BUSY;
656 }
657 }
658
659 /**
660 * @brief Receive an amount of data in DMA mode till either the expected number
661 * of data is received or an IDLE event occurs.
662 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
663 * to DMA services, transferring automatically received data elements in user reception buffer and
664 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
665 * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
666 * @note When the UART parity is enabled (PCE = 1), the received data contain
667 * the parity bit (MSB position).
668 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
669 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
670 * of uint16_t available through pData.
671 * @param huart UART handle.
672 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
673 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
674 * @retval HAL status
675 */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)676 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
677 {
678 HAL_StatusTypeDef status;
679
680 /* Check that a Rx process is not already ongoing */
681 if (huart->RxState == HAL_UART_STATE_READY)
682 {
683 if ((pData == NULL) || (Size == 0U))
684 {
685 return HAL_ERROR;
686 }
687
688 /* Set Reception type to reception till IDLE Event*/
689 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
690 huart->RxEventType = HAL_UART_RXEVENT_TC;
691
692 status = UART_Start_Receive_DMA(huart, pData, Size);
693
694 /* Check Rx process has been successfully started */
695 if (status == HAL_OK)
696 {
697 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
698 {
699 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
700 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
701 }
702 else
703 {
704 /* In case of errors already pending when reception is started,
705 Interrupts may have already been raised and lead to reception abortion.
706 (Overrun error for instance).
707 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
708 status = HAL_ERROR;
709 }
710 }
711
712 return status;
713 }
714 else
715 {
716 return HAL_BUSY;
717 }
718 }
719
720 /**
721 * @brief Provide Rx Event type that has lead to RxEvent callback execution.
722 * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
723 * of reception process is provided to application through calls of Rx Event callback (either default one
724 * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
725 * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
726 * to Rx Event callback execution.
727 * @note This function is expected to be called within the user implementation of Rx Event Callback,
728 * in order to provide the accurate value :
729 * In Interrupt Mode :
730 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
731 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
732 * received data is lower than expected one)
733 * In DMA Mode :
734 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
735 * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
736 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
737 * received data is lower than expected one).
738 * In DMA mode, RxEvent callback could be called several times;
739 * When DMA is configured in Normal Mode, HT event does not stop Reception process;
740 * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
741 * @param huart UART handle.
742 * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
743 */
HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef * huart)744 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart)
745 {
746 /* Return Rx Event type value, as stored in UART handle */
747 return (huart->RxEventType);
748 }
749
750 /**
751 * @}
752 */
753
754 /**
755 * @}
756 */
757
758 /** @addtogroup UARTEx_Private_Functions
759 * @{
760 */
761 #if defined(USART_CR1_UESM)
762
763 /**
764 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
765 * @param huart UART handle.
766 * @param WakeUpSelection UART wake up from stop mode parameters.
767 * @retval None
768 */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)769 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
770 {
771 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
772
773 /* Set the USART address length */
774 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
775
776 /* Set the USART address node */
777 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
778 }
779 #endif /* USART_CR1_UESM */
780
781 /**
782 * @}
783 */
784
785 #endif /* HAL_UART_MODULE_ENABLED */
786
787 /**
788 * @}
789 */
790
791 /**
792 * @}
793 */
794
795