Subversion Repositories ScreenTimer

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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
  @verbatim
13
  ==============================================================================
14
               ##### UART peripheral extended features  #####
15
  ==============================================================================
16
 
17
    (#) Declare a UART_HandleTypeDef handle structure.
18
 
19
    (#) For the UART RS485 Driver Enable mode, initialize the UART registers
20
        by calling the HAL_RS485Ex_Init() API.
21
 
22
  @endverbatim
23
  ******************************************************************************
24
  * @attention
25
  *
26
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
27
  * All rights reserved.</center></h2>
28
  *
29
  * This software component is licensed by ST under BSD 3-Clause license,
30
  * the "License"; You may not use this file except in compliance with the
31
  * License. You may obtain a copy of the License at:
32
  *                        opensource.org/licenses/BSD-3-Clause
33
  *
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
  */
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
  */
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
  */
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
  */
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
  */
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
  */
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
  */
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
    __HAL_LOCK(huart);
524
 
525
    huart->ErrorCode = HAL_UART_ERROR_NONE;
526
    huart->RxState = HAL_UART_STATE_BUSY_RX;
527
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
528
 
529
    /* Init tickstart for timeout management */
530
    tickstart = HAL_GetTick();
531
 
532
    huart->RxXferSize  = Size;
533
    huart->RxXferCount = Size;
534
 
535
    /* Computation of UART mask to apply to RDR register */
536
    UART_MASK_COMPUTATION(huart);
537
    uhMask = huart->Mask;
538
 
539
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
540
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
541
    {
542
      pdata8bits  = NULL;
543
      pdata16bits = (uint16_t *) pData;
544
    }
545
    else
546
    {
547
      pdata8bits  = pData;
548
      pdata16bits = NULL;
549
    }
550
 
551
    __HAL_UNLOCK(huart);
552
 
553
    /* Initialize output number of received elements */
554
    *RxLen = 0U;
555
 
556
    /* as long as data have to be received */
557
    while (huart->RxXferCount > 0U)
558
    {
559
      /* Check if IDLE flag is set */
560
      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
561
      {
562
        /* Clear IDLE flag in ISR */
563
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
564
 
565
        /* If Set, but no data ever received, clear flag without exiting loop */
566
        /* If Set, and data has already been received, this means Idle Event is valid : End reception */
567
        if (*RxLen > 0U)
568
        {
569
          huart->RxState = HAL_UART_STATE_READY;
570
 
571
          return HAL_OK;
572
        }
573
      }
574
 
575
      /* Check if RXNE flag is set */
576
      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
577
      {
578
        if (pdata8bits == NULL)
579
        {
580
          *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
581
          pdata16bits++;
582
        }
583
        else
584
        {
585
          *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
586
          pdata8bits++;
587
        }
588
        /* Increment number of received elements */
589
        *RxLen += 1U;
590
        huart->RxXferCount--;
591
      }
592
 
593
      /* Check for the Timeout */
594
      if (Timeout != HAL_MAX_DELAY)
595
      {
596
        if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
597
        {
598
          huart->RxState = HAL_UART_STATE_READY;
599
 
600
          return HAL_TIMEOUT;
601
        }
602
      }
603
    }
604
 
605
    /* Set number of received elements in output parameter : RxLen */
606
    *RxLen = huart->RxXferSize - huart->RxXferCount;
607
    /* At end of Rx process, restore huart->RxState to Ready */
608
    huart->RxState = HAL_UART_STATE_READY;
609
 
610
    return HAL_OK;
611
  }
612
  else
613
  {
614
    return HAL_BUSY;
615
  }
616
}
617
 
618
/**
619
  * @brief Receive an amount of data in interrupt mode till either the expected number of data
620
  *        is received or an IDLE event occurs.
621
  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
622
  *        to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
623
  *        number of received data elements.
624
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
625
  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
626
  *        of uint16_t available through pData.
627
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
628
  *        address of user data buffer for storing data to be received, should be aligned on a half word frontier
629
  *        (16 bits) (as received data will be handled using uint16_t pointer cast). Depending on compilation chain,
630
  *        use of specific alignment compilation directives or pragmas might be required
631
  *        to ensure proper alignment for pData.
632
  * @param huart UART handle.
633
  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
634
  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
635
  * @retval HAL status
636
  */
637
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
638
{
639
  HAL_StatusTypeDef status;
640
 
641
  /* Check that a Rx process is not already ongoing */
642
  if (huart->RxState == HAL_UART_STATE_READY)
643
  {
644
    if ((pData == NULL) || (Size == 0U))
645
    {
646
      return HAL_ERROR;
647
    }
648
 
649
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
650
       should be aligned on a uint16_t frontier, as data to be received from RDR will be
651
       handled through a uint16_t cast. */
652
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
653
    {
654
      if ((((uint32_t)pData) & 1U) != 0U)
655
      {
656
        return  HAL_ERROR;
657
      }
658
    }
659
 
660
    __HAL_LOCK(huart);
661
 
662
    /* Set Reception type to reception till IDLE Event*/
663
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
664
 
665
    status =  UART_Start_Receive_IT(huart, pData, Size);
666
 
667
    /* Check Rx process has been successfully started */
668
    if (status == HAL_OK)
669
    {
670
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
671
      {
672
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
673
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
674
      }
675
      else
676
      {
677
        /* In case of errors already pending when reception is started,
678
           Interrupts may have already been raised and lead to reception abortion.
679
           (Overrun error for instance).
680
           In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
681
        status = HAL_ERROR;
682
      }
683
    }
684
 
685
    return status;
686
  }
687
  else
688
  {
689
    return HAL_BUSY;
690
  }
691
}
692
 
693
/**
694
  * @brief Receive an amount of data in DMA mode till either the expected number
695
  *        of data is received or an IDLE event occurs.
696
  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
697
  *        to DMA services, transferring automatically received data elements in user reception buffer and
698
  *        calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
699
  *        reception phase as ended. In all cases, callback execution will indicate number of received data elements.
700
  * @note  When the UART parity is enabled (PCE = 1), the received data contain
701
  *        the parity bit (MSB position).
702
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
703
  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
704
  *        of uint16_t available through pData.
705
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
706
  *        address of user data buffer for storing data to be received, should be aligned on a half word frontier
707
  *        (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
708
  *        use of specific alignment compilation directives or pragmas might be required
709
  *        to ensure proper alignment for pData.
710
  * @param huart UART handle.
711
  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
712
  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
713
  * @retval HAL status
714
  */
715
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
716
{
717
  HAL_StatusTypeDef status;
718
 
719
  /* Check that a Rx process is not already ongoing */
720
  if (huart->RxState == HAL_UART_STATE_READY)
721
  {
722
    if ((pData == NULL) || (Size == 0U))
723
    {
724
      return HAL_ERROR;
725
    }
726
 
727
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
728
       should be aligned on a uint16_t frontier, as data copy from RDR will be
729
       handled by DMA from a uint16_t frontier. */
730
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
731
    {
732
      if ((((uint32_t)pData) & 1U) != 0U)
733
      {
734
        return  HAL_ERROR;
735
      }
736
    }
737
 
738
    __HAL_LOCK(huart);
739
 
740
    /* Set Reception type to reception till IDLE Event*/
741
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
742
 
743
    status =  UART_Start_Receive_DMA(huart, pData, Size);
744
 
745
    /* Check Rx process has been successfully started */
746
    if (status == HAL_OK)
747
    {
748
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
749
      {
750
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
751
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
752
      }
753
      else
754
      {
755
        /* In case of errors already pending when reception is started,
756
           Interrupts may have already been raised and lead to reception abortion.
757
           (Overrun error for instance).
758
           In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
759
        status = HAL_ERROR;
760
      }
761
    }
762
 
763
    return status;
764
  }
765
  else
766
  {
767
    return HAL_BUSY;
768
  }
769
}
770
 
771
/**
772
  * @}
773
  */
774
 
775
/**
776
  * @}
777
  */
778
 
779
/** @addtogroup UARTEx_Private_Functions
780
  * @{
781
  */
782
#if defined(USART_CR1_UESM)
783
 
784
/**
785
  * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
786
  * @param huart           UART handle.
787
  * @param WakeUpSelection UART wake up from stop mode parameters.
788
  * @retval None
789
  */
790
static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
791
{
792
  assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
793
 
794
  /* Set the USART address length */
795
  MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
796
 
797
  /* Set the USART address node */
798
  MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
799
}
800
#endif /* USART_CR1_UESM */
801
 
802
/**
803
  * @}
804
  */
805
 
806
#endif /* HAL_UART_MODULE_ENABLED */
807
 
808
/**
809
  * @}
810
  */
811
 
812
/**
813
  * @}
814
  */
815
 
816
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/