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