1 /**
2 ******************************************************************************
3 * @file stm32f0xx_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 "stm32f0xx_hal.h"
39
40 /** @addtogroup STM32F0xx_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 /* Set the UART Communication parameters */
199 if (UART_SetConfig(huart) == HAL_ERROR)
200 {
201 return HAL_ERROR;
202 }
203
204 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
205 {
206 UART_AdvFeatureConfig(huart);
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 #if defined(USART_CR1_UESM)
241 #if defined(USART_CR3_WUFIE)
242 (#) Wakeup from Stop mode Callback:
243 (+) HAL_UARTEx_WakeupCallback()
244
245 #endif
246 #endif
247 @endverbatim
248 * @{
249 */
250
251 #if defined(USART_CR1_UESM)
252 #if defined(USART_CR3_WUFIE)
253 /**
254 * @brief UART wakeup from Stop mode callback.
255 * @param huart UART handle.
256 * @retval None
257 */
HAL_UARTEx_WakeupCallback(UART_HandleTypeDef * huart)258 __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
259 {
260 /* Prevent unused argument(s) compilation warning */
261 UNUSED(huart);
262
263 /* NOTE : This function should not be modified, when the callback is needed,
264 the HAL_UARTEx_WakeupCallback can be implemented in the user file.
265 */
266 }
267
268 #endif /* USART_CR3_WUFIE */
269 #endif /* USART_CR1_UESM */
270
271 /**
272 * @}
273 */
274
275 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
276 * @brief Extended Peripheral Control functions
277 *
278 @verbatim
279 ===============================================================================
280 ##### Peripheral Control functions #####
281 ===============================================================================
282 [..] This section provides the following functions:
283 (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
284 detection length to more than 4 bits for multiprocessor address mark wake up.
285 #if defined(USART_CR1_UESM)
286 (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
287 trigger: address match, Start Bit detection or RXNE bit status.
288 (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
289 (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
290 #endif
291
292 [..] This subsection also provides a set of additional functions providing enhanced reception
293 services to user. (For example, these functions allow application to handle use cases
294 where number of data to be received is unknown).
295
296 (#) Compared to standard reception services which only consider number of received
297 data elements as reception completion criteria, these functions also consider additional events
298 as triggers for updating reception status to caller :
299 (+) Detection of inactivity period (RX line has not been active for a given period).
300 (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
301 for 1 frame time, after last received byte.
302 (++) RX inactivity detected by RTO, i.e. line has been in idle state
303 for a programmable time, after last received byte.
304 (+) Detection that a specific character has been received.
305
306 (#) There are two mode of transfer:
307 (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
308 or till IDLE event occurs. Reception is handled only during function execution.
309 When function exits, no data reception could occur. HAL status and number of actually received data elements,
310 are returned by function after finishing transfer.
311 (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
312 These API's return the HAL status.
313 The end of the data processing will be indicated through the
314 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
315 The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
316 The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
317
318 (#) Blocking mode API:
319 (+) HAL_UARTEx_ReceiveToIdle()
320
321 (#) Non-Blocking mode API with Interrupt:
322 (+) HAL_UARTEx_ReceiveToIdle_IT()
323
324 (#) Non-Blocking mode API with DMA:
325 (+) HAL_UARTEx_ReceiveToIdle_DMA()
326
327 @endverbatim
328 * @{
329 */
330
331 /**
332 * @brief By default in multiprocessor mode, when the wake up method is set
333 * to address mark, the UART handles only 4-bit long addresses detection;
334 * this API allows to enable longer addresses detection (6-, 7- or 8-bit
335 * long).
336 * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
337 * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
338 * @param huart UART handle.
339 * @param AddressLength This parameter can be one of the following values:
340 * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
341 * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
342 * @retval HAL status
343 */
HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef * huart,uint32_t AddressLength)344 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
345 {
346 /* Check the UART handle allocation */
347 if (huart == NULL)
348 {
349 return HAL_ERROR;
350 }
351
352 /* Check the address length parameter */
353 assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
354
355 huart->gState = HAL_UART_STATE_BUSY;
356
357 /* Disable the Peripheral */
358 __HAL_UART_DISABLE(huart);
359
360 /* Set the address length */
361 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
362
363 /* Enable the Peripheral */
364 __HAL_UART_ENABLE(huart);
365
366 /* TEACK and/or REACK to check before moving huart->gState to Ready */
367 return (UART_CheckIdleState(huart));
368 }
369
370 #if defined(USART_CR1_UESM)
371 /**
372 * @brief Set Wakeup from Stop mode interrupt flag selection.
373 * @note It is the application responsibility to enable the interrupt used as
374 * usart_wkup interrupt source before entering low-power mode.
375 * @param huart UART handle.
376 * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
377 * This parameter can be one of the following values:
378 * @arg @ref UART_WAKEUP_ON_ADDRESS
379 * @arg @ref UART_WAKEUP_ON_STARTBIT
380 * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
381 * @retval HAL status
382 */
HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)383 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
384 {
385 HAL_StatusTypeDef status = HAL_OK;
386 uint32_t tickstart;
387
388 /* check the wake-up from stop mode UART instance */
389 assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
390 /* check the wake-up selection parameter */
391 assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
392
393 /* Process Locked */
394 __HAL_LOCK(huart);
395
396 huart->gState = HAL_UART_STATE_BUSY;
397
398 /* Disable the Peripheral */
399 __HAL_UART_DISABLE(huart);
400
401 #if defined(USART_CR3_WUS)
402 /* Set the wake-up selection scheme */
403 MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
404 #endif /* USART_CR3_WUS */
405
406 if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
407 {
408 UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
409 }
410
411 /* Enable the Peripheral */
412 __HAL_UART_ENABLE(huart);
413
414 /* Init tickstart for timeout management */
415 tickstart = HAL_GetTick();
416
417 /* Wait until REACK flag is set */
418 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
419 {
420 status = HAL_TIMEOUT;
421 }
422 else
423 {
424 /* Initialize the UART State */
425 huart->gState = HAL_UART_STATE_READY;
426 }
427
428 /* Process Unlocked */
429 __HAL_UNLOCK(huart);
430
431 return status;
432 }
433
434 /**
435 * @brief Enable UART Stop Mode.
436 * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
437 * @param huart UART handle.
438 * @retval HAL status
439 */
HAL_UARTEx_EnableStopMode(UART_HandleTypeDef * huart)440 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
441 {
442 /* Process Locked */
443 __HAL_LOCK(huart);
444
445 /* Set UESM bit */
446 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
447
448 /* Process Unlocked */
449 __HAL_UNLOCK(huart);
450
451 return HAL_OK;
452 }
453
454 /**
455 * @brief Disable UART Stop Mode.
456 * @param huart UART handle.
457 * @retval HAL status
458 */
HAL_UARTEx_DisableStopMode(UART_HandleTypeDef * huart)459 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
460 {
461 /* Process Locked */
462 __HAL_LOCK(huart);
463
464 /* Clear UESM bit */
465 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
466
467 /* Process Unlocked */
468 __HAL_UNLOCK(huart);
469
470 return HAL_OK;
471 }
472
473 #endif /* USART_CR1_UESM */
474 /**
475 * @brief Receive an amount of data in blocking mode till either the expected number of data
476 * is received or an IDLE event occurs.
477 * @note HAL_OK is returned if reception is completed (expected number of data has been received)
478 * or if reception is stopped after IDLE event (less than the expected number of data has been received)
479 * In this case, RxLen output parameter indicates number of data available in reception buffer.
480 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
481 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
482 * of uint16_t available through pData.
483 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
484 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
485 * (16 bits) (as received data will be handled using uint16_t pointer cast). Depending on compilation chain,
486 * use of specific alignment compilation directives or pragmas might be required to ensure proper
487 * alignment for 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 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
513 should be aligned on a uint16_t frontier, as data to be received from RDR will be
514 handled through a uint16_t cast. */
515 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
516 {
517 if ((((uint32_t)pData) & 1U) != 0U)
518 {
519 return HAL_ERROR;
520 }
521 }
522
523 huart->ErrorCode = HAL_UART_ERROR_NONE;
524 huart->RxState = HAL_UART_STATE_BUSY_RX;
525 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
526 huart->RxEventType = HAL_UART_RXEVENT_TC;
527
528 /* Init tickstart for timeout management */
529 tickstart = HAL_GetTick();
530
531 huart->RxXferSize = Size;
532 huart->RxXferCount = Size;
533
534 /* Computation of UART mask to apply to RDR register */
535 UART_MASK_COMPUTATION(huart);
536 uhMask = huart->Mask;
537
538 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
539 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
540 {
541 pdata8bits = NULL;
542 pdata16bits = (uint16_t *) pData;
543 }
544 else
545 {
546 pdata8bits = pData;
547 pdata16bits = NULL;
548 }
549
550 /* Initialize output number of received elements */
551 *RxLen = 0U;
552
553 /* as long as data have to be received */
554 while (huart->RxXferCount > 0U)
555 {
556 /* Check if IDLE flag is set */
557 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
558 {
559 /* Clear IDLE flag in ISR */
560 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
561
562 /* If Set, but no data ever received, clear flag without exiting loop */
563 /* If Set, and data has already been received, this means Idle Event is valid : End reception */
564 if (*RxLen > 0U)
565 {
566 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
567 huart->RxState = HAL_UART_STATE_READY;
568
569 return HAL_OK;
570 }
571 }
572
573 /* Check if RXNE flag is set */
574 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
575 {
576 if (pdata8bits == NULL)
577 {
578 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
579 pdata16bits++;
580 }
581 else
582 {
583 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
584 pdata8bits++;
585 }
586 /* Increment number of received elements */
587 *RxLen += 1U;
588 huart->RxXferCount--;
589 }
590
591 /* Check for the Timeout */
592 if (Timeout != HAL_MAX_DELAY)
593 {
594 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
595 {
596 huart->RxState = HAL_UART_STATE_READY;
597
598 return HAL_TIMEOUT;
599 }
600 }
601 }
602
603 /* Set number of received elements in output parameter : RxLen */
604 *RxLen = huart->RxXferSize - huart->RxXferCount;
605 /* At end of Rx process, restore huart->RxState to Ready */
606 huart->RxState = HAL_UART_STATE_READY;
607
608 return HAL_OK;
609 }
610 else
611 {
612 return HAL_BUSY;
613 }
614 }
615
616 /**
617 * @brief Receive an amount of data in interrupt mode till either the expected number of data
618 * is received or an IDLE event occurs.
619 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
620 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
621 * number of received data elements.
622 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
623 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
624 * of uint16_t available through pData.
625 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
626 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
627 * (16 bits) (as received data will be handled using uint16_t pointer cast). Depending on compilation chain,
628 * use of specific alignment compilation directives or pragmas might be required
629 * to ensure proper alignment for pData.
630 * @param huart UART handle.
631 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
632 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
633 * @retval HAL status
634 */
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)635 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
636 {
637 HAL_StatusTypeDef status;
638
639 /* Check that a Rx process is not already ongoing */
640 if (huart->RxState == HAL_UART_STATE_READY)
641 {
642 if ((pData == NULL) || (Size == 0U))
643 {
644 return HAL_ERROR;
645 }
646
647 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
648 should be aligned on a uint16_t frontier, as data to be received from RDR will be
649 handled through a uint16_t cast. */
650 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
651 {
652 if ((((uint32_t)pData) & 1U) != 0U)
653 {
654 return HAL_ERROR;
655 }
656 }
657
658 /* Set Reception type to reception till IDLE Event*/
659 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
660 huart->RxEventType = HAL_UART_RXEVENT_TC;
661
662 status = UART_Start_Receive_IT(huart, pData, Size);
663
664 /* Check Rx process has been successfully started */
665 if (status == HAL_OK)
666 {
667 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
668 {
669 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
670 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
671 }
672 else
673 {
674 /* In case of errors already pending when reception is started,
675 Interrupts may have already been raised and lead to reception abortion.
676 (Overrun error for instance).
677 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
678 status = HAL_ERROR;
679 }
680 }
681
682 return status;
683 }
684 else
685 {
686 return HAL_BUSY;
687 }
688 }
689
690 /**
691 * @brief Receive an amount of data in DMA mode till either the expected number
692 * of data is received or an IDLE event occurs.
693 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
694 * to DMA services, transferring automatically received data elements in user reception buffer and
695 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
696 * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
697 * @note When the UART parity is enabled (PCE = 1), the received data contain
698 * the parity bit (MSB position).
699 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
700 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
701 * of uint16_t available through pData.
702 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
703 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
704 * (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
705 * use of specific alignment compilation directives or pragmas might be required
706 * to ensure proper alignment for pData.
707 * @param huart UART handle.
708 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
709 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
710 * @retval HAL status
711 */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)712 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
713 {
714 HAL_StatusTypeDef status;
715
716 /* Check that a Rx process is not already ongoing */
717 if (huart->RxState == HAL_UART_STATE_READY)
718 {
719 if ((pData == NULL) || (Size == 0U))
720 {
721 return HAL_ERROR;
722 }
723
724 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
725 should be aligned on a uint16_t frontier, as data copy from RDR will be
726 handled by DMA from a uint16_t frontier. */
727 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
728 {
729 if ((((uint32_t)pData) & 1U) != 0U)
730 {
731 return HAL_ERROR;
732 }
733 }
734
735 /* Set Reception type to reception till IDLE Event*/
736 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
737 huart->RxEventType = HAL_UART_RXEVENT_TC;
738
739 status = UART_Start_Receive_DMA(huart, pData, Size);
740
741 /* Check Rx process has been successfully started */
742 if (status == HAL_OK)
743 {
744 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
745 {
746 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
747 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
748 }
749 else
750 {
751 /* In case of errors already pending when reception is started,
752 Interrupts may have already been raised and lead to reception abortion.
753 (Overrun error for instance).
754 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
755 status = HAL_ERROR;
756 }
757 }
758
759 return status;
760 }
761 else
762 {
763 return HAL_BUSY;
764 }
765 }
766
767 /**
768 * @brief Provide Rx Event type that has lead to RxEvent callback execution.
769 * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
770 * of reception process is provided to application through calls of Rx Event callback (either default one
771 * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
772 * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
773 * to Rx Event callback execution.
774 * @note This function is expected to be called within the user implementation of Rx Event Callback,
775 * in order to provide the accurate value :
776 * In Interrupt Mode :
777 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
778 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
779 * received data is lower than expected one)
780 * In DMA Mode :
781 * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
782 * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
783 * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
784 * received data is lower than expected one).
785 * In DMA mode, RxEvent callback could be called several times;
786 * When DMA is configured in Normal Mode, HT event does not stop Reception process;
787 * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
788 * @param huart UART handle.
789 * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
790 */
HAL_UARTEx_GetRxEventType(UART_HandleTypeDef * huart)791 HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart)
792 {
793 /* Return Rx Event type value, as stored in UART handle */
794 return (huart->RxEventType);
795 }
796
797 /**
798 * @}
799 */
800
801 /**
802 * @}
803 */
804
805 /** @addtogroup UARTEx_Private_Functions
806 * @{
807 */
808 #if defined(USART_CR1_UESM)
809
810 /**
811 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
812 * @param huart UART handle.
813 * @param WakeUpSelection UART wake up from stop mode parameters.
814 * @retval None
815 */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)816 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
817 {
818 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
819
820 /* Set the USART address length */
821 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
822
823 /* Set the USART address node */
824 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
825 }
826 #endif /* USART_CR1_UESM */
827
828 /**
829 * @}
830 */
831
832 #endif /* HAL_UART_MODULE_ENABLED */
833
834 /**
835 * @}
836 */
837
838 /**
839 * @}
840 */
841
842