Subversion Repositories FuelGauge

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_hal_uart.c
4
  * @author  MCD Application Team
5
  * @brief   UART HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8
  *           + Initialization and de-initialization functions
9
  *           + IO operation functions
10
  *           + Peripheral Control functions
11
  *
12
  *
13
  @verbatim
14
 ===============================================================================
15
                        ##### How to use this driver #####
16
 ===============================================================================
17
  [..]
18
    The UART HAL driver can be used as follows:
19
 
20
    (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
21
    (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
22
        (++) Enable the USARTx interface clock.
23
        (++) UART pins configuration:
24
            (+++) Enable the clock for the UART GPIOs.
25
            (+++) Configure these UART pins as alternate function pull-up.
26
        (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
27
             and HAL_UART_Receive_IT() APIs):
28
            (+++) Configure the USARTx interrupt priority.
29
            (+++) Enable the NVIC USART IRQ handle.
30
        (++) UART interrupts handling:
31
              -@@-  The specific UART interrupts (Transmission complete interrupt,
32
                RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
33
                are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
34
                inside the transmit and receive processes.
35
        (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
36
             and HAL_UART_Receive_DMA() APIs):
37
            (+++) Declare a DMA handle structure for the Tx/Rx channel.
38
            (+++) Enable the DMAx interface clock.
39
            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40
            (+++) Configure the DMA Tx/Rx channel.
41
            (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
6 mjames 42
            (+++) Configure the priority and enable the NVIC for the transfer complete
43
                  interrupt on the DMA Tx/Rx channel.
2 mjames 44
 
45
    (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
46
        flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
47
 
48
    (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
49
        in the huart handle AdvancedInit structure.
50
 
51
    (#) For the UART asynchronous mode, initialize the UART registers by calling
52
        the HAL_UART_Init() API.
53
 
54
    (#) For the UART Half duplex mode, initialize the UART registers by calling
55
        the HAL_HalfDuplex_Init() API.
56
 
57
    (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
58
        by calling the HAL_LIN_Init() API.
59
 
60
    (#) For the UART Multiprocessor mode, initialize the UART registers
61
        by calling the HAL_MultiProcessor_Init() API.
62
 
63
    (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
64
        by calling the HAL_RS485Ex_Init() API.
65
 
66
    [..]
67
    (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
68
        also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
69
        calling the customized HAL_UART_MspInit() API.
70
 
71
    ##### Callback registration #####
72
    ==================================
73
 
74
    [..]
75
    The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
76
    allows the user to configure dynamically the driver callbacks.
77
 
78
    [..]
6 mjames 79
    Use Function HAL_UART_RegisterCallback() to register a user callback.
80
    Function HAL_UART_RegisterCallback() allows to register following callbacks:
2 mjames 81
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
82
    (+) TxCpltCallback            : Tx Complete Callback.
83
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
84
    (+) RxCpltCallback            : Rx Complete Callback.
85
    (+) ErrorCallback             : Error Callback.
86
    (+) AbortCpltCallback         : Abort Complete Callback.
87
    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
88
    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
89
    (+) WakeupCallback            : Wakeup Callback.
90
    (+) MspInitCallback           : UART MspInit.
91
    (+) MspDeInitCallback         : UART MspDeInit.
92
    This function takes as parameters the HAL peripheral handle, the Callback ID
93
    and a pointer to the user callback function.
94
 
95
    [..]
6 mjames 96
    Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
2 mjames 97
    weak (surcharged) function.
6 mjames 98
    HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
2 mjames 99
    and the Callback ID.
100
    This function allows to reset following callbacks:
101
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
102
    (+) TxCpltCallback            : Tx Complete Callback.
103
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
104
    (+) RxCpltCallback            : Rx Complete Callback.
105
    (+) ErrorCallback             : Error Callback.
106
    (+) AbortCpltCallback         : Abort Complete Callback.
107
    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
108
    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
109
    (+) WakeupCallback            : Wakeup Callback.
110
    (+) MspInitCallback           : UART MspInit.
111
    (+) MspDeInitCallback         : UART MspDeInit.
112
 
113
    [..]
6 mjames 114
    For specific callback RxEventCallback, use dedicated registration/reset functions:
115
    respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
116
 
117
    [..]
118
    By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
2 mjames 119
    all callbacks are set to the corresponding weak (surcharged) functions:
6 mjames 120
    examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
2 mjames 121
    Exception done for MspInit and MspDeInit functions that are respectively
6 mjames 122
    reset to the legacy weak (surcharged) functions in the HAL_UART_Init()
123
    and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
124
    If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
2 mjames 125
    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
126
 
127
    [..]
128
    Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
129
    Exception done MspInit/MspDeInit that can be registered/unregistered
130
    in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
131
    MspInit/DeInit callbacks can be used during the Init/DeInit.
132
    In that case first register the MspInit/MspDeInit user callbacks
6 mjames 133
    using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
134
    or HAL_UART_Init() function.
2 mjames 135
 
136
    [..]
137
    When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
138
    not defined, the callback registration feature is not available
139
    and weak (surcharged) callbacks are used.
140
 
141
 
142
  @endverbatim
143
  ******************************************************************************
144
  * @attention
145
  *
146
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
147
  * All rights reserved.</center></h2>
148
  *
149
  * This software component is licensed by ST under BSD 3-Clause license,
150
  * the "License"; You may not use this file except in compliance with the
151
  * License. You may obtain a copy of the License at:
152
  *                        opensource.org/licenses/BSD-3-Clause
153
  *
154
  ******************************************************************************
155
  */
156
 
157
/* Includes ------------------------------------------------------------------*/
158
#include "stm32f0xx_hal.h"
159
 
160
/** @addtogroup STM32F0xx_HAL_Driver
161
  * @{
162
  */
163
 
164
/** @defgroup UART UART
165
  * @brief HAL UART module driver
166
  * @{
167
  */
168
 
169
#ifdef HAL_UART_MODULE_ENABLED
170
 
171
/* Private typedef -----------------------------------------------------------*/
172
/* Private define ------------------------------------------------------------*/
173
/** @defgroup UART_Private_Constants UART Private Constants
174
  * @{
175
  */
6 mjames 176
#define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \
177
                                      USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
2 mjames 178
 
6 mjames 179
#define USART_CR3_FIELDS  ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE |\
180
                            USART_CR3_ONEBIT)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
2 mjames 181
 
182
 
183
#define UART_BRR_MIN    0x10U        /* UART BRR minimum authorized value */
184
#define UART_BRR_MAX    0x0000FFFFU  /* UART BRR maximum authorized value */
185
/**
186
  * @}
187
  */
188
 
189
/* Private macros ------------------------------------------------------------*/
190
/* Private function prototypes -----------------------------------------------*/
191
/** @addtogroup UART_Private_Functions
192
  * @{
193
  */
194
static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
195
static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
196
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
197
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
198
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
199
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
200
static void UART_DMAError(DMA_HandleTypeDef *hdma);
201
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
202
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
203
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
204
static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
205
static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
206
static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
207
static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
208
static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
209
static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
210
static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
211
/**
212
  * @}
213
  */
214
 
6 mjames 215
/* Private variables ---------------------------------------------------------*/
216
/* Exported Constants --------------------------------------------------------*/
2 mjames 217
/* Exported functions --------------------------------------------------------*/
218
 
219
/** @defgroup UART_Exported_Functions UART Exported Functions
220
  * @{
221
  */
222
 
223
/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
224
  *  @brief    Initialization and Configuration functions
225
  *
226
@verbatim
227
===============================================================================
228
            ##### Initialization and Configuration functions #####
229
 ===============================================================================
230
    [..]
231
    This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
232
    in asynchronous mode.
233
      (+) For the asynchronous mode the parameters below can be configured:
234
        (++) Baud Rate
235
        (++) Word Length
236
        (++) Stop Bit
237
        (++) Parity: If the parity is enabled, then the MSB bit of the data written
238
             in the data register is transmitted but is changed by the parity bit.
239
        (++) Hardware flow control
240
        (++) Receiver/transmitter modes
241
        (++) Over Sampling Method
242
        (++) One-Bit Sampling Method
243
      (+) For the asynchronous mode, the following advanced features can be configured as well:
244
        (++) TX and/or RX pin level inversion
245
        (++) data logical level inversion
246
        (++) RX and TX pins swap
247
        (++) RX overrun detection disabling
248
        (++) DMA disabling on RX error
249
        (++) MSB first on communication line
250
        (++) auto Baud rate detection
251
    [..]
252
    The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
253
    follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
254
    and UART multiprocessor mode configuration procedures (details for the procedures
255
    are available in reference manual).
256
 
257
@endverbatim
258
 
259
  Depending on the frame length defined by the M1 and M0 bits (7-bit,
260
  8-bit or 9-bit), the possible UART formats are listed in the
261
  following table.
262
 
263
  Table 1. UART frame format.
264
    +-----------------------------------------------------------------------+
265
    |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
266
    |---------|---------|-----------|---------------------------------------|
267
    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
268
    |---------|---------|-----------|---------------------------------------|
269
    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
270
    |---------|---------|-----------|---------------------------------------|
271
    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
272
    |---------|---------|-----------|---------------------------------------|
273
    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
274
    |---------|---------|-----------|---------------------------------------|
275
    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
276
    |---------|---------|-----------|---------------------------------------|
277
    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
278
    +-----------------------------------------------------------------------+
279
 
280
  * @{
281
  */
282
 
283
/**
284
  * @brief Initialize the UART mode according to the specified
285
  *        parameters in the UART_InitTypeDef and initialize the associated handle.
286
  * @param huart UART handle.
287
  * @retval HAL status
288
  */
289
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
290
{
291
  /* Check the UART handle allocation */
292
  if (huart == NULL)
293
  {
294
    return HAL_ERROR;
295
  }
296
 
297
  if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
298
  {
299
    /* Check the parameters */
300
    assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
301
  }
302
  else
303
  {
304
    /* Check the parameters */
305
    assert_param(IS_UART_INSTANCE(huart->Instance));
306
  }
307
 
308
  if (huart->gState == HAL_UART_STATE_RESET)
309
  {
310
    /* Allocate lock resource and initialize it */
311
    huart->Lock = HAL_UNLOCKED;
312
 
313
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
314
    UART_InitCallbacksToDefault(huart);
315
 
316
    if (huart->MspInitCallback == NULL)
317
    {
318
      huart->MspInitCallback = HAL_UART_MspInit;
319
    }
320
 
321
    /* Init the low level hardware */
322
    huart->MspInitCallback(huart);
323
#else
324
    /* Init the low level hardware : GPIO, CLOCK */
325
    HAL_UART_MspInit(huart);
326
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
327
  }
328
 
329
  huart->gState = HAL_UART_STATE_BUSY;
330
 
331
  __HAL_UART_DISABLE(huart);
332
 
333
  /* Set the UART Communication parameters */
334
  if (UART_SetConfig(huart) == HAL_ERROR)
335
  {
336
    return HAL_ERROR;
337
  }
338
 
339
  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
340
  {
341
    UART_AdvFeatureConfig(huart);
342
  }
343
 
344
  /* In asynchronous mode, the following bits must be kept cleared:
345
  - LINEN (if LIN is supported) and CLKEN bits in the USART_CR2 register,
346
  - SCEN (if Smartcard is supported), HDSEL and IREN (if IrDA is supported)  bits in the USART_CR3 register.*/
347
#if defined (USART_CR2_LINEN)
348
  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
349
#else
350
  CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
351
#endif /* USART_CR2_LINEN */
352
#if defined (USART_CR3_SCEN)
353
#if defined (USART_CR3_IREN)
354
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
355
#else
356
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
357
#endif /* USART_CR3_IREN */
358
#else
359
#if defined (USART_CR3_IREN)
360
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN));
361
#else
362
  CLEAR_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
363
#endif /* USART_CR3_IREN*/
364
#endif /* USART_CR3_SCEN */
365
 
366
  __HAL_UART_ENABLE(huart);
367
 
368
  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
369
  return (UART_CheckIdleState(huart));
370
}
371
 
372
/**
373
  * @brief Initialize the half-duplex mode according to the specified
374
  *        parameters in the UART_InitTypeDef and creates the associated handle.
375
  * @param huart UART handle.
376
  * @retval HAL status
377
  */
378
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
379
{
380
  /* Check the UART handle allocation */
381
  if (huart == NULL)
382
  {
383
    return HAL_ERROR;
384
  }
385
 
386
  /* Check UART instance */
387
  assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
388
 
389
  if (huart->gState == HAL_UART_STATE_RESET)
390
  {
391
    /* Allocate lock resource and initialize it */
392
    huart->Lock = HAL_UNLOCKED;
393
 
394
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
395
    UART_InitCallbacksToDefault(huart);
396
 
397
    if (huart->MspInitCallback == NULL)
398
    {
399
      huart->MspInitCallback = HAL_UART_MspInit;
400
    }
401
 
402
    /* Init the low level hardware */
403
    huart->MspInitCallback(huart);
404
#else
405
    /* Init the low level hardware : GPIO, CLOCK */
406
    HAL_UART_MspInit(huart);
407
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
408
  }
409
 
410
  huart->gState = HAL_UART_STATE_BUSY;
411
 
412
  __HAL_UART_DISABLE(huart);
413
 
414
  /* Set the UART Communication parameters */
415
  if (UART_SetConfig(huart) == HAL_ERROR)
416
  {
417
    return HAL_ERROR;
418
  }
419
 
420
  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
421
  {
422
    UART_AdvFeatureConfig(huart);
423
  }
424
 
425
  /* In half-duplex mode, the following bits must be kept cleared:
426
  - LINEN (if LIN is supported) and CLKEN bits in the USART_CR2 register,
427
  - SCEN (if Smartcard is supported) and IREN (if IrDA is supported) bits in the USART_CR3 register.*/
428
#if defined (USART_CR2_LINEN)
429
  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
430
#else
431
  CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
432
#endif /* USART_CR2_LINEN */
433
#if defined (USART_CR3_SCEN)
434
#if defined (USART_CR3_IREN)
435
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
436
#else
437
  CLEAR_BIT(huart->Instance->CR3, USART_CR3_SCEN);
438
#endif /* USART_CR3_IREN */
439
#else
440
#if defined (USART_CR3_IREN)
441
  CLEAR_BIT(huart->Instance->CR3, USART_CR3_IREN);
442
#endif /* USART_CR3_IREN */
443
#endif /* USART_CR3_SCEN */
444
 
445
  /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
446
  SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
447
 
448
  __HAL_UART_ENABLE(huart);
449
 
450
  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
451
  return (UART_CheckIdleState(huart));
452
}
453
 
454
 
455
#if   defined(USART_CR2_LINEN)
456
/**
457
  * @brief Initialize the LIN mode according to the specified
458
  *        parameters in the UART_InitTypeDef and creates the associated handle.
459
  * @param huart             UART handle.
460
  * @param BreakDetectLength Specifies the LIN break detection length.
461
  *        This parameter can be one of the following values:
462
  *          @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
463
  *          @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
464
  * @retval HAL status
465
  */
466
HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
467
{
468
  /* Check the UART handle allocation */
469
  if (huart == NULL)
470
  {
471
    return HAL_ERROR;
472
  }
473
 
474
  /* Check the LIN UART instance */
475
  assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
476
  /* Check the Break detection length parameter */
477
  assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
478
 
479
  /* LIN mode limited to 16-bit oversampling only */
480
  if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
481
  {
482
    return HAL_ERROR;
483
  }
484
  /* LIN mode limited to 8-bit data length */
485
  if (huart->Init.WordLength != UART_WORDLENGTH_8B)
486
  {
487
    return HAL_ERROR;
488
  }
489
 
490
  if (huart->gState == HAL_UART_STATE_RESET)
491
  {
492
    /* Allocate lock resource and initialize it */
493
    huart->Lock = HAL_UNLOCKED;
494
 
495
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
496
    UART_InitCallbacksToDefault(huart);
497
 
498
    if (huart->MspInitCallback == NULL)
499
    {
500
      huart->MspInitCallback = HAL_UART_MspInit;
501
    }
502
 
503
    /* Init the low level hardware */
504
    huart->MspInitCallback(huart);
505
#else
506
    /* Init the low level hardware : GPIO, CLOCK */
507
    HAL_UART_MspInit(huart);
508
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
509
  }
510
 
511
  huart->gState = HAL_UART_STATE_BUSY;
512
 
513
  __HAL_UART_DISABLE(huart);
514
 
515
  /* Set the UART Communication parameters */
516
  if (UART_SetConfig(huart) == HAL_ERROR)
517
  {
518
    return HAL_ERROR;
519
  }
520
 
521
  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
522
  {
523
    UART_AdvFeatureConfig(huart);
524
  }
525
 
526
  /* In LIN mode, the following bits must be kept cleared:
527
  - LINEN and CLKEN bits in the USART_CR2 register,
528
  - SCEN(if Smartcard is supported) and IREN(if IrDA is supported) bits in the USART_CR3 register.*/
529
  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
530
#if defined (USART_CR3_SCEN)
531
#if defined (USART_CR3_IREN)
532
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
533
#else
534
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
535
#endif /* USART_CR3_IREN */
536
#else
537
#if defined (USART_CR3_IREN)
538
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN));
539
#else
540
  CLEAR_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
541
#endif /* USART_CR3_IREN*/
542
#endif /* USART_CR3_SCEN */
543
 
544
  /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
545
  SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
546
 
547
  /* Set the USART LIN Break detection length. */
548
  MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
549
 
550
  __HAL_UART_ENABLE(huart);
551
 
552
  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
553
  return (UART_CheckIdleState(huart));
554
}
555
#endif /* USART_CR2_LINEN */
556
 
557
 
558
/**
559
  * @brief Initialize the multiprocessor mode according to the specified
560
  *        parameters in the UART_InitTypeDef and initialize the associated handle.
561
  * @param huart        UART handle.
562
  * @param Address      UART node address (4-, 6-, 7- or 8-bit long).
563
  * @param WakeUpMethod Specifies the UART wakeup method.
564
  *        This parameter can be one of the following values:
565
  *          @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
566
  *          @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
567
  * @note  If the user resorts to idle line detection wake up, the Address parameter
568
  *        is useless and ignored by the initialization function.
569
  * @note  If the user resorts to address mark wake up, the address length detection
570
  *        is configured by default to 4 bits only. For the UART to be able to
571
  *        manage 6-, 7- or 8-bit long addresses detection, the API
572
  *        HAL_MultiProcessorEx_AddressLength_Set() must be called after
573
  *        HAL_MultiProcessor_Init().
574
  * @retval HAL status
575
  */
576
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
577
{
578
  /* Check the UART handle allocation */
579
  if (huart == NULL)
580
  {
581
    return HAL_ERROR;
582
  }
583
 
584
  /* Check the wake up method parameter */
585
  assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
586
 
587
  if (huart->gState == HAL_UART_STATE_RESET)
588
  {
589
    /* Allocate lock resource and initialize it */
590
    huart->Lock = HAL_UNLOCKED;
591
 
592
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
593
    UART_InitCallbacksToDefault(huart);
594
 
595
    if (huart->MspInitCallback == NULL)
596
    {
597
      huart->MspInitCallback = HAL_UART_MspInit;
598
    }
599
 
600
    /* Init the low level hardware */
601
    huart->MspInitCallback(huart);
602
#else
603
    /* Init the low level hardware : GPIO, CLOCK */
604
    HAL_UART_MspInit(huart);
605
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
606
  }
607
 
608
  huart->gState = HAL_UART_STATE_BUSY;
609
 
610
  __HAL_UART_DISABLE(huart);
611
 
612
  /* Set the UART Communication parameters */
613
  if (UART_SetConfig(huart) == HAL_ERROR)
614
  {
615
    return HAL_ERROR;
616
  }
617
 
618
  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
619
  {
620
    UART_AdvFeatureConfig(huart);
621
  }
622
 
623
  /* In multiprocessor mode, the following bits must be kept cleared:
624
  - LINEN (if LIN is supported) and CLKEN bits in the USART_CR2 register,
625
  - SCEN (if Smartcard is supported), HDSEL and IREN (if IrDA is supported) bits in the USART_CR3 register. */
626
#if defined (USART_CR2_LINEN)
627
  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
628
#else
629
  CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
630
#endif /* USART_CR2_LINEN */
631
#if defined (USART_CR3_SCEN)
632
#if defined (USART_CR3_IREN)
633
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
634
#else
635
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
636
#endif /* USART_CR3_IREN */
637
#else
638
#if defined (USART_CR3_IREN)
639
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN));
640
#else
641
  CLEAR_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
642
#endif /* USART_CR3_IREN */
643
#endif /* USART_CR3_SCEN */
644
 
645
  if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
646
  {
647
    /* If address mark wake up method is chosen, set the USART address node */
648
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
649
  }
650
 
651
  /* Set the wake up method by setting the WAKE bit in the CR1 register */
652
  MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
653
 
654
  __HAL_UART_ENABLE(huart);
655
 
656
  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
657
  return (UART_CheckIdleState(huart));
658
}
659
 
660
 
661
/**
662
  * @brief DeInitialize the UART peripheral.
663
  * @param huart UART handle.
664
  * @retval HAL status
665
  */
666
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
667
{
668
  /* Check the UART handle allocation */
669
  if (huart == NULL)
670
  {
671
    return HAL_ERROR;
672
  }
673
 
674
  /* Check the parameters */
675
  assert_param(IS_UART_INSTANCE(huart->Instance));
676
 
677
  huart->gState = HAL_UART_STATE_BUSY;
678
 
679
  __HAL_UART_DISABLE(huart);
680
 
681
  huart->Instance->CR1 = 0x0U;
682
  huart->Instance->CR2 = 0x0U;
683
  huart->Instance->CR3 = 0x0U;
684
 
685
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
686
  if (huart->MspDeInitCallback == NULL)
687
  {
688
    huart->MspDeInitCallback = HAL_UART_MspDeInit;
689
  }
690
  /* DeInit the low level hardware */
691
  huart->MspDeInitCallback(huart);
692
#else
693
  /* DeInit the low level hardware */
694
  HAL_UART_MspDeInit(huart);
695
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
696
 
697
  huart->ErrorCode = HAL_UART_ERROR_NONE;
698
  huart->gState = HAL_UART_STATE_RESET;
699
  huart->RxState = HAL_UART_STATE_RESET;
6 mjames 700
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 701
 
702
  __HAL_UNLOCK(huart);
703
 
704
  return HAL_OK;
705
}
706
 
707
/**
708
  * @brief Initialize the UART MSP.
709
  * @param huart UART handle.
710
  * @retval None
711
  */
712
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
713
{
714
  /* Prevent unused argument(s) compilation warning */
715
  UNUSED(huart);
716
 
717
  /* NOTE : This function should not be modified, when the callback is needed,
718
            the HAL_UART_MspInit can be implemented in the user file
719
   */
720
}
721
 
722
/**
723
  * @brief DeInitialize the UART MSP.
724
  * @param huart UART handle.
725
  * @retval None
726
  */
727
__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
728
{
729
  /* Prevent unused argument(s) compilation warning */
730
  UNUSED(huart);
731
 
732
  /* NOTE : This function should not be modified, when the callback is needed,
733
            the HAL_UART_MspDeInit can be implemented in the user file
734
   */
735
}
736
 
737
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
738
/**
739
  * @brief  Register a User UART Callback
740
  *         To be used instead of the weak predefined callback
741
  * @param  huart uart handle
742
  * @param  CallbackID ID of the callback to be registered
743
  *         This parameter can be one of the following values:
744
  *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
745
  *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
746
  *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
747
  *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
748
  *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
749
  *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
750
  *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
751
  *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
752
  *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
753
  *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
754
  *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
755
  * @param  pCallback pointer to the Callback function
756
  * @retval HAL status
757
  */
758
HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
759
                                            pUART_CallbackTypeDef pCallback)
760
{
761
  HAL_StatusTypeDef status = HAL_OK;
762
 
763
  if (pCallback == NULL)
764
  {
765
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
766
 
767
    return HAL_ERROR;
768
  }
769
 
770
  __HAL_LOCK(huart);
771
 
772
  if (huart->gState == HAL_UART_STATE_READY)
773
  {
774
    switch (CallbackID)
775
    {
776
      case HAL_UART_TX_HALFCOMPLETE_CB_ID :
777
        huart->TxHalfCpltCallback = pCallback;
778
        break;
779
 
780
      case HAL_UART_TX_COMPLETE_CB_ID :
781
        huart->TxCpltCallback = pCallback;
782
        break;
783
 
784
      case HAL_UART_RX_HALFCOMPLETE_CB_ID :
785
        huart->RxHalfCpltCallback = pCallback;
786
        break;
787
 
788
      case HAL_UART_RX_COMPLETE_CB_ID :
789
        huart->RxCpltCallback = pCallback;
790
        break;
791
 
792
      case HAL_UART_ERROR_CB_ID :
793
        huart->ErrorCallback = pCallback;
794
        break;
795
 
796
      case HAL_UART_ABORT_COMPLETE_CB_ID :
797
        huart->AbortCpltCallback = pCallback;
798
        break;
799
 
800
      case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
801
        huart->AbortTransmitCpltCallback = pCallback;
802
        break;
803
 
804
      case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
805
        huart->AbortReceiveCpltCallback = pCallback;
806
        break;
807
 
6 mjames 808
#if defined(USART_CR1_UESM)
809
#if defined(USART_CR3_WUFIE)
2 mjames 810
      case HAL_UART_WAKEUP_CB_ID :
811
        huart->WakeupCallback = pCallback;
812
        break;
813
 
6 mjames 814
#endif /* USART_CR3_WUFIE */
815
#endif /* USART_CR1_UESM */
2 mjames 816
 
817
      case HAL_UART_MSPINIT_CB_ID :
818
        huart->MspInitCallback = pCallback;
819
        break;
820
 
821
      case HAL_UART_MSPDEINIT_CB_ID :
822
        huart->MspDeInitCallback = pCallback;
823
        break;
824
 
825
      default :
826
        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
827
 
828
        status =  HAL_ERROR;
829
        break;
830
    }
831
  }
832
  else if (huart->gState == HAL_UART_STATE_RESET)
833
  {
834
    switch (CallbackID)
835
    {
836
      case HAL_UART_MSPINIT_CB_ID :
837
        huart->MspInitCallback = pCallback;
838
        break;
839
 
840
      case HAL_UART_MSPDEINIT_CB_ID :
841
        huart->MspDeInitCallback = pCallback;
842
        break;
843
 
844
      default :
845
        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
846
 
847
        status =  HAL_ERROR;
848
        break;
849
    }
850
  }
851
  else
852
  {
853
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
854
 
855
    status =  HAL_ERROR;
856
  }
857
 
858
  __HAL_UNLOCK(huart);
859
 
860
  return status;
861
}
862
 
863
/**
864
  * @brief  Unregister an UART Callback
865
  *         UART callaback is redirected to the weak predefined callback
866
  * @param  huart uart handle
867
  * @param  CallbackID ID of the callback to be unregistered
868
  *         This parameter can be one of the following values:
869
  *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
870
  *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
871
  *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
872
  *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
873
  *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
874
  *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
875
  *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
876
  *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
877
  *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
878
  *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
879
  *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
880
  * @retval HAL status
881
  */
882
HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
883
{
884
  HAL_StatusTypeDef status = HAL_OK;
885
 
886
  __HAL_LOCK(huart);
887
 
888
  if (HAL_UART_STATE_READY == huart->gState)
889
  {
890
    switch (CallbackID)
891
    {
892
      case HAL_UART_TX_HALFCOMPLETE_CB_ID :
6 mjames 893
        huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback    */
2 mjames 894
        break;
895
 
896
      case HAL_UART_TX_COMPLETE_CB_ID :
6 mjames 897
        huart->TxCpltCallback = HAL_UART_TxCpltCallback;                       /* Legacy weak TxCpltCallback         */
2 mjames 898
        break;
899
 
900
      case HAL_UART_RX_HALFCOMPLETE_CB_ID :
6 mjames 901
        huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback     */
2 mjames 902
        break;
903
 
904
      case HAL_UART_RX_COMPLETE_CB_ID :
6 mjames 905
        huart->RxCpltCallback = HAL_UART_RxCpltCallback;                       /* Legacy weak RxCpltCallback         */
2 mjames 906
        break;
907
 
908
      case HAL_UART_ERROR_CB_ID :
6 mjames 909
        huart->ErrorCallback = HAL_UART_ErrorCallback;                         /* Legacy weak ErrorCallback          */
2 mjames 910
        break;
911
 
912
      case HAL_UART_ABORT_COMPLETE_CB_ID :
6 mjames 913
        huart->AbortCpltCallback = HAL_UART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback      */
2 mjames 914
        break;
915
 
916
      case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
6 mjames 917
        huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak
918
                                                                                  AbortTransmitCpltCallback          */
2 mjames 919
        break;
920
 
921
      case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
6 mjames 922
        huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback;   /* Legacy weak
923
                                                                                  AbortReceiveCpltCallback           */
2 mjames 924
        break;
925
 
926
#if defined(USART_CR1_UESM)
6 mjames 927
#if defined(USART_CR3_WUFIE)
2 mjames 928
      case HAL_UART_WAKEUP_CB_ID :
6 mjames 929
        huart->WakeupCallback = HAL_UARTEx_WakeupCallback;                     /* Legacy weak WakeupCallback         */
2 mjames 930
        break;
931
 
6 mjames 932
#endif /* USART_CR3_WUFIE */
2 mjames 933
#endif /* USART_CR1_UESM */
934
      case HAL_UART_MSPINIT_CB_ID :
6 mjames 935
        huart->MspInitCallback = HAL_UART_MspInit;                             /* Legacy weak MspInitCallback        */
2 mjames 936
        break;
937
 
938
      case HAL_UART_MSPDEINIT_CB_ID :
6 mjames 939
        huart->MspDeInitCallback = HAL_UART_MspDeInit;                         /* Legacy weak MspDeInitCallback      */
2 mjames 940
        break;
941
 
942
      default :
943
        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
944
 
945
        status =  HAL_ERROR;
946
        break;
947
    }
948
  }
949
  else if (HAL_UART_STATE_RESET == huart->gState)
950
  {
951
    switch (CallbackID)
952
    {
953
      case HAL_UART_MSPINIT_CB_ID :
954
        huart->MspInitCallback = HAL_UART_MspInit;
955
        break;
956
 
957
      case HAL_UART_MSPDEINIT_CB_ID :
958
        huart->MspDeInitCallback = HAL_UART_MspDeInit;
959
        break;
960
 
961
      default :
962
        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
963
 
964
        status =  HAL_ERROR;
965
        break;
966
    }
967
  }
968
  else
969
  {
970
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
971
 
972
    status =  HAL_ERROR;
973
  }
974
 
975
  __HAL_UNLOCK(huart);
976
 
977
  return status;
978
}
6 mjames 979
 
980
/**
981
  * @brief  Register a User UART Rx Event Callback
982
  *         To be used instead of the weak predefined callback
983
  * @param  huart     Uart handle
984
  * @param  pCallback Pointer to the Rx Event Callback function
985
  * @retval HAL status
986
  */
987
HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
988
{
989
  HAL_StatusTypeDef status = HAL_OK;
990
 
991
  if (pCallback == NULL)
992
  {
993
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
994
 
995
    return HAL_ERROR;
996
  }
997
 
998
  /* Process locked */
999
  __HAL_LOCK(huart);
1000
 
1001
  if (huart->gState == HAL_UART_STATE_READY)
1002
  {
1003
    huart->RxEventCallback = pCallback;
1004
  }
1005
  else
1006
  {
1007
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
1008
 
1009
    status =  HAL_ERROR;
1010
  }
1011
 
1012
  /* Release Lock */
1013
  __HAL_UNLOCK(huart);
1014
 
1015
  return status;
1016
}
1017
 
1018
/**
1019
  * @brief  UnRegister the UART Rx Event Callback
1020
  *         UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
1021
  * @param  huart     Uart handle
1022
  * @retval HAL status
1023
  */
1024
HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
1025
{
1026
  HAL_StatusTypeDef status = HAL_OK;
1027
 
1028
  /* Process locked */
1029
  __HAL_LOCK(huart);
1030
 
1031
  if (huart->gState == HAL_UART_STATE_READY)
1032
  {
1033
    huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback  */
1034
  }
1035
  else
1036
  {
1037
    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
1038
 
1039
    status =  HAL_ERROR;
1040
  }
1041
 
1042
  /* Release Lock */
1043
  __HAL_UNLOCK(huart);
1044
  return status;
1045
}
1046
 
2 mjames 1047
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1048
 
1049
/**
1050
  * @}
1051
  */
1052
 
1053
/** @defgroup UART_Exported_Functions_Group2 IO operation functions
1054
  * @brief UART Transmit/Receive functions
1055
  *
1056
@verbatim
1057
 ===============================================================================
1058
                      ##### IO operation functions #####
1059
 ===============================================================================
1060
    This subsection provides a set of functions allowing to manage the UART asynchronous
1061
    and Half duplex data transfers.
1062
 
1063
    (#) There are two mode of transfer:
1064
       (+) Blocking mode: The communication is performed in polling mode.
1065
           The HAL status of all data processing is returned by the same function
1066
           after finishing transfer.
1067
       (+) Non-Blocking mode: The communication is performed using Interrupts
1068
           or DMA, These API's return the HAL status.
1069
           The end of the data processing will be indicated through the
1070
           dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
1071
           using DMA mode.
1072
           The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
1073
           will be executed respectively at the end of the transmit or Receive process
1074
           The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
1075
 
1076
    (#) Blocking mode API's are :
1077
        (+) HAL_UART_Transmit()
1078
        (+) HAL_UART_Receive()
1079
 
1080
    (#) Non-Blocking mode API's with Interrupt are :
1081
        (+) HAL_UART_Transmit_IT()
1082
        (+) HAL_UART_Receive_IT()
1083
        (+) HAL_UART_IRQHandler()
1084
 
1085
    (#) Non-Blocking mode API's with DMA are :
1086
        (+) HAL_UART_Transmit_DMA()
1087
        (+) HAL_UART_Receive_DMA()
1088
        (+) HAL_UART_DMAPause()
1089
        (+) HAL_UART_DMAResume()
1090
        (+) HAL_UART_DMAStop()
1091
 
1092
    (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
1093
        (+) HAL_UART_TxHalfCpltCallback()
1094
        (+) HAL_UART_TxCpltCallback()
1095
        (+) HAL_UART_RxHalfCpltCallback()
1096
        (+) HAL_UART_RxCpltCallback()
1097
        (+) HAL_UART_ErrorCallback()
1098
 
1099
    (#) Non-Blocking mode transfers could be aborted using Abort API's :
1100
        (+) HAL_UART_Abort()
1101
        (+) HAL_UART_AbortTransmit()
1102
        (+) HAL_UART_AbortReceive()
1103
        (+) HAL_UART_Abort_IT()
1104
        (+) HAL_UART_AbortTransmit_IT()
1105
        (+) HAL_UART_AbortReceive_IT()
1106
 
1107
    (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1108
        (+) HAL_UART_AbortCpltCallback()
1109
        (+) HAL_UART_AbortTransmitCpltCallback()
1110
        (+) HAL_UART_AbortReceiveCpltCallback()
1111
 
6 mjames 1112
    (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced
1113
        reception services:
1114
        (+) HAL_UARTEx_RxEventCallback()
1115
 
2 mjames 1116
    (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1117
        Errors are handled as follows :
1118
       (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
6 mjames 1119
           to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
1120
           in Interrupt mode reception .
1121
           Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
1122
           to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1123
           Transfer is kept ongoing on UART side.
2 mjames 1124
           If user wants to abort it, Abort services should be called by user.
1125
       (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1126
           This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
6 mjames 1127
           Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
1128
           user callback is executed.
2 mjames 1129
 
1130
    -@- In the Half duplex communication, it is forbidden to run the transmit
1131
        and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1132
 
1133
@endverbatim
1134
  * @{
1135
  */
1136
 
1137
/**
1138
  * @brief Send an amount of data in blocking mode.
1139
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1140
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1141
  *         of u16 provided through pData.
1142
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1143
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1144
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
6 mjames 1145
  *         use of specific alignment compilation directives or pragmas might be required
1146
  *         to ensure proper alignment for pData.
2 mjames 1147
  * @param huart   UART handle.
1148
  * @param pData   Pointer to data buffer (u8 or u16 data elements).
1149
  * @param Size    Amount of data elements (u8 or u16) to be sent.
1150
  * @param Timeout Timeout duration.
1151
  * @retval HAL status
1152
  */
1153
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1154
{
1155
  uint8_t  *pdata8bits;
1156
  uint16_t *pdata16bits;
1157
  uint32_t tickstart;
1158
 
1159
  /* Check that a Tx process is not already ongoing */
1160
  if (huart->gState == HAL_UART_STATE_READY)
1161
  {
1162
    if ((pData == NULL) || (Size == 0U))
1163
    {
1164
      return  HAL_ERROR;
1165
    }
1166
 
1167
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1168
       should be aligned on a u16 frontier, as data to be filled into TDR will be
1169
       handled through a u16 cast. */
1170
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1171
    {
1172
      if ((((uint32_t)pData) & 1U) != 0U)
1173
      {
1174
        return  HAL_ERROR;
1175
      }
1176
    }
1177
 
1178
    __HAL_LOCK(huart);
1179
 
1180
    huart->ErrorCode = HAL_UART_ERROR_NONE;
1181
    huart->gState = HAL_UART_STATE_BUSY_TX;
1182
 
6 mjames 1183
    /* Init tickstart for timeout management */
2 mjames 1184
    tickstart = HAL_GetTick();
1185
 
1186
    huart->TxXferSize  = Size;
1187
    huart->TxXferCount = Size;
1188
 
1189
    /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1190
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1191
    {
1192
      pdata8bits  = NULL;
1193
      pdata16bits = (uint16_t *) pData;
1194
    }
1195
    else
1196
    {
1197
      pdata8bits  = pData;
1198
      pdata16bits = NULL;
1199
    }
1200
 
6 mjames 1201
    __HAL_UNLOCK(huart);
1202
 
2 mjames 1203
    while (huart->TxXferCount > 0U)
1204
    {
1205
      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1206
      {
1207
        return HAL_TIMEOUT;
1208
      }
1209
      if (pdata8bits == NULL)
1210
      {
1211
        huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1212
        pdata16bits++;
1213
      }
1214
      else
1215
      {
1216
        huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1217
        pdata8bits++;
1218
      }
1219
      huart->TxXferCount--;
1220
    }
1221
 
1222
    if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1223
    {
1224
      return HAL_TIMEOUT;
1225
    }
1226
 
1227
    /* At end of Tx process, restore huart->gState to Ready */
1228
    huart->gState = HAL_UART_STATE_READY;
1229
 
1230
    return HAL_OK;
1231
  }
1232
  else
1233
  {
1234
    return HAL_BUSY;
1235
  }
1236
}
1237
 
1238
/**
1239
  * @brief Receive an amount of data in blocking mode.
1240
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1241
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
1242
  *         of u16 available through pData.
1243
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
6 mjames 1244
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier
1245
  *         (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1246
  *         use of specific alignment compilation directives or pragmas might be required
1247
  *         to ensure proper alignment for pData.
2 mjames 1248
  * @param huart   UART handle.
1249
  * @param pData   Pointer to data buffer (u8 or u16 data elements).
1250
  * @param Size    Amount of data elements (u8 or u16) to be received.
1251
  * @param Timeout Timeout duration.
1252
  * @retval HAL status
1253
  */
1254
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1255
{
1256
  uint8_t  *pdata8bits;
1257
  uint16_t *pdata16bits;
1258
  uint16_t uhMask;
1259
  uint32_t tickstart;
1260
 
1261
  /* Check that a Rx process is not already ongoing */
1262
  if (huart->RxState == HAL_UART_STATE_READY)
1263
  {
1264
    if ((pData == NULL) || (Size == 0U))
1265
    {
1266
      return  HAL_ERROR;
1267
    }
1268
 
1269
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1270
       should be aligned on a u16 frontier, as data to be received from RDR will be
1271
       handled through a u16 cast. */
1272
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1273
    {
1274
      if ((((uint32_t)pData) & 1U) != 0U)
1275
      {
1276
        return  HAL_ERROR;
1277
      }
1278
    }
1279
 
1280
    __HAL_LOCK(huart);
1281
 
1282
    huart->ErrorCode = HAL_UART_ERROR_NONE;
1283
    huart->RxState = HAL_UART_STATE_BUSY_RX;
6 mjames 1284
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 1285
 
6 mjames 1286
    /* Init tickstart for timeout management */
2 mjames 1287
    tickstart = HAL_GetTick();
1288
 
1289
    huart->RxXferSize  = Size;
1290
    huart->RxXferCount = Size;
1291
 
1292
    /* Computation of UART mask to apply to RDR register */
1293
    UART_MASK_COMPUTATION(huart);
1294
    uhMask = huart->Mask;
1295
 
1296
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1297
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1298
    {
1299
      pdata8bits  = NULL;
1300
      pdata16bits = (uint16_t *) pData;
1301
    }
1302
    else
1303
    {
1304
      pdata8bits  = pData;
1305
      pdata16bits = NULL;
1306
    }
1307
 
6 mjames 1308
    __HAL_UNLOCK(huart);
1309
 
2 mjames 1310
    /* as long as data have to be received */
1311
    while (huart->RxXferCount > 0U)
1312
    {
1313
      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1314
      {
1315
        return HAL_TIMEOUT;
1316
      }
1317
      if (pdata8bits == NULL)
1318
      {
1319
        *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1320
        pdata16bits++;
1321
      }
1322
      else
1323
      {
1324
        *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1325
        pdata8bits++;
1326
      }
1327
      huart->RxXferCount--;
1328
    }
1329
 
1330
    /* At end of Rx process, restore huart->RxState to Ready */
1331
    huart->RxState = HAL_UART_STATE_READY;
1332
 
1333
    return HAL_OK;
1334
  }
1335
  else
1336
  {
1337
    return HAL_BUSY;
1338
  }
1339
}
1340
 
1341
/**
1342
  * @brief Send an amount of data in interrupt mode.
1343
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1344
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1345
  *         of u16 provided through pData.
1346
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1347
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1348
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
6 mjames 1349
  *         use of specific alignment compilation directives or pragmas might be required
1350
  *         to ensure proper alignment for pData.
2 mjames 1351
  * @param huart UART handle.
1352
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1353
  * @param Size  Amount of data elements (u8 or u16) to be sent.
1354
  * @retval HAL status
1355
  */
1356
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1357
{
1358
  /* Check that a Tx process is not already ongoing */
1359
  if (huart->gState == HAL_UART_STATE_READY)
1360
  {
1361
    if ((pData == NULL) || (Size == 0U))
1362
    {
1363
      return HAL_ERROR;
1364
    }
1365
 
1366
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1367
       should be aligned on a u16 frontier, as data to be filled into TDR will be
1368
       handled through a u16 cast. */
1369
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1370
    {
1371
      if ((((uint32_t)pData) & 1U) != 0U)
1372
      {
1373
        return  HAL_ERROR;
1374
      }
1375
    }
1376
 
1377
    __HAL_LOCK(huart);
1378
 
1379
    huart->pTxBuffPtr  = pData;
1380
    huart->TxXferSize  = Size;
1381
    huart->TxXferCount = Size;
1382
    huart->TxISR       = NULL;
1383
 
1384
    huart->ErrorCode = HAL_UART_ERROR_NONE;
1385
    huart->gState = HAL_UART_STATE_BUSY_TX;
1386
 
1387
    /* Set the Tx ISR function pointer according to the data word length */
1388
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1389
    {
1390
      huart->TxISR = UART_TxISR_16BIT;
1391
    }
1392
    else
1393
    {
1394
      huart->TxISR = UART_TxISR_8BIT;
1395
    }
1396
 
1397
    __HAL_UNLOCK(huart);
1398
 
1399
    /* Enable the Transmit Data Register Empty interrupt */
6 mjames 1400
    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
2 mjames 1401
 
1402
    return HAL_OK;
1403
  }
1404
  else
1405
  {
1406
    return HAL_BUSY;
1407
  }
1408
}
1409
 
1410
/**
1411
  * @brief Receive an amount of data in interrupt mode.
1412
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1413
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
1414
  *         of u16 available through pData.
1415
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
6 mjames 1416
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier
1417
  *         (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1418
  *         use of specific alignment compilation directives or pragmas might be required
1419
  *         to ensure proper alignment for pData.
2 mjames 1420
  * @param huart UART handle.
1421
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1422
  * @param Size  Amount of data elements (u8 or u16) to be received.
1423
  * @retval HAL status
1424
  */
1425
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1426
{
1427
  /* Check that a Rx process is not already ongoing */
1428
  if (huart->RxState == HAL_UART_STATE_READY)
1429
  {
1430
    if ((pData == NULL) || (Size == 0U))
1431
    {
1432
      return HAL_ERROR;
1433
    }
1434
 
1435
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1436
       should be aligned on a u16 frontier, as data to be received from RDR will be
1437
       handled through a u16 cast. */
1438
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1439
    {
1440
      if ((((uint32_t)pData) & 1U) != 0U)
1441
      {
1442
        return  HAL_ERROR;
1443
      }
1444
    }
1445
 
1446
    __HAL_LOCK(huart);
1447
 
6 mjames 1448
    /* Set Reception type to Standard reception */
1449
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 1450
 
6 mjames 1451
    /* Check that USART RTOEN bit is set */
1452
    if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
2 mjames 1453
    {
6 mjames 1454
      /* Enable the UART Receiver Timeout Interrupt */
1455
      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
2 mjames 1456
    }
1457
 
6 mjames 1458
    return (UART_Start_Receive_IT(huart, pData, Size));
2 mjames 1459
  }
1460
  else
1461
  {
1462
    return HAL_BUSY;
1463
  }
1464
}
1465
 
1466
/**
1467
  * @brief Send an amount of data in DMA mode.
1468
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1469
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1470
  *         of u16 provided through pData.
1471
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1472
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1473
  *         (as sent data will be handled by DMA from halfword frontier). Depending on compilation chain,
6 mjames 1474
  *         use of specific alignment compilation directives or pragmas might be required
1475
  *         to ensure proper alignment for pData.
2 mjames 1476
  * @param huart UART handle.
1477
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1478
  * @param Size  Amount of data elements (u8 or u16) to be sent.
1479
  * @retval HAL status
1480
  */
1481
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1482
{
1483
  /* Check that a Tx process is not already ongoing */
1484
  if (huart->gState == HAL_UART_STATE_READY)
1485
  {
1486
    if ((pData == NULL) || (Size == 0U))
1487
    {
1488
      return HAL_ERROR;
1489
    }
1490
 
1491
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1492
       should be aligned on a u16 frontier, as data copy into TDR will be
1493
       handled by DMA from a u16 frontier. */
1494
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1495
    {
1496
      if ((((uint32_t)pData) & 1U) != 0U)
1497
      {
1498
        return  HAL_ERROR;
1499
      }
1500
    }
1501
 
1502
    __HAL_LOCK(huart);
1503
 
1504
    huart->pTxBuffPtr  = pData;
1505
    huart->TxXferSize  = Size;
1506
    huart->TxXferCount = Size;
1507
 
1508
    huart->ErrorCode = HAL_UART_ERROR_NONE;
1509
    huart->gState = HAL_UART_STATE_BUSY_TX;
1510
 
1511
    if (huart->hdmatx != NULL)
1512
    {
1513
      /* Set the UART DMA transfer complete callback */
1514
      huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1515
 
1516
      /* Set the UART DMA Half transfer complete callback */
1517
      huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1518
 
1519
      /* Set the DMA error callback */
1520
      huart->hdmatx->XferErrorCallback = UART_DMAError;
1521
 
1522
      /* Set the DMA abort callback */
1523
      huart->hdmatx->XferAbortCallback = NULL;
1524
 
1525
      /* Enable the UART transmit DMA channel */
1526
      if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
1527
      {
1528
        /* Set error code to DMA */
1529
        huart->ErrorCode = HAL_UART_ERROR_DMA;
1530
 
1531
        __HAL_UNLOCK(huart);
1532
 
1533
        /* Restore huart->gState to ready */
1534
        huart->gState = HAL_UART_STATE_READY;
1535
 
1536
        return HAL_ERROR;
1537
      }
1538
    }
1539
    /* Clear the TC flag in the ICR register */
1540
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1541
 
1542
    __HAL_UNLOCK(huart);
1543
 
1544
    /* Enable the DMA transfer for transmit request by setting the DMAT bit
1545
    in the UART CR3 register */
6 mjames 1546
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1547
 
1548
    return HAL_OK;
1549
  }
1550
  else
1551
  {
1552
    return HAL_BUSY;
1553
  }
1554
}
1555
 
1556
/**
1557
  * @brief Receive an amount of data in DMA mode.
1558
  * @note   When the UART parity is enabled (PCE = 1), the received data contain
1559
  *         the parity bit (MSB position).
1560
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1561
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
1562
  *         of u16 available through pData.
1563
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
6 mjames 1564
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier
1565
  *         (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1566
  *         use of specific alignment compilation directives or pragmas might be required
1567
  *         to ensure proper alignment for pData.
2 mjames 1568
  * @param huart UART handle.
1569
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1570
  * @param Size  Amount of data elements (u8 or u16) to be received.
1571
  * @retval HAL status
1572
  */
1573
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1574
{
1575
  /* Check that a Rx process is not already ongoing */
1576
  if (huart->RxState == HAL_UART_STATE_READY)
1577
  {
1578
    if ((pData == NULL) || (Size == 0U))
1579
    {
1580
      return HAL_ERROR;
1581
    }
1582
 
1583
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1584
       should be aligned on a u16 frontier, as data copy from RDR will be
1585
       handled by DMA from a u16 frontier. */
1586
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1587
    {
1588
      if ((((uint32_t)pData) & 1U) != 0U)
1589
      {
1590
        return  HAL_ERROR;
1591
      }
1592
    }
1593
 
1594
    __HAL_LOCK(huart);
1595
 
6 mjames 1596
    /* Set Reception type to Standard reception */
1597
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 1598
 
6 mjames 1599
    /* Check that USART RTOEN bit is set */
1600
    if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
2 mjames 1601
    {
6 mjames 1602
      /* Enable the UART Receiver Timeout Interrupt */
1603
      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
2 mjames 1604
    }
1605
 
6 mjames 1606
    return (UART_Start_Receive_DMA(huart, pData, Size));
2 mjames 1607
  }
1608
  else
1609
  {
1610
    return HAL_BUSY;
1611
  }
1612
}
1613
 
1614
/**
1615
  * @brief Pause the DMA Transfer.
1616
  * @param huart UART handle.
1617
  * @retval HAL status
1618
  */
1619
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1620
{
1621
  const HAL_UART_StateTypeDef gstate = huart->gState;
1622
  const HAL_UART_StateTypeDef rxstate = huart->RxState;
1623
 
1624
  __HAL_LOCK(huart);
1625
 
1626
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1627
      (gstate == HAL_UART_STATE_BUSY_TX))
1628
  {
1629
    /* Disable the UART DMA Tx request */
6 mjames 1630
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1631
  }
1632
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1633
      (rxstate == HAL_UART_STATE_BUSY_RX))
1634
  {
1635
    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 1636
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1637
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 1638
 
1639
    /* Disable the UART DMA Rx request */
6 mjames 1640
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 1641
  }
1642
 
1643
  __HAL_UNLOCK(huart);
1644
 
1645
  return HAL_OK;
1646
}
1647
 
1648
/**
1649
  * @brief Resume the DMA Transfer.
1650
  * @param huart UART handle.
1651
  * @retval HAL status
1652
  */
1653
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1654
{
1655
  __HAL_LOCK(huart);
1656
 
1657
  if (huart->gState == HAL_UART_STATE_BUSY_TX)
1658
  {
1659
    /* Enable the UART DMA Tx request */
6 mjames 1660
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1661
  }
1662
  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1663
  {
1664
    /* Clear the Overrun flag before resuming the Rx transfer */
1665
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1666
 
6 mjames 1667
    /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1668
    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1669
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 1670
 
1671
    /* Enable the UART DMA Rx request */
6 mjames 1672
    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 1673
  }
1674
 
1675
  __HAL_UNLOCK(huart);
1676
 
1677
  return HAL_OK;
1678
}
1679
 
1680
/**
1681
  * @brief Stop the DMA Transfer.
1682
  * @param huart UART handle.
1683
  * @retval HAL status
1684
  */
1685
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1686
{
1687
  /* The Lock is not implemented on this API to allow the user application
1688
     to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1689
     HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1690
     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1691
     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1692
     the stream and the corresponding call back is executed. */
1693
 
1694
  const HAL_UART_StateTypeDef gstate = huart->gState;
1695
  const HAL_UART_StateTypeDef rxstate = huart->RxState;
1696
 
1697
  /* Stop UART DMA Tx request if ongoing */
1698
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1699
      (gstate == HAL_UART_STATE_BUSY_TX))
1700
  {
6 mjames 1701
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1702
 
1703
    /* Abort the UART DMA Tx channel */
1704
    if (huart->hdmatx != NULL)
1705
    {
1706
      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1707
      {
1708
        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1709
        {
1710
          /* Set error code to DMA */
1711
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1712
 
1713
          return HAL_TIMEOUT;
1714
        }
1715
      }
1716
    }
1717
 
1718
    UART_EndTxTransfer(huart);
1719
  }
1720
 
1721
  /* Stop UART DMA Rx request if ongoing */
1722
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1723
      (rxstate == HAL_UART_STATE_BUSY_RX))
1724
  {
6 mjames 1725
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 1726
 
1727
    /* Abort the UART DMA Rx channel */
1728
    if (huart->hdmarx != NULL)
1729
    {
1730
      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1731
      {
1732
        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1733
        {
1734
          /* Set error code to DMA */
1735
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1736
 
1737
          return HAL_TIMEOUT;
1738
        }
1739
      }
1740
    }
1741
 
1742
    UART_EndRxTransfer(huart);
1743
  }
1744
 
1745
  return HAL_OK;
1746
}
1747
 
1748
/**
1749
  * @brief  Abort ongoing transfers (blocking mode).
1750
  * @param  huart UART handle.
1751
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1752
  *         This procedure performs following operations :
1753
  *           - Disable UART Interrupts (Tx and Rx)
1754
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1755
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1756
  *           - Set handle State to READY
1757
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1758
  * @retval HAL status
1759
  */
1760
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1761
{
1762
  /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 1763
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1764
  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 1765
 
6 mjames 1766
  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1767
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1768
  {
1769
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1770
  }
1771
 
2 mjames 1772
  /* Disable the UART DMA Tx request if enabled */
1773
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1774
  {
6 mjames 1775
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1776
 
1777
    /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1778
    if (huart->hdmatx != NULL)
1779
    {
1780
      /* Set the UART DMA Abort callback to Null.
1781
         No call back execution at end of DMA abort procedure */
1782
      huart->hdmatx->XferAbortCallback = NULL;
1783
 
1784
      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1785
      {
1786
        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1787
        {
1788
          /* Set error code to DMA */
1789
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1790
 
1791
          return HAL_TIMEOUT;
1792
        }
1793
      }
1794
    }
1795
  }
1796
 
1797
  /* Disable the UART DMA Rx request if enabled */
1798
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1799
  {
6 mjames 1800
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 1801
 
1802
    /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1803
    if (huart->hdmarx != NULL)
1804
    {
1805
      /* Set the UART DMA Abort callback to Null.
1806
         No call back execution at end of DMA abort procedure */
1807
      huart->hdmarx->XferAbortCallback = NULL;
1808
 
1809
      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1810
      {
1811
        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1812
        {
1813
          /* Set error code to DMA */
1814
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1815
 
1816
          return HAL_TIMEOUT;
1817
        }
1818
      }
1819
    }
1820
  }
1821
 
1822
  /* Reset Tx and Rx transfer counters */
1823
  huart->TxXferCount = 0U;
1824
  huart->RxXferCount = 0U;
1825
 
1826
  /* Clear the Error flags in the ICR register */
1827
  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1828
 
1829
 
1830
  /* Discard the received data */
1831
  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1832
 
1833
  /* Restore huart->gState and huart->RxState to Ready */
1834
  huart->gState  = HAL_UART_STATE_READY;
1835
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 1836
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 1837
 
1838
  huart->ErrorCode = HAL_UART_ERROR_NONE;
1839
 
1840
  return HAL_OK;
1841
}
1842
 
1843
/**
1844
  * @brief  Abort ongoing Transmit transfer (blocking mode).
1845
  * @param  huart UART handle.
1846
  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1847
  *         This procedure performs following operations :
1848
  *           - Disable UART Interrupts (Tx)
1849
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1850
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1851
  *           - Set handle State to READY
1852
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1853
  * @retval HAL status
1854
  */
1855
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1856
{
1857
  /* Disable TXEIE and TCIE interrupts */
6 mjames 1858
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2 mjames 1859
 
1860
  /* Disable the UART DMA Tx request if enabled */
1861
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1862
  {
6 mjames 1863
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 1864
 
1865
    /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1866
    if (huart->hdmatx != NULL)
1867
    {
1868
      /* Set the UART DMA Abort callback to Null.
1869
         No call back execution at end of DMA abort procedure */
1870
      huart->hdmatx->XferAbortCallback = NULL;
1871
 
1872
      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1873
      {
1874
        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1875
        {
1876
          /* Set error code to DMA */
1877
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1878
 
1879
          return HAL_TIMEOUT;
1880
        }
1881
      }
1882
    }
1883
  }
1884
 
1885
  /* Reset Tx transfer counter */
1886
  huart->TxXferCount = 0U;
1887
 
1888
 
1889
  /* Restore huart->gState to Ready */
1890
  huart->gState = HAL_UART_STATE_READY;
1891
 
1892
  return HAL_OK;
1893
}
1894
 
1895
/**
1896
  * @brief  Abort ongoing Receive transfer (blocking mode).
1897
  * @param  huart UART handle.
1898
  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1899
  *         This procedure performs following operations :
1900
  *           - Disable UART Interrupts (Rx)
1901
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1902
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1903
  *           - Set handle State to READY
1904
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1905
  * @retval HAL status
1906
  */
1907
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1908
{
1909
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 1910
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1911
  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 1912
 
6 mjames 1913
  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1914
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1915
  {
1916
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1917
  }
1918
 
2 mjames 1919
  /* Disable the UART DMA Rx request if enabled */
1920
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1921
  {
6 mjames 1922
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 1923
 
1924
    /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1925
    if (huart->hdmarx != NULL)
1926
    {
1927
      /* Set the UART DMA Abort callback to Null.
1928
         No call back execution at end of DMA abort procedure */
1929
      huart->hdmarx->XferAbortCallback = NULL;
1930
 
1931
      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1932
      {
1933
        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1934
        {
1935
          /* Set error code to DMA */
1936
          huart->ErrorCode = HAL_UART_ERROR_DMA;
1937
 
1938
          return HAL_TIMEOUT;
1939
        }
1940
      }
1941
    }
1942
  }
1943
 
1944
  /* Reset Rx transfer counter */
1945
  huart->RxXferCount = 0U;
1946
 
1947
  /* Clear the Error flags in the ICR register */
1948
  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1949
 
1950
  /* Discard the received data */
1951
  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1952
 
1953
  /* Restore huart->RxState to Ready */
1954
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 1955
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 1956
 
1957
  return HAL_OK;
1958
}
1959
 
1960
/**
1961
  * @brief  Abort ongoing transfers (Interrupt mode).
1962
  * @param  huart UART handle.
1963
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1964
  *         This procedure performs following operations :
1965
  *           - Disable UART Interrupts (Tx and Rx)
1966
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1967
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1968
  *           - Set handle State to READY
1969
  *           - At abort completion, call user abort complete callback
1970
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1971
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
1972
  * @retval HAL status
1973
  */
1974
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1975
{
1976
  uint32_t abortcplt = 1U;
1977
 
1978
  /* Disable interrupts */
6 mjames 1979
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1980
  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 1981
 
6 mjames 1982
  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1983
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1984
  {
1985
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1986
  }
1987
 
2 mjames 1988
  /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1989
     before any call to DMA Abort functions */
1990
  /* DMA Tx Handle is valid */
1991
  if (huart->hdmatx != NULL)
1992
  {
1993
    /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
1994
       Otherwise, set it to NULL */
1995
    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1996
    {
1997
      huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
1998
    }
1999
    else
2000
    {
2001
      huart->hdmatx->XferAbortCallback = NULL;
2002
    }
2003
  }
2004
  /* DMA Rx Handle is valid */
2005
  if (huart->hdmarx != NULL)
2006
  {
2007
    /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
2008
       Otherwise, set it to NULL */
2009
    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2010
    {
2011
      huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
2012
    }
2013
    else
2014
    {
2015
      huart->hdmarx->XferAbortCallback = NULL;
2016
    }
2017
  }
2018
 
2019
  /* Disable the UART DMA Tx request if enabled */
2020
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2021
  {
2022
    /* Disable DMA Tx at UART level */
6 mjames 2023
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 2024
 
2025
    /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2026
    if (huart->hdmatx != NULL)
2027
    {
2028
      /* UART Tx DMA Abort callback has already been initialised :
2029
         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2030
 
2031
      /* Abort DMA TX */
2032
      if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2033
      {
2034
        huart->hdmatx->XferAbortCallback = NULL;
2035
      }
2036
      else
2037
      {
2038
        abortcplt = 0U;
2039
      }
2040
    }
2041
  }
2042
 
2043
  /* Disable the UART DMA Rx request if enabled */
2044
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2045
  {
6 mjames 2046
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 2047
 
2048
    /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2049
    if (huart->hdmarx != NULL)
2050
    {
2051
      /* UART Rx DMA Abort callback has already been initialised :
2052
         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2053
 
2054
      /* Abort DMA RX */
2055
      if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2056
      {
2057
        huart->hdmarx->XferAbortCallback = NULL;
2058
        abortcplt = 1U;
2059
      }
2060
      else
2061
      {
2062
        abortcplt = 0U;
2063
      }
2064
    }
2065
  }
2066
 
2067
  /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2068
  if (abortcplt == 1U)
2069
  {
2070
    /* Reset Tx and Rx transfer counters */
2071
    huart->TxXferCount = 0U;
2072
    huart->RxXferCount = 0U;
2073
 
2074
    /* Clear ISR function pointers */
2075
    huart->RxISR = NULL;
2076
    huart->TxISR = NULL;
2077
 
2078
    /* Reset errorCode */
2079
    huart->ErrorCode = HAL_UART_ERROR_NONE;
2080
 
2081
    /* Clear the Error flags in the ICR register */
2082
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2083
 
2084
 
2085
    /* Discard the received data */
2086
    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2087
 
2088
    /* Restore huart->gState and huart->RxState to Ready */
2089
    huart->gState  = HAL_UART_STATE_READY;
2090
    huart->RxState = HAL_UART_STATE_READY;
6 mjames 2091
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 2092
 
2093
    /* As no DMA to be aborted, call directly user Abort complete callback */
2094
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2095
    /* Call registered Abort complete callback */
2096
    huart->AbortCpltCallback(huart);
2097
#else
2098
    /* Call legacy weak Abort complete callback */
2099
    HAL_UART_AbortCpltCallback(huart);
2100
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2101
  }
2102
 
2103
  return HAL_OK;
2104
}
2105
 
2106
/**
2107
  * @brief  Abort ongoing Transmit transfer (Interrupt mode).
2108
  * @param  huart UART handle.
2109
  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
2110
  *         This procedure performs following operations :
2111
  *           - Disable UART Interrupts (Tx)
2112
  *           - Disable the DMA transfer in the peripheral register (if enabled)
2113
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2114
  *           - Set handle State to READY
2115
  *           - At abort completion, call user abort complete callback
2116
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
2117
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
2118
  * @retval HAL status
2119
  */
2120
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2121
{
2122
  /* Disable interrupts */
6 mjames 2123
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2 mjames 2124
 
2125
  /* Disable the UART DMA Tx request if enabled */
2126
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2127
  {
6 mjames 2128
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 2129
 
2130
    /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2131
    if (huart->hdmatx != NULL)
2132
    {
2133
      /* Set the UART DMA Abort callback :
2134
         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2135
      huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2136
 
2137
      /* Abort DMA TX */
2138
      if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2139
      {
2140
        /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2141
        huart->hdmatx->XferAbortCallback(huart->hdmatx);
2142
      }
2143
    }
2144
    else
2145
    {
2146
      /* Reset Tx transfer counter */
2147
      huart->TxXferCount = 0U;
2148
 
2149
      /* Clear TxISR function pointers */
2150
      huart->TxISR = NULL;
2151
 
2152
      /* Restore huart->gState to Ready */
2153
      huart->gState = HAL_UART_STATE_READY;
2154
 
2155
      /* As no DMA to be aborted, call directly user Abort complete callback */
2156
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2157
      /* Call registered Abort Transmit Complete Callback */
2158
      huart->AbortTransmitCpltCallback(huart);
2159
#else
2160
      /* Call legacy weak Abort Transmit Complete Callback */
2161
      HAL_UART_AbortTransmitCpltCallback(huart);
2162
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2163
    }
2164
  }
2165
  else
2166
  {
2167
    /* Reset Tx transfer counter */
2168
    huart->TxXferCount = 0U;
2169
 
2170
    /* Clear TxISR function pointers */
2171
    huart->TxISR = NULL;
2172
 
2173
 
2174
    /* Restore huart->gState to Ready */
2175
    huart->gState = HAL_UART_STATE_READY;
2176
 
2177
    /* As no DMA to be aborted, call directly user Abort complete callback */
2178
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2179
    /* Call registered Abort Transmit Complete Callback */
2180
    huart->AbortTransmitCpltCallback(huart);
2181
#else
2182
    /* Call legacy weak Abort Transmit Complete Callback */
2183
    HAL_UART_AbortTransmitCpltCallback(huart);
2184
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2185
  }
2186
 
2187
  return HAL_OK;
2188
}
2189
 
2190
/**
2191
  * @brief  Abort ongoing Receive transfer (Interrupt mode).
2192
  * @param  huart UART handle.
2193
  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2194
  *         This procedure performs following operations :
2195
  *           - Disable UART Interrupts (Rx)
2196
  *           - Disable the DMA transfer in the peripheral register (if enabled)
2197
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2198
  *           - Set handle State to READY
2199
  *           - At abort completion, call user abort complete callback
2200
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
2201
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
2202
  * @retval HAL status
2203
  */
2204
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2205
{
2206
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 2207
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2208
  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 2209
 
6 mjames 2210
  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
2211
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2212
  {
2213
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
2214
  }
2215
 
2 mjames 2216
  /* Disable the UART DMA Rx request if enabled */
2217
  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2218
  {
6 mjames 2219
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 2220
 
2221
    /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2222
    if (huart->hdmarx != NULL)
2223
    {
2224
      /* Set the UART DMA Abort callback :
2225
         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2226
      huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2227
 
2228
      /* Abort DMA RX */
2229
      if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2230
      {
2231
        /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2232
        huart->hdmarx->XferAbortCallback(huart->hdmarx);
2233
      }
2234
    }
2235
    else
2236
    {
2237
      /* Reset Rx transfer counter */
2238
      huart->RxXferCount = 0U;
2239
 
2240
      /* Clear RxISR function pointer */
2241
      huart->pRxBuffPtr = NULL;
2242
 
2243
      /* Clear the Error flags in the ICR register */
2244
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2245
 
2246
      /* Discard the received data */
2247
      __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2248
 
2249
      /* Restore huart->RxState to Ready */
2250
      huart->RxState = HAL_UART_STATE_READY;
6 mjames 2251
      huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 2252
 
2253
      /* As no DMA to be aborted, call directly user Abort complete callback */
2254
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2255
      /* Call registered Abort Receive Complete Callback */
2256
      huart->AbortReceiveCpltCallback(huart);
2257
#else
2258
      /* Call legacy weak Abort Receive Complete Callback */
2259
      HAL_UART_AbortReceiveCpltCallback(huart);
2260
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2261
    }
2262
  }
2263
  else
2264
  {
2265
    /* Reset Rx transfer counter */
2266
    huart->RxXferCount = 0U;
2267
 
2268
    /* Clear RxISR function pointer */
2269
    huart->pRxBuffPtr = NULL;
2270
 
2271
    /* Clear the Error flags in the ICR register */
2272
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2273
 
2274
    /* Restore huart->RxState to Ready */
2275
    huart->RxState = HAL_UART_STATE_READY;
6 mjames 2276
    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 2277
 
2278
    /* As no DMA to be aborted, call directly user Abort complete callback */
2279
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2280
    /* Call registered Abort Receive Complete Callback */
2281
    huart->AbortReceiveCpltCallback(huart);
2282
#else
2283
    /* Call legacy weak Abort Receive Complete Callback */
2284
    HAL_UART_AbortReceiveCpltCallback(huart);
2285
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2286
  }
2287
 
2288
  return HAL_OK;
2289
}
2290
 
2291
/**
2292
  * @brief Handle UART interrupt request.
2293
  * @param huart UART handle.
2294
  * @retval None
2295
  */
2296
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2297
{
2298
  uint32_t isrflags   = READ_REG(huart->Instance->ISR);
2299
  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
2300
  uint32_t cr3its     = READ_REG(huart->Instance->CR3);
2301
 
2302
  uint32_t errorflags;
2303
  uint32_t errorcode;
2304
 
2305
  /* If no error occurs */
2306
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2307
  if (errorflags == 0U)
2308
  {
2309
    /* UART in mode Receiver ---------------------------------------------------*/
2310
    if (((isrflags & USART_ISR_RXNE) != 0U)
2311
        && ((cr1its & USART_CR1_RXNEIE) != 0U))
2312
    {
2313
      if (huart->RxISR != NULL)
2314
      {
2315
        huart->RxISR(huart);
2316
      }
2317
      return;
2318
    }
2319
  }
2320
 
2321
  /* If some errors occur */
2322
  if ((errorflags != 0U)
2323
      && (((cr3its & USART_CR3_EIE) != 0U)
6 mjames 2324
          || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U)))
2 mjames 2325
  {
2326
    /* UART parity error interrupt occurred -------------------------------------*/
2327
    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2328
    {
2329
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2330
 
2331
      huart->ErrorCode |= HAL_UART_ERROR_PE;
2332
    }
2333
 
2334
    /* UART frame error interrupt occurred --------------------------------------*/
2335
    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2336
    {
2337
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2338
 
2339
      huart->ErrorCode |= HAL_UART_ERROR_FE;
2340
    }
2341
 
2342
    /* UART noise error interrupt occurred --------------------------------------*/
2343
    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2344
    {
2345
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2346
 
2347
      huart->ErrorCode |= HAL_UART_ERROR_NE;
2348
    }
2349
 
2350
    /* UART Over-Run interrupt occurred -----------------------------------------*/
2351
    if (((isrflags & USART_ISR_ORE) != 0U)
2352
        && (((cr1its & USART_CR1_RXNEIE) != 0U) ||
2353
            ((cr3its & USART_CR3_EIE) != 0U)))
2354
    {
2355
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2356
 
2357
      huart->ErrorCode |= HAL_UART_ERROR_ORE;
2358
    }
2359
 
2360
    /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2361
    if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2362
    {
2363
      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2364
 
2365
      huart->ErrorCode |= HAL_UART_ERROR_RTO;
2366
    }
2367
 
2368
    /* Call UART Error Call back function if need be ----------------------------*/
2369
    if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2370
    {
2371
      /* UART in mode Receiver --------------------------------------------------*/
2372
      if (((isrflags & USART_ISR_RXNE) != 0U)
2373
          && ((cr1its & USART_CR1_RXNEIE) != 0U))
2374
      {
2375
        if (huart->RxISR != NULL)
2376
        {
2377
          huart->RxISR(huart);
2378
        }
2379
      }
2380
 
2381
      /* If Error is to be considered as blocking :
2382
          - Receiver Timeout error in Reception
2383
          - Overrun error in Reception
2384
          - any error occurs in DMA mode reception
2385
      */
2386
      errorcode = huart->ErrorCode;
2387
      if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2388
          ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2389
      {
2390
        /* Blocking error : transfer is aborted
2391
           Set the UART state ready to be able to start again the process,
2392
           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2393
        UART_EndRxTransfer(huart);
2394
 
2395
        /* Disable the UART DMA Rx request if enabled */
2396
        if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2397
        {
6 mjames 2398
          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 2399
 
2400
          /* Abort the UART DMA Rx channel */
2401
          if (huart->hdmarx != NULL)
2402
          {
2403
            /* Set the UART DMA Abort callback :
2404
               will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2405
            huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2406
 
2407
            /* Abort DMA RX */
2408
            if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2409
            {
2410
              /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2411
              huart->hdmarx->XferAbortCallback(huart->hdmarx);
2412
            }
2413
          }
2414
          else
2415
          {
2416
            /* Call user error callback */
2417
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2418
            /*Call registered error callback*/
2419
            huart->ErrorCallback(huart);
2420
#else
2421
            /*Call legacy weak error callback*/
2422
            HAL_UART_ErrorCallback(huart);
2423
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2424
 
2425
          }
2426
        }
2427
        else
2428
        {
2429
          /* Call user error callback */
2430
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2431
          /*Call registered error callback*/
2432
          huart->ErrorCallback(huart);
2433
#else
2434
          /*Call legacy weak error callback*/
2435
          HAL_UART_ErrorCallback(huart);
2436
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2437
        }
2438
      }
2439
      else
2440
      {
2441
        /* Non Blocking error : transfer could go on.
2442
           Error is notified to user through user error callback */
2443
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2444
        /*Call registered error callback*/
2445
        huart->ErrorCallback(huart);
2446
#else
2447
        /*Call legacy weak error callback*/
2448
        HAL_UART_ErrorCallback(huart);
2449
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2450
        huart->ErrorCode = HAL_UART_ERROR_NONE;
2451
      }
2452
    }
2453
    return;
2454
 
2455
  } /* End if some error occurs */
6 mjames 2456
 
2457
  /* Check current reception Mode :
2458
     If Reception till IDLE event has been selected : */
2459
  if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2460
      && ((isrflags & USART_ISR_IDLE) != 0U)
2461
      && ((cr1its & USART_ISR_IDLE) != 0U))
2462
  {
2463
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
2464
 
2465
    /* Check if DMA mode is enabled in UART */
2466
    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2467
    {
2468
      /* DMA mode enabled */
2469
      /* Check received length : If all expected data are received, do nothing,
2470
         (DMA cplt callback will be called).
2471
         Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2472
      uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
2473
      if ((nb_remaining_rx_data > 0U)
2474
          && (nb_remaining_rx_data < huart->RxXferSize))
2475
      {
2476
        /* Reception is not complete */
2477
        huart->RxXferCount = nb_remaining_rx_data;
2478
 
2479
        /* In Normal mode, end DMA xfer and HAL UART Rx process*/
2480
        if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
2481
        {
2482
          /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2483
          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
2484
          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2485
 
2486
          /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2487
             in the UART CR3 register */
2488
          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2489
 
2490
          /* At end of Rx process, restore huart->RxState to Ready */
2491
          huart->RxState = HAL_UART_STATE_READY;
2492
          huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2493
 
2494
          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2495
 
2496
          /* Last bytes received, so no need as the abort is immediate */
2497
          (void)HAL_DMA_Abort(huart->hdmarx);
2498
        }
2499
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2500
        /*Call registered Rx Event callback*/
2501
        huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2502
#else
2503
        /*Call legacy weak Rx Event callback*/
2504
        HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2505
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2506
      }
2507
      return;
2508
    }
2509
    else
2510
    {
2511
      /* DMA mode not enabled */
2512
      /* Check received length : If all expected data are received, do nothing.
2513
         Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2514
      uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
2515
      if ((huart->RxXferCount > 0U)
2516
          && (nb_rx_data > 0U))
2517
      {
2518
        /* Disable the UART Parity Error Interrupt and RXNE interrupts */
2519
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2520
 
2521
        /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
2522
        ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2523
 
2524
        /* Rx process is completed, restore huart->RxState to Ready */
2525
        huart->RxState = HAL_UART_STATE_READY;
2526
        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2527
 
2528
        /* Clear RxISR function pointer */
2529
        huart->RxISR = NULL;
2530
 
2531
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2532
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2533
        /*Call registered Rx complete callback*/
2534
        huart->RxEventCallback(huart, nb_rx_data);
2535
#else
2536
        /*Call legacy weak Rx Event callback*/
2537
        HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
2538
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2539
      }
2540
      return;
2541
    }
2542
  }
2 mjames 2543
#if defined(USART_CR1_UESM)
6 mjames 2544
#if defined(USART_CR3_WUFIE)
2 mjames 2545
 
2546
  /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2547
  if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2548
  {
2549
    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2550
 
2551
    /* UART Rx state is not reset as a reception process might be ongoing.
2552
       If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2553
 
2554
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2555
    /* Call registered Wakeup Callback */
2556
    huart->WakeupCallback(huart);
2557
#else
2558
    /* Call legacy weak Wakeup Callback */
2559
    HAL_UARTEx_WakeupCallback(huart);
2560
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2561
    return;
2562
  }
6 mjames 2563
#endif /* USART_CR3_WUFIE */
2 mjames 2564
#endif /* USART_CR1_UESM */
2565
 
2566
  /* UART in mode Transmitter ------------------------------------------------*/
2567
  if (((isrflags & USART_ISR_TXE) != 0U)
2568
      && ((cr1its & USART_CR1_TXEIE) != 0U))
2569
  {
2570
    if (huart->TxISR != NULL)
2571
    {
2572
      huart->TxISR(huart);
2573
    }
2574
    return;
2575
  }
2576
 
2577
  /* UART in mode Transmitter (transmission end) -----------------------------*/
2578
  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2579
  {
2580
    UART_EndTransmit_IT(huart);
2581
    return;
2582
  }
2583
 
2584
}
2585
 
2586
/**
2587
  * @brief Tx Transfer completed callback.
2588
  * @param huart UART handle.
2589
  * @retval None
2590
  */
2591
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2592
{
2593
  /* Prevent unused argument(s) compilation warning */
2594
  UNUSED(huart);
2595
 
2596
  /* NOTE : This function should not be modified, when the callback is needed,
2597
            the HAL_UART_TxCpltCallback can be implemented in the user file.
2598
   */
2599
}
2600
 
2601
/**
2602
  * @brief  Tx Half Transfer completed callback.
2603
  * @param  huart UART handle.
2604
  * @retval None
2605
  */
2606
__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2607
{
2608
  /* Prevent unused argument(s) compilation warning */
2609
  UNUSED(huart);
2610
 
2611
  /* NOTE: This function should not be modified, when the callback is needed,
2612
           the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2613
   */
2614
}
2615
 
2616
/**
2617
  * @brief  Rx Transfer completed callback.
2618
  * @param  huart UART handle.
2619
  * @retval None
2620
  */
2621
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2622
{
2623
  /* Prevent unused argument(s) compilation warning */
2624
  UNUSED(huart);
2625
 
2626
  /* NOTE : This function should not be modified, when the callback is needed,
2627
            the HAL_UART_RxCpltCallback can be implemented in the user file.
2628
   */
2629
}
2630
 
2631
/**
2632
  * @brief  Rx Half Transfer completed callback.
2633
  * @param  huart UART handle.
2634
  * @retval None
2635
  */
2636
__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2637
{
2638
  /* Prevent unused argument(s) compilation warning */
2639
  UNUSED(huart);
2640
 
2641
  /* NOTE: This function should not be modified, when the callback is needed,
2642
           the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2643
   */
2644
}
2645
 
2646
/**
2647
  * @brief  UART error callback.
2648
  * @param  huart UART handle.
2649
  * @retval None
2650
  */
2651
__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2652
{
2653
  /* Prevent unused argument(s) compilation warning */
2654
  UNUSED(huart);
2655
 
2656
  /* NOTE : This function should not be modified, when the callback is needed,
2657
            the HAL_UART_ErrorCallback can be implemented in the user file.
2658
   */
2659
}
2660
 
2661
/**
2662
  * @brief  UART Abort Complete callback.
2663
  * @param  huart UART handle.
2664
  * @retval None
2665
  */
2666
__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2667
{
2668
  /* Prevent unused argument(s) compilation warning */
2669
  UNUSED(huart);
2670
 
2671
  /* NOTE : This function should not be modified, when the callback is needed,
2672
            the HAL_UART_AbortCpltCallback can be implemented in the user file.
2673
   */
2674
}
2675
 
2676
/**
2677
  * @brief  UART Abort Complete callback.
2678
  * @param  huart UART handle.
2679
  * @retval None
2680
  */
2681
__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2682
{
2683
  /* Prevent unused argument(s) compilation warning */
2684
  UNUSED(huart);
2685
 
2686
  /* NOTE : This function should not be modified, when the callback is needed,
2687
            the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2688
   */
2689
}
2690
 
2691
/**
2692
  * @brief  UART Abort Receive Complete callback.
2693
  * @param  huart UART handle.
2694
  * @retval None
2695
  */
2696
__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2697
{
2698
  /* Prevent unused argument(s) compilation warning */
2699
  UNUSED(huart);
2700
 
2701
  /* NOTE : This function should not be modified, when the callback is needed,
2702
            the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2703
   */
2704
}
2705
 
2706
/**
6 mjames 2707
  * @brief  Reception Event Callback (Rx event notification called after use of advanced reception service).
2708
  * @param  huart UART handle
2709
  * @param  Size  Number of data available in application reception buffer (indicates a position in
2710
  *               reception buffer until which, data are available)
2711
  * @retval None
2712
  */
2713
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
2714
{
2715
  /* Prevent unused argument(s) compilation warning */
2716
  UNUSED(huart);
2717
  UNUSED(Size);
2718
 
2719
  /* NOTE : This function should not be modified, when the callback is needed,
2720
            the HAL_UARTEx_RxEventCallback can be implemented in the user file.
2721
   */
2722
}
2723
 
2724
/**
2 mjames 2725
  * @}
2726
  */
2727
 
2728
/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2729
  *  @brief   UART control functions
2730
  *
2731
@verbatim
2732
 ===============================================================================
2733
                      ##### Peripheral Control functions #####
2734
 ===============================================================================
2735
    [..]
2736
    This subsection provides a set of functions allowing to control the UART.
2737
     (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2738
     (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2739
     (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2740
     (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2741
     (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2742
     (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2743
     (+) UART_SetConfig() API configures the UART peripheral
2744
     (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2745
     (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2746
     (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2747
     (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2748
     (+) HAL_LIN_SendBreak() API transmits the break characters
2749
@endverbatim
2750
  * @{
2751
  */
2752
 
2753
/**
2754
  * @brief  Update on the fly the receiver timeout value in RTOR register.
2755
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2756
  *                    the configuration information for the specified UART module.
2757
  * @param  TimeoutValue receiver timeout value in number of baud blocks. The timeout
2758
  *                     value must be less or equal to 0x0FFFFFFFF.
2759
  * @retval None
2760
  */
2761
void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2762
{
2763
  assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2764
  MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2765
}
2766
 
2767
/**
2768
  * @brief  Enable the UART receiver timeout feature.
2769
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2770
  *                    the configuration information for the specified UART module.
2771
  * @retval HAL status
2772
  */
2773
HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2774
{
2775
  if (huart->gState == HAL_UART_STATE_READY)
2776
  {
2777
    /* Process Locked */
2778
    __HAL_LOCK(huart);
2779
 
2780
    huart->gState = HAL_UART_STATE_BUSY;
2781
 
2782
    /* Set the USART RTOEN bit */
2783
    SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2784
 
2785
    huart->gState = HAL_UART_STATE_READY;
2786
 
2787
    /* Process Unlocked */
2788
    __HAL_UNLOCK(huart);
2789
 
2790
    return HAL_OK;
2791
  }
2792
  else
2793
  {
2794
    return HAL_BUSY;
2795
  }
2796
}
2797
 
2798
/**
2799
  * @brief  Disable the UART receiver timeout feature.
2800
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2801
  *                    the configuration information for the specified UART module.
2802
  * @retval HAL status
2803
  */
2804
HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2805
{
2806
  if (huart->gState == HAL_UART_STATE_READY)
2807
  {
2808
    /* Process Locked */
2809
    __HAL_LOCK(huart);
2810
 
2811
    huart->gState = HAL_UART_STATE_BUSY;
2812
 
2813
    /* Clear the USART RTOEN bit */
2814
    CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2815
 
2816
    huart->gState = HAL_UART_STATE_READY;
2817
 
2818
    /* Process Unlocked */
2819
    __HAL_UNLOCK(huart);
2820
 
2821
    return HAL_OK;
2822
  }
2823
  else
2824
  {
2825
    return HAL_BUSY;
2826
  }
2827
}
2828
 
2829
/**
2830
  * @brief  Enable UART in mute mode (does not mean UART enters mute mode;
2831
  *         to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2832
  * @param  huart UART handle.
2833
  * @retval HAL status
2834
  */
2835
HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2836
{
2837
  __HAL_LOCK(huart);
2838
 
2839
  huart->gState = HAL_UART_STATE_BUSY;
2840
 
2841
  /* Enable USART mute mode by setting the MME bit in the CR1 register */
6 mjames 2842
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2 mjames 2843
 
2844
  huart->gState = HAL_UART_STATE_READY;
2845
 
2846
  return (UART_CheckIdleState(huart));
2847
}
2848
 
2849
/**
2850
  * @brief  Disable UART mute mode (does not mean the UART actually exits mute mode
2851
  *         as it may not have been in mute mode at this very moment).
2852
  * @param  huart UART handle.
2853
  * @retval HAL status
2854
  */
2855
HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2856
{
2857
  __HAL_LOCK(huart);
2858
 
2859
  huart->gState = HAL_UART_STATE_BUSY;
2860
 
2861
  /* Disable USART mute mode by clearing the MME bit in the CR1 register */
6 mjames 2862
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2 mjames 2863
 
2864
  huart->gState = HAL_UART_STATE_READY;
2865
 
2866
  return (UART_CheckIdleState(huart));
2867
}
2868
 
2869
/**
2870
  * @brief Enter UART mute mode (means UART actually enters mute mode).
2871
  * @note  To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2872
  * @param huart UART handle.
2873
  * @retval None
2874
  */
2875
void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2876
{
2877
  __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2878
}
2879
 
2880
/**
2881
  * @brief  Enable the UART transmitter and disable the UART receiver.
2882
  * @param  huart UART handle.
2883
  * @retval HAL status
2884
  */
2885
HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2886
{
2887
  __HAL_LOCK(huart);
2888
  huart->gState = HAL_UART_STATE_BUSY;
2889
 
2890
  /* Clear TE and RE bits */
6 mjames 2891
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2 mjames 2892
 
2893
  /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
6 mjames 2894
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2 mjames 2895
 
2896
  huart->gState = HAL_UART_STATE_READY;
2897
 
2898
  __HAL_UNLOCK(huart);
2899
 
2900
  return HAL_OK;
2901
}
2902
 
2903
/**
2904
  * @brief  Enable the UART receiver and disable the UART transmitter.
2905
  * @param  huart UART handle.
2906
  * @retval HAL status.
2907
  */
2908
HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2909
{
2910
  __HAL_LOCK(huart);
2911
  huart->gState = HAL_UART_STATE_BUSY;
2912
 
2913
  /* Clear TE and RE bits */
6 mjames 2914
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2 mjames 2915
 
2916
  /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
6 mjames 2917
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2 mjames 2918
 
2919
  huart->gState = HAL_UART_STATE_READY;
2920
 
2921
  __HAL_UNLOCK(huart);
2922
 
2923
  return HAL_OK;
2924
}
2925
 
2926
 
2927
#if   defined(USART_CR2_LINEN)
2928
/**
2929
  * @brief  Transmit break characters.
2930
  * @param  huart UART handle.
2931
  * @retval HAL status
2932
  */
2933
HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2934
{
2935
  /* Check the parameters */
2936
  assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2937
 
2938
  __HAL_LOCK(huart);
2939
 
2940
  huart->gState = HAL_UART_STATE_BUSY;
2941
 
2942
  /* Send break characters */
2943
  __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
2944
 
2945
  huart->gState = HAL_UART_STATE_READY;
2946
 
2947
  __HAL_UNLOCK(huart);
2948
 
2949
  return HAL_OK;
2950
}
2951
#endif /* USART_CR2_LINEN */
2952
 
2953
/**
2954
  * @}
2955
  */
2956
 
2957
/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
2958
  *  @brief   UART Peripheral State functions
2959
  *
2960
@verbatim
2961
  ==============================================================================
2962
            ##### Peripheral State and Error functions #####
2963
  ==============================================================================
2964
    [..]
2965
    This subsection provides functions allowing to :
2966
      (+) Return the UART handle state.
2967
      (+) Return the UART handle error code
2968
 
2969
@endverbatim
2970
  * @{
2971
  */
2972
 
2973
/**
2974
  * @brief Return the UART handle state.
2975
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2976
  *               the configuration information for the specified UART.
2977
  * @retval HAL state
2978
  */
2979
HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
2980
{
2981
  uint32_t temp1;
2982
  uint32_t temp2;
2983
  temp1 = huart->gState;
2984
  temp2 = huart->RxState;
2985
 
2986
  return (HAL_UART_StateTypeDef)(temp1 | temp2);
2987
}
2988
 
2989
/**
2990
  * @brief  Return the UART handle error code.
2991
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2992
  *               the configuration information for the specified UART.
2993
  * @retval UART Error Code
2994
  */
2995
uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
2996
{
2997
  return huart->ErrorCode;
2998
}
2999
/**
3000
  * @}
3001
  */
3002
 
3003
/**
3004
  * @}
3005
  */
3006
 
3007
/** @defgroup UART_Private_Functions UART Private Functions
3008
  * @{
3009
  */
3010
 
3011
/**
3012
  * @brief  Initialize the callbacks to their default values.
3013
  * @param  huart UART handle.
3014
  * @retval none
3015
  */
3016
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3017
void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
3018
{
3019
  /* Init the UART Callback settings */
3020
  huart->TxHalfCpltCallback        = HAL_UART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
3021
  huart->TxCpltCallback            = HAL_UART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
3022
  huart->RxHalfCpltCallback        = HAL_UART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
3023
  huart->RxCpltCallback            = HAL_UART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
3024
  huart->ErrorCallback             = HAL_UART_ErrorCallback;             /* Legacy weak ErrorCallback             */
3025
  huart->AbortCpltCallback         = HAL_UART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
3026
  huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
3027
  huart->AbortReceiveCpltCallback  = HAL_UART_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
3028
#if defined(USART_CR1_UESM)
6 mjames 3029
#if defined(USART_CR3_WUFIE)
2 mjames 3030
  huart->WakeupCallback            = HAL_UARTEx_WakeupCallback;          /* Legacy weak WakeupCallback            */
6 mjames 3031
#endif /* USART_CR3_WUFIE */
2 mjames 3032
#endif /* USART_CR1_UESM */
6 mjames 3033
  huart->RxEventCallback           = HAL_UARTEx_RxEventCallback;         /* Legacy weak RxEventCallback           */
2 mjames 3034
 
3035
}
3036
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3037
 
3038
/**
3039
  * @brief Configure the UART peripheral.
3040
  * @param huart UART handle.
3041
  * @retval HAL status
3042
  */
3043
HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
3044
{
3045
  uint32_t tmpreg;
3046
  uint16_t brrtemp;
3047
  UART_ClockSourceTypeDef clocksource;
6 mjames 3048
  uint32_t usartdiv;
2 mjames 3049
  HAL_StatusTypeDef ret               = HAL_OK;
3050
  uint32_t pclk;
3051
 
3052
  /* Check the parameters */
3053
  assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
3054
  assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
3055
  assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
3056
  assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
3057
 
3058
  assert_param(IS_UART_PARITY(huart->Init.Parity));
3059
  assert_param(IS_UART_MODE(huart->Init.Mode));
3060
  assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
3061
  assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
3062
 
3063
  /*-------------------------- USART CR1 Configuration -----------------------*/
3064
  /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
3065
  *  the UART Word Length, Parity, Mode and oversampling:
3066
  *  set the M bits according to huart->Init.WordLength value
3067
  *  set PCE and PS bits according to huart->Init.Parity value
3068
  *  set TE and RE bits according to huart->Init.Mode value
3069
  *  set OVER8 bit according to huart->Init.OverSampling value */
3070
  tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
3071
  MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3072
 
3073
  /*-------------------------- USART CR2 Configuration -----------------------*/
3074
  /* Configure the UART Stop Bits: Set STOP[13:12] bits according
3075
  * to huart->Init.StopBits value */
3076
  MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
3077
 
3078
  /*-------------------------- USART CR3 Configuration -----------------------*/
3079
  /* Configure
3080
  * - UART HardWare Flow Control: set CTSE and RTSE bits according
3081
  *   to huart->Init.HwFlowCtl value
3082
  * - one-bit sampling method versus three samples' majority rule according
3083
  *   to huart->Init.OneBitSampling (not applicable to LPUART) */
3084
  tmpreg = (uint32_t)huart->Init.HwFlowCtl;
3085
 
3086
  tmpreg |= huart->Init.OneBitSampling;
3087
  MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
3088
 
3089
 
3090
  /*-------------------------- USART BRR Configuration -----------------------*/
3091
  UART_GETCLOCKSOURCE(huart, clocksource);
3092
 
3093
  if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3094
  {
3095
    switch (clocksource)
3096
    {
3097
      case UART_CLOCKSOURCE_PCLK1:
3098
        pclk = HAL_RCC_GetPCLK1Freq();
3099
        break;
3100
      case UART_CLOCKSOURCE_HSI:
6 mjames 3101
        pclk = (uint32_t) HSI_VALUE;
2 mjames 3102
        break;
3103
      case UART_CLOCKSOURCE_SYSCLK:
3104
        pclk = HAL_RCC_GetSysClockFreq();
3105
        break;
3106
      case UART_CLOCKSOURCE_LSE:
6 mjames 3107
        pclk = (uint32_t) LSE_VALUE;
2 mjames 3108
        break;
3109
      default:
6 mjames 3110
        pclk = 0U;
2 mjames 3111
        ret = HAL_ERROR;
3112
        break;
3113
    }
3114
 
3115
    /* USARTDIV must be greater than or equal to 0d16 */
6 mjames 3116
    if (pclk != 0U)
2 mjames 3117
    {
6 mjames 3118
      usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate));
3119
      if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3120
      {
3121
        brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3122
        brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3123
        huart->Instance->BRR = brrtemp;
3124
      }
3125
      else
3126
      {
3127
        ret = HAL_ERROR;
3128
      }
2 mjames 3129
    }
3130
  }
3131
  else
3132
  {
3133
    switch (clocksource)
3134
    {
3135
      case UART_CLOCKSOURCE_PCLK1:
3136
        pclk = HAL_RCC_GetPCLK1Freq();
3137
        break;
3138
      case UART_CLOCKSOURCE_HSI:
6 mjames 3139
        pclk = (uint32_t) HSI_VALUE;
2 mjames 3140
        break;
3141
      case UART_CLOCKSOURCE_SYSCLK:
3142
        pclk = HAL_RCC_GetSysClockFreq();
3143
        break;
3144
      case UART_CLOCKSOURCE_LSE:
6 mjames 3145
        pclk = (uint32_t) LSE_VALUE;
2 mjames 3146
        break;
3147
      default:
6 mjames 3148
        pclk = 0U;
2 mjames 3149
        ret = HAL_ERROR;
3150
        break;
3151
    }
3152
 
6 mjames 3153
    if (pclk != 0U)
2 mjames 3154
    {
6 mjames 3155
      /* USARTDIV must be greater than or equal to 0d16 */
3156
      usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate));
3157
      if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3158
      {
3159
        huart->Instance->BRR = usartdiv;
3160
      }
3161
      else
3162
      {
3163
        ret = HAL_ERROR;
3164
      }
2 mjames 3165
    }
3166
  }
3167
 
3168
 
3169
  /* Clear ISR function pointers */
3170
  huart->RxISR = NULL;
3171
  huart->TxISR = NULL;
3172
 
3173
  return ret;
3174
}
3175
 
3176
/**
3177
  * @brief Configure the UART peripheral advanced features.
3178
  * @param huart UART handle.
3179
  * @retval None
3180
  */
3181
void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3182
{
3183
  /* Check whether the set of advanced features to configure is properly set */
3184
  assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3185
 
3186
  /* if required, configure TX pin active level inversion */
3187
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3188
  {
3189
    assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3190
    MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3191
  }
3192
 
3193
  /* if required, configure RX pin active level inversion */
3194
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3195
  {
3196
    assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3197
    MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3198
  }
3199
 
3200
  /* if required, configure data inversion */
3201
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3202
  {
3203
    assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3204
    MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3205
  }
3206
 
3207
  /* if required, configure RX/TX pins swap */
3208
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3209
  {
3210
    assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3211
    MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3212
  }
3213
 
3214
  /* if required, configure RX overrun detection disabling */
3215
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3216
  {
3217
    assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3218
    MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3219
  }
3220
 
3221
  /* if required, configure DMA disabling on reception error */
3222
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3223
  {
3224
    assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3225
    MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3226
  }
3227
 
3228
  /* if required, configure auto Baud rate detection scheme */
3229
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3230
  {
3231
    assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3232
    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3233
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3234
    /* set auto Baudrate detection parameters if detection is enabled */
3235
    if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3236
    {
3237
      assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3238
      MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3239
    }
3240
  }
3241
 
3242
  /* if required, configure MSB first on communication line */
3243
  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3244
  {
3245
    assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3246
    MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3247
  }
3248
}
3249
 
3250
/**
3251
  * @brief Check the UART Idle State.
3252
  * @param huart UART handle.
3253
  * @retval HAL status
3254
  */
3255
HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3256
{
3257
  uint32_t tickstart;
3258
 
3259
  /* Initialize the UART ErrorCode */
3260
  huart->ErrorCode = HAL_UART_ERROR_NONE;
3261
 
6 mjames 3262
  /* Init tickstart for timeout management */
2 mjames 3263
  tickstart = HAL_GetTick();
3264
 
3265
  /* Check if the Transmitter is enabled */
3266
  if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3267
  {
3268
    /* Wait until TEACK flag is set */
3269
    if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3270
    {
3271
      /* Timeout occurred */
3272
      return HAL_TIMEOUT;
3273
    }
3274
  }
3275
 
3276
  /* Check if the Receiver is enabled */
3277
  if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3278
  {
3279
    /* Wait until REACK flag is set */
3280
    if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3281
    {
3282
      /* Timeout occurred */
3283
      return HAL_TIMEOUT;
3284
    }
3285
  }
3286
 
3287
  /* Initialize the UART State */
3288
  huart->gState = HAL_UART_STATE_READY;
3289
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 3290
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 3291
 
3292
  __HAL_UNLOCK(huart);
3293
 
3294
  return HAL_OK;
3295
}
3296
 
3297
/**
3298
  * @brief  Handle UART Communication Timeout.
3299
  * @param huart     UART handle.
3300
  * @param Flag      Specifies the UART flag to check
3301
  * @param Status    Flag status (SET or RESET)
3302
  * @param Tickstart Tick start value
3303
  * @param Timeout   Timeout duration
3304
  * @retval HAL status
3305
  */
3306
HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3307
                                              uint32_t Tickstart, uint32_t Timeout)
3308
{
3309
  /* Wait until flag is set */
3310
  while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3311
  {
3312
    /* Check for the Timeout */
3313
    if (Timeout != HAL_MAX_DELAY)
3314
    {
3315
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3316
      {
6 mjames 3317
        /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
3318
           interrupts for the interrupt process */
3319
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
3320
        ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 3321
 
3322
        huart->gState = HAL_UART_STATE_READY;
3323
        huart->RxState = HAL_UART_STATE_READY;
3324
 
3325
        __HAL_UNLOCK(huart);
3326
 
3327
        return HAL_TIMEOUT;
3328
      }
3329
 
3330
      if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
3331
      {
3332
        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3333
        {
3334
          /* Clear Receiver Timeout flag*/
3335
          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3336
 
6 mjames 3337
          /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
3338
             interrupts for the interrupt process */
3339
          ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
3340
          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3341
 
2 mjames 3342
          huart->gState = HAL_UART_STATE_READY;
3343
          huart->RxState = HAL_UART_STATE_READY;
3344
          huart->ErrorCode = HAL_UART_ERROR_RTO;
6 mjames 3345
 
2 mjames 3346
          /* Process Unlocked */
3347
          __HAL_UNLOCK(huart);
6 mjames 3348
 
2 mjames 3349
          return HAL_TIMEOUT;
3350
        }
3351
      }
3352
    }
3353
  }
3354
  return HAL_OK;
3355
}
3356
 
6 mjames 3357
/**
3358
  * @brief  Start Receive operation in interrupt mode.
3359
  * @note   This function could be called by all HAL UART API providing reception in Interrupt mode.
3360
  * @note   When calling this function, parameters validity is considered as already checked,
3361
  *         i.e. Rx State, buffer address, ...
3362
  *         UART Handle is assumed as Locked.
3363
  * @param  huart UART handle.
3364
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
3365
  * @param  Size  Amount of data elements (u8 or u16) to be received.
3366
  * @retval HAL status
3367
  */
3368
HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3369
{
3370
  huart->pRxBuffPtr  = pData;
3371
  huart->RxXferSize  = Size;
3372
  huart->RxXferCount = Size;
3373
  huart->RxISR       = NULL;
2 mjames 3374
 
6 mjames 3375
  /* Computation of UART mask to apply to RDR register */
3376
  UART_MASK_COMPUTATION(huart);
3377
 
3378
  huart->ErrorCode = HAL_UART_ERROR_NONE;
3379
  huart->RxState = HAL_UART_STATE_BUSY_RX;
3380
 
3381
  /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3382
  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3383
 
3384
  /* Set the Rx ISR function pointer according to the data word length */
3385
  if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3386
  {
3387
    huart->RxISR = UART_RxISR_16BIT;
3388
  }
3389
  else
3390
  {
3391
    huart->RxISR = UART_RxISR_8BIT;
3392
  }
3393
 
3394
  __HAL_UNLOCK(huart);
3395
 
3396
  /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
3397
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
3398
  return HAL_OK;
3399
}
3400
 
2 mjames 3401
/**
6 mjames 3402
  * @brief  Start Receive operation in DMA mode.
3403
  * @note   This function could be called by all HAL UART API providing reception in DMA mode.
3404
  * @note   When calling this function, parameters validity is considered as already checked,
3405
  *         i.e. Rx State, buffer address, ...
3406
  *         UART Handle is assumed as Locked.
3407
  * @param  huart UART handle.
3408
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
3409
  * @param  Size  Amount of data elements (u8 or u16) to be received.
3410
  * @retval HAL status
3411
  */
3412
HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3413
{
3414
  huart->pRxBuffPtr = pData;
3415
  huart->RxXferSize = Size;
3416
 
3417
  huart->ErrorCode = HAL_UART_ERROR_NONE;
3418
  huart->RxState = HAL_UART_STATE_BUSY_RX;
3419
 
3420
  if (huart->hdmarx != NULL)
3421
  {
3422
    /* Set the UART DMA transfer complete callback */
3423
    huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
3424
 
3425
    /* Set the UART DMA Half transfer complete callback */
3426
    huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
3427
 
3428
    /* Set the DMA error callback */
3429
    huart->hdmarx->XferErrorCallback = UART_DMAError;
3430
 
3431
    /* Set the DMA abort callback */
3432
    huart->hdmarx->XferAbortCallback = NULL;
3433
 
3434
    /* Enable the DMA channel */
3435
    if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
3436
    {
3437
      /* Set error code to DMA */
3438
      huart->ErrorCode = HAL_UART_ERROR_DMA;
3439
 
3440
      __HAL_UNLOCK(huart);
3441
 
3442
      /* Restore huart->RxState to ready */
3443
      huart->RxState = HAL_UART_STATE_READY;
3444
 
3445
      return HAL_ERROR;
3446
    }
3447
  }
3448
  __HAL_UNLOCK(huart);
3449
 
3450
  /* Enable the UART Parity Error Interrupt */
3451
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3452
 
3453
  /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3454
  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3455
 
3456
  /* Enable the DMA transfer for the receiver request by setting the DMAR bit
3457
  in the UART CR3 register */
3458
  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3459
 
3460
  return HAL_OK;
3461
}
3462
 
3463
 
3464
/**
2 mjames 3465
  * @brief  End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3466
  * @param  huart UART handle.
3467
  * @retval None
3468
  */
3469
static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3470
{
3471
  /* Disable TXEIE and TCIE interrupts */
6 mjames 3472
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2 mjames 3473
 
3474
  /* At end of Tx process, restore huart->gState to Ready */
3475
  huart->gState = HAL_UART_STATE_READY;
3476
}
3477
 
3478
 
3479
/**
3480
  * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3481
  * @param  huart UART handle.
3482
  * @retval None
3483
  */
3484
static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3485
{
3486
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 3487
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3488
  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 3489
 
6 mjames 3490
  /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
3491
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3492
  {
3493
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3494
  }
3495
 
2 mjames 3496
  /* At end of Rx process, restore huart->RxState to Ready */
3497
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 3498
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 3499
 
3500
  /* Reset RxIsr function pointer */
3501
  huart->RxISR = NULL;
3502
}
3503
 
3504
 
3505
/**
3506
  * @brief DMA UART transmit process complete callback.
3507
  * @param hdma DMA handle.
3508
  * @retval None
3509
  */
3510
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3511
{
3512
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3513
 
3514
  /* DMA Normal mode */
3515
  if (hdma->Init.Mode != DMA_CIRCULAR)
3516
  {
3517
    huart->TxXferCount = 0U;
3518
 
3519
    /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3520
       in the UART CR3 register */
6 mjames 3521
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2 mjames 3522
 
3523
    /* Enable the UART Transmit Complete Interrupt */
6 mjames 3524
    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
2 mjames 3525
  }
3526
  /* DMA Circular mode */
3527
  else
3528
  {
3529
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3530
    /*Call registered Tx complete callback*/
3531
    huart->TxCpltCallback(huart);
3532
#else
3533
    /*Call legacy weak Tx complete callback*/
3534
    HAL_UART_TxCpltCallback(huart);
3535
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3536
  }
3537
}
3538
 
3539
/**
3540
  * @brief DMA UART transmit process half complete callback.
3541
  * @param hdma DMA handle.
3542
  * @retval None
3543
  */
3544
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3545
{
3546
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3547
 
3548
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3549
  /*Call registered Tx Half complete callback*/
3550
  huart->TxHalfCpltCallback(huart);
3551
#else
3552
  /*Call legacy weak Tx Half complete callback*/
3553
  HAL_UART_TxHalfCpltCallback(huart);
3554
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3555
}
3556
 
3557
/**
3558
  * @brief DMA UART receive process complete callback.
3559
  * @param hdma DMA handle.
3560
  * @retval None
3561
  */
3562
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3563
{
3564
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3565
 
3566
  /* DMA Normal mode */
3567
  if (hdma->Init.Mode != DMA_CIRCULAR)
3568
  {
3569
    huart->RxXferCount = 0U;
3570
 
3571
    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
6 mjames 3572
    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3573
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 3574
 
3575
    /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3576
       in the UART CR3 register */
6 mjames 3577
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2 mjames 3578
 
3579
    /* At end of Rx process, restore huart->RxState to Ready */
3580
    huart->RxState = HAL_UART_STATE_READY;
6 mjames 3581
 
3582
    /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
3583
    if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3584
    {
3585
      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3586
    }
2 mjames 3587
  }
3588
 
6 mjames 3589
  /* Check current reception Mode :
3590
     If Reception till IDLE event has been selected : use Rx Event callback */
3591
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3592
  {
2 mjames 3593
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
6 mjames 3594
    /*Call registered Rx Event callback*/
3595
    huart->RxEventCallback(huart, huart->RxXferSize);
2 mjames 3596
#else
6 mjames 3597
    /*Call legacy weak Rx Event callback*/
3598
    HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
2 mjames 3599
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
6 mjames 3600
  }
3601
  else
3602
  {
3603
    /* In other cases : use Rx Complete callback */
3604
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3605
    /*Call registered Rx complete callback*/
3606
    huart->RxCpltCallback(huart);
3607
#else
3608
    /*Call legacy weak Rx complete callback*/
3609
    HAL_UART_RxCpltCallback(huart);
3610
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3611
  }
2 mjames 3612
}
3613
 
3614
/**
3615
  * @brief DMA UART receive process half complete callback.
3616
  * @param hdma DMA handle.
3617
  * @retval None
3618
  */
3619
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3620
{
3621
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3622
 
6 mjames 3623
  /* Check current reception Mode :
3624
     If Reception till IDLE event has been selected : use Rx Event callback */
3625
  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3626
  {
2 mjames 3627
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
6 mjames 3628
    /*Call registered Rx Event callback*/
3629
    huart->RxEventCallback(huart, huart->RxXferSize / 2U);
2 mjames 3630
#else
6 mjames 3631
    /*Call legacy weak Rx Event callback*/
3632
    HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
2 mjames 3633
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
6 mjames 3634
  }
3635
  else
3636
  {
3637
    /* In other cases : use Rx Half Complete callback */
3638
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3639
    /*Call registered Rx Half complete callback*/
3640
    huart->RxHalfCpltCallback(huart);
3641
#else
3642
    /*Call legacy weak Rx Half complete callback*/
3643
    HAL_UART_RxHalfCpltCallback(huart);
3644
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3645
  }
2 mjames 3646
}
3647
 
3648
/**
3649
  * @brief DMA UART communication error callback.
3650
  * @param hdma DMA handle.
3651
  * @retval None
3652
  */
3653
static void UART_DMAError(DMA_HandleTypeDef *hdma)
3654
{
3655
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3656
 
3657
  const HAL_UART_StateTypeDef gstate = huart->gState;
3658
  const HAL_UART_StateTypeDef rxstate = huart->RxState;
3659
 
3660
  /* Stop UART DMA Tx request if ongoing */
3661
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3662
      (gstate == HAL_UART_STATE_BUSY_TX))
3663
  {
3664
    huart->TxXferCount = 0U;
3665
    UART_EndTxTransfer(huart);
3666
  }
3667
 
3668
  /* Stop UART DMA Rx request if ongoing */
3669
  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3670
      (rxstate == HAL_UART_STATE_BUSY_RX))
3671
  {
3672
    huart->RxXferCount = 0U;
3673
    UART_EndRxTransfer(huart);
3674
  }
3675
 
3676
  huart->ErrorCode |= HAL_UART_ERROR_DMA;
3677
 
3678
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3679
  /*Call registered error callback*/
3680
  huart->ErrorCallback(huart);
3681
#else
3682
  /*Call legacy weak error callback*/
3683
  HAL_UART_ErrorCallback(huart);
3684
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3685
}
3686
 
3687
/**
3688
  * @brief  DMA UART communication abort callback, when initiated by HAL services on Error
3689
  *         (To be called at end of DMA Abort procedure following error occurrence).
3690
  * @param  hdma DMA handle.
3691
  * @retval None
3692
  */
3693
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3694
{
3695
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3696
  huart->RxXferCount = 0U;
3697
  huart->TxXferCount = 0U;
3698
 
3699
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3700
  /*Call registered error callback*/
3701
  huart->ErrorCallback(huart);
3702
#else
3703
  /*Call legacy weak error callback*/
3704
  HAL_UART_ErrorCallback(huart);
3705
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3706
}
3707
 
3708
/**
3709
  * @brief  DMA UART Tx communication abort callback, when initiated by user
3710
  *         (To be called at end of DMA Tx Abort procedure following user abort request).
3711
  * @note   When this callback is executed, User Abort complete call back is called only if no
3712
  *         Abort still ongoing for Rx DMA Handle.
3713
  * @param  hdma DMA handle.
3714
  * @retval None
3715
  */
3716
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3717
{
3718
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3719
 
3720
  huart->hdmatx->XferAbortCallback = NULL;
3721
 
3722
  /* Check if an Abort process is still ongoing */
3723
  if (huart->hdmarx != NULL)
3724
  {
3725
    if (huart->hdmarx->XferAbortCallback != NULL)
3726
    {
3727
      return;
3728
    }
3729
  }
3730
 
3731
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3732
  huart->TxXferCount = 0U;
3733
  huart->RxXferCount = 0U;
3734
 
3735
  /* Reset errorCode */
3736
  huart->ErrorCode = HAL_UART_ERROR_NONE;
3737
 
3738
  /* Clear the Error flags in the ICR register */
3739
  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3740
 
3741
 
3742
  /* Restore huart->gState and huart->RxState to Ready */
3743
  huart->gState  = HAL_UART_STATE_READY;
3744
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 3745
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 3746
 
3747
  /* Call user Abort complete callback */
3748
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3749
  /* Call registered Abort complete callback */
3750
  huart->AbortCpltCallback(huart);
3751
#else
3752
  /* Call legacy weak Abort complete callback */
3753
  HAL_UART_AbortCpltCallback(huart);
3754
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3755
}
3756
 
3757
 
3758
/**
3759
  * @brief  DMA UART Rx communication abort callback, when initiated by user
3760
  *         (To be called at end of DMA Rx Abort procedure following user abort request).
3761
  * @note   When this callback is executed, User Abort complete call back is called only if no
3762
  *         Abort still ongoing for Tx DMA Handle.
3763
  * @param  hdma DMA handle.
3764
  * @retval None
3765
  */
3766
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3767
{
3768
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3769
 
3770
  huart->hdmarx->XferAbortCallback = NULL;
3771
 
3772
  /* Check if an Abort process is still ongoing */
3773
  if (huart->hdmatx != NULL)
3774
  {
3775
    if (huart->hdmatx->XferAbortCallback != NULL)
3776
    {
3777
      return;
3778
    }
3779
  }
3780
 
3781
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3782
  huart->TxXferCount = 0U;
3783
  huart->RxXferCount = 0U;
3784
 
3785
  /* Reset errorCode */
3786
  huart->ErrorCode = HAL_UART_ERROR_NONE;
3787
 
3788
  /* Clear the Error flags in the ICR register */
3789
  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3790
 
3791
  /* Discard the received data */
3792
  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3793
 
3794
  /* Restore huart->gState and huart->RxState to Ready */
3795
  huart->gState  = HAL_UART_STATE_READY;
3796
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 3797
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 3798
 
3799
  /* Call user Abort complete callback */
3800
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3801
  /* Call registered Abort complete callback */
3802
  huart->AbortCpltCallback(huart);
3803
#else
3804
  /* Call legacy weak Abort complete callback */
3805
  HAL_UART_AbortCpltCallback(huart);
3806
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3807
}
3808
 
3809
 
3810
/**
3811
  * @brief  DMA UART Tx communication abort callback, when initiated by user by a call to
3812
  *         HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3813
  *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3814
  *         and leads to user Tx Abort Complete callback execution).
3815
  * @param  hdma DMA handle.
3816
  * @retval None
3817
  */
3818
static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3819
{
3820
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3821
 
3822
  huart->TxXferCount = 0U;
3823
 
3824
 
3825
  /* Restore huart->gState to Ready */
3826
  huart->gState = HAL_UART_STATE_READY;
3827
 
3828
  /* Call user Abort complete callback */
3829
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3830
  /* Call registered Abort Transmit Complete Callback */
3831
  huart->AbortTransmitCpltCallback(huart);
3832
#else
3833
  /* Call legacy weak Abort Transmit Complete Callback */
3834
  HAL_UART_AbortTransmitCpltCallback(huart);
3835
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3836
}
3837
 
3838
/**
3839
  * @brief  DMA UART Rx communication abort callback, when initiated by user by a call to
3840
  *         HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3841
  *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3842
  *         and leads to user Rx Abort Complete callback execution).
3843
  * @param  hdma DMA handle.
3844
  * @retval None
3845
  */
3846
static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3847
{
3848
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3849
 
3850
  huart->RxXferCount = 0U;
3851
 
3852
  /* Clear the Error flags in the ICR register */
3853
  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3854
 
3855
  /* Discard the received data */
3856
  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3857
 
3858
  /* Restore huart->RxState to Ready */
3859
  huart->RxState = HAL_UART_STATE_READY;
6 mjames 3860
  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2 mjames 3861
 
3862
  /* Call user Abort complete callback */
3863
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3864
  /* Call registered Abort Receive Complete Callback */
3865
  huart->AbortReceiveCpltCallback(huart);
3866
#else
3867
  /* Call legacy weak Abort Receive Complete Callback */
3868
  HAL_UART_AbortReceiveCpltCallback(huart);
3869
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3870
}
3871
 
3872
/**
6 mjames 3873
  * @brief TX interrupt handler for 7 or 8 bits data word length .
2 mjames 3874
  * @note   Function is called under interruption only, once
3875
  *         interruptions have been enabled by HAL_UART_Transmit_IT().
3876
  * @param huart UART handle.
3877
  * @retval None
3878
  */
3879
static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
3880
{
3881
  /* Check that a Tx process is ongoing */
3882
  if (huart->gState == HAL_UART_STATE_BUSY_TX)
3883
  {
3884
    if (huart->TxXferCount == 0U)
3885
    {
3886
      /* Disable the UART Transmit Data Register Empty Interrupt */
6 mjames 3887
      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
2 mjames 3888
 
3889
      /* Enable the UART Transmit Complete Interrupt */
6 mjames 3890
      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
2 mjames 3891
    }
3892
    else
3893
    {
3894
      huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
3895
      huart->pTxBuffPtr++;
3896
      huart->TxXferCount--;
3897
    }
3898
  }
3899
}
3900
 
3901
/**
6 mjames 3902
  * @brief TX interrupt handler for 9 bits data word length.
2 mjames 3903
  * @note   Function is called under interruption only, once
3904
  *         interruptions have been enabled by HAL_UART_Transmit_IT().
3905
  * @param huart UART handle.
3906
  * @retval None
3907
  */
3908
static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
3909
{
3910
  uint16_t *tmp;
3911
 
3912
  /* Check that a Tx process is ongoing */
3913
  if (huart->gState == HAL_UART_STATE_BUSY_TX)
3914
  {
3915
    if (huart->TxXferCount == 0U)
3916
    {
3917
      /* Disable the UART Transmit Data Register Empty Interrupt */
6 mjames 3918
      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
2 mjames 3919
 
3920
      /* Enable the UART Transmit Complete Interrupt */
6 mjames 3921
      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
2 mjames 3922
    }
3923
    else
3924
    {
3925
      tmp = (uint16_t *) huart->pTxBuffPtr;
3926
      huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
3927
      huart->pTxBuffPtr += 2U;
3928
      huart->TxXferCount--;
3929
    }
3930
  }
3931
}
3932
 
3933
 
3934
/**
3935
  * @brief  Wrap up transmission in non-blocking mode.
3936
  * @param  huart pointer to a UART_HandleTypeDef structure that contains
3937
  *                the configuration information for the specified UART module.
3938
  * @retval None
3939
  */
3940
static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
3941
{
3942
  /* Disable the UART Transmit Complete Interrupt */
6 mjames 3943
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
2 mjames 3944
 
3945
  /* Tx process is ended, restore huart->gState to Ready */
3946
  huart->gState = HAL_UART_STATE_READY;
3947
 
3948
  /* Cleat TxISR function pointer */
3949
  huart->TxISR = NULL;
3950
 
3951
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3952
  /*Call registered Tx complete callback*/
3953
  huart->TxCpltCallback(huart);
3954
#else
3955
  /*Call legacy weak Tx complete callback*/
3956
  HAL_UART_TxCpltCallback(huart);
3957
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3958
}
3959
 
3960
/**
6 mjames 3961
  * @brief RX interrupt handler for 7 or 8 bits data word length .
2 mjames 3962
  * @param huart UART handle.
3963
  * @retval None
3964
  */
3965
static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
3966
{
3967
  uint16_t uhMask = huart->Mask;
3968
  uint16_t  uhdata;
3969
 
3970
  /* Check that a Rx process is ongoing */
3971
  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3972
  {
3973
    uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3974
    *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
3975
    huart->pRxBuffPtr++;
3976
    huart->RxXferCount--;
3977
 
3978
    if (huart->RxXferCount == 0U)
3979
    {
3980
      /* Disable the UART Parity Error Interrupt and RXNE interrupts */
6 mjames 3981
      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2 mjames 3982
 
3983
      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
6 mjames 3984
      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 3985
 
3986
      /* Rx process is completed, restore huart->RxState to Ready */
3987
      huart->RxState = HAL_UART_STATE_READY;
3988
 
3989
      /* Clear RxISR function pointer */
3990
      huart->RxISR = NULL;
3991
 
6 mjames 3992
      /* Check current reception Mode :
3993
         If Reception till IDLE event has been selected : */
3994
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3995
      {
3996
        /* Set reception type to Standard */
3997
        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3998
 
3999
        /* Disable IDLE interrupt */
4000
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4001
 
4002
        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4003
        {
4004
          /* Clear IDLE Flag */
4005
          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4006
        }
2 mjames 4007
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
6 mjames 4008
        /*Call registered Rx Event callback*/
4009
        huart->RxEventCallback(huart, huart->RxXferSize);
2 mjames 4010
#else
6 mjames 4011
        /*Call legacy weak Rx Event callback*/
4012
        HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4013
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4014
      }
4015
      else
4016
      {
4017
        /* Standard reception API called */
4018
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4019
        /*Call registered Rx complete callback*/
4020
        huart->RxCpltCallback(huart);
4021
#else
4022
        /*Call legacy weak Rx complete callback*/
4023
        HAL_UART_RxCpltCallback(huart);
2 mjames 4024
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
6 mjames 4025
      }
2 mjames 4026
    }
4027
  }
4028
  else
4029
  {
4030
    /* Clear RXNE interrupt flag */
4031
    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4032
  }
4033
}
4034
 
4035
/**
6 mjames 4036
  * @brief RX interrupt handler for 9 bits data word length .
2 mjames 4037
  * @note   Function is called under interruption only, once
4038
  *         interruptions have been enabled by HAL_UART_Receive_IT()
4039
  * @param huart UART handle.
4040
  * @retval None
4041
  */
4042
static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
4043
{
4044
  uint16_t *tmp;
4045
  uint16_t uhMask = huart->Mask;
4046
  uint16_t  uhdata;
4047
 
4048
  /* Check that a Rx process is ongoing */
4049
  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4050
  {
4051
    uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4052
    tmp = (uint16_t *) huart->pRxBuffPtr ;
4053
    *tmp = (uint16_t)(uhdata & uhMask);
4054
    huart->pRxBuffPtr += 2U;
4055
    huart->RxXferCount--;
4056
 
4057
    if (huart->RxXferCount == 0U)
4058
    {
4059
      /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
6 mjames 4060
      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2 mjames 4061
 
4062
      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
6 mjames 4063
      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2 mjames 4064
 
4065
      /* Rx process is completed, restore huart->RxState to Ready */
4066
      huart->RxState = HAL_UART_STATE_READY;
4067
 
4068
      /* Clear RxISR function pointer */
4069
      huart->RxISR = NULL;
4070
 
6 mjames 4071
      /* Check current reception Mode :
4072
         If Reception till IDLE event has been selected : */
4073
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4074
      {
4075
        /* Set reception type to Standard */
4076
        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4077
 
4078
        /* Disable IDLE interrupt */
4079
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4080
 
4081
        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4082
        {
4083
          /* Clear IDLE Flag */
4084
          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4085
        }
2 mjames 4086
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
6 mjames 4087
        /*Call registered Rx Event callback*/
4088
        huart->RxEventCallback(huart, huart->RxXferSize);
2 mjames 4089
#else
6 mjames 4090
        /*Call legacy weak Rx Event callback*/
4091
        HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4092
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4093
      }
4094
      else
4095
      {
4096
        /* Standard reception API called */
4097
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4098
        /*Call registered Rx complete callback*/
4099
        huart->RxCpltCallback(huart);
4100
#else
4101
        /*Call legacy weak Rx complete callback*/
4102
        HAL_UART_RxCpltCallback(huart);
2 mjames 4103
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
6 mjames 4104
      }
2 mjames 4105
    }
4106
  }
4107
  else
4108
  {
4109
    /* Clear RXNE interrupt flag */
4110
    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4111
  }
4112
}
4113
 
4114
 
4115
/**
4116
  * @}
4117
  */
4118
 
4119
#endif /* HAL_UART_MODULE_ENABLED */
4120
/**
4121
  * @}
4122
  */
4123
 
4124
/**
4125
  * @}
4126
  */
4127
 
4128
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/