Subversion Repositories FuelGauge

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_hal_usart.c
4
  * @author  MCD Application Team
5
  * @brief   USART HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
8
  *          Peripheral (USART).
9
  *           + Initialization and de-initialization functions
10
  *           + IO operation functions
11
  *           + Peripheral Control functions
12
  *           + Peripheral State and Error functions
13
  *
14
  @verbatim
15
 ===============================================================================
16
                        ##### How to use this driver #####
17
 ===============================================================================
18
    [..]
19
      The USART HAL driver can be used as follows:
20
 
21
      (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
22
      (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
23
          (++) Enable the USARTx interface clock.
24
          (++) USART pins configuration:
25
            (+++) Enable the clock for the USART GPIOs.
26
            (+++) Configure these USART pins as alternate function pull-up.
27
          (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
28
                HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
29
            (+++) Configure the USARTx interrupt priority.
30
            (+++) Enable the NVIC USART IRQ handle.
31
            (++) USART interrupts handling:
32
              -@@-   The specific USART interrupts (Transmission complete interrupt,
33
                  RXNE interrupt and Error Interrupts) will be managed using the macros
34
                  __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
35
          (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
36
               HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_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 USART DMA Tx/Rx handle.
42
            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
43
 
44
      (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
45
          (Receiver/Transmitter) in the husart handle Init structure.
46
 
47
      (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48
          (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49
               by calling the customized HAL_USART_MspInit(&husart) API.
50
 
51
    [..]
52
     (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
53
        HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
54
        HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
55
 
56
    ##### Callback registration #####
57
    ==================================
58
 
59
    [..]
60
    The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
61
    allows the user to configure dynamically the driver callbacks.
62
 
63
    [..]
64
    Use Function @ref HAL_USART_RegisterCallback() to register a user callback.
65
    Function @ref HAL_USART_RegisterCallback() allows to register following callbacks:
66
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
67
    (+) TxCpltCallback            : Tx Complete Callback.
68
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
69
    (+) RxCpltCallback            : Rx Complete Callback.
70
    (+) TxRxCpltCallback          : Tx Rx Complete Callback.
71
    (+) ErrorCallback             : Error Callback.
72
    (+) AbortCpltCallback         : Abort Complete Callback.
73
    (+) MspInitCallback           : USART MspInit.
74
    (+) MspDeInitCallback         : USART MspDeInit.
75
    This function takes as parameters the HAL peripheral handle, the Callback ID
76
    and a pointer to the user callback function.
77
 
78
    [..]
79
    Use function @ref HAL_USART_UnRegisterCallback() to reset a callback to the default
80
    weak (surcharged) function.
81
    @ref HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
82
    and the Callback ID.
83
    This function allows to reset following callbacks:
84
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
85
    (+) TxCpltCallback            : Tx Complete Callback.
86
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
87
    (+) RxCpltCallback            : Rx Complete Callback.
88
    (+) TxRxCpltCallback          : Tx Rx Complete Callback.
89
    (+) ErrorCallback             : Error Callback.
90
    (+) AbortCpltCallback         : Abort Complete Callback.
91
    (+) MspInitCallback           : USART MspInit.
92
    (+) MspDeInitCallback         : USART MspDeInit.
93
 
94
    [..]
95
    By default, after the @ref HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
96
    all callbacks are set to the corresponding weak (surcharged) functions:
97
    examples @ref HAL_USART_TxCpltCallback(), @ref HAL_USART_RxHalfCpltCallback().
98
    Exception done for MspInit and MspDeInit functions that are respectively
99
    reset to the legacy weak (surcharged) functions in the @ref HAL_USART_Init()
100
    and @ref HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
101
    If not, MspInit or MspDeInit are not null, the @ref HAL_USART_Init() and @ref HAL_USART_DeInit()
102
    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
103
 
104
    [..]
105
    Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
106
    Exception done MspInit/MspDeInit that can be registered/unregistered
107
    in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
108
    MspInit/DeInit callbacks can be used during the Init/DeInit.
109
    In that case first register the MspInit/MspDeInit user callbacks
110
    using @ref HAL_USART_RegisterCallback() before calling @ref HAL_USART_DeInit()
111
    or @ref HAL_USART_Init() function.
112
 
113
    [..]
114
    When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
115
    not defined, the callback registration feature is not available
116
    and weak (surcharged) callbacks are used.
117
 
118
 
119
  @endverbatim
120
  ******************************************************************************
121
  * @attention
122
  *
123
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
124
  * All rights reserved.</center></h2>
125
  *
126
  * This software component is licensed by ST under BSD 3-Clause license,
127
  * the "License"; You may not use this file except in compliance with the
128
  * License. You may obtain a copy of the License at:
129
  *                        opensource.org/licenses/BSD-3-Clause
130
  *
131
  ******************************************************************************
132
  */
133
 
134
/* Includes ------------------------------------------------------------------*/
135
#include "stm32f0xx_hal.h"
136
 
137
/** @addtogroup STM32F0xx_HAL_Driver
138
  * @{
139
  */
140
 
141
/** @defgroup USART USART
142
  * @brief HAL USART Synchronous module driver
143
  * @{
144
  */
145
 
146
#ifdef HAL_USART_MODULE_ENABLED
147
 
148
/* Private typedef -----------------------------------------------------------*/
149
/* Private define ------------------------------------------------------------*/
150
/** @defgroup USART_Private_Constants USART Private Constants
151
  * @{
152
  */
153
#define USART_DUMMY_DATA          ((uint16_t) 0xFFFF)           /*!< USART transmitted dummy data                     */
154
#define USART_TEACK_REACK_TIMEOUT             1000U             /*!< USART TX or RX enable acknowledge time-out value */
155
#define USART_CR1_FIELDS          ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
156
                                              USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8))    /*!< USART CR1 fields of parameters set by USART_SetConfig API */
157
#define USART_CR2_FIELDS          ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
158
                                              USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
159
 
160
#define USART_BRR_MIN    0x10U        /* USART BRR minimum authorized value */
161
#define USART_BRR_MAX    0xFFFFU      /* USART BRR maximum authorized value */
162
/**
163
  * @}
164
  */
165
 
166
/* Private macros ------------------------------------------------------------*/
167
/* Private variables ---------------------------------------------------------*/
168
/* Private function prototypes -----------------------------------------------*/
169
/** @addtogroup USART_Private_Functions
170
  * @{
171
  */
172
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
173
void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
174
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
175
static void USART_EndTransfer(USART_HandleTypeDef *husart);
176
static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
177
static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
178
static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
179
static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
180
static void USART_DMAError(DMA_HandleTypeDef *hdma);
181
static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
182
static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
183
static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
184
static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
185
                                                      uint32_t Tickstart, uint32_t Timeout);
186
static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
187
static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
188
static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
189
static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
190
static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
191
static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
192
static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
193
 
194
 
195
/**
196
  * @}
197
  */
198
 
199
/* Exported functions --------------------------------------------------------*/
200
 
201
/** @defgroup USART_Exported_Functions USART Exported Functions
202
  * @{
203
  */
204
 
205
/** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
206
  * @brief    Initialization and Configuration functions
207
  *
208
@verbatim
209
 ===============================================================================
210
            ##### Initialization and Configuration functions #####
211
 ===============================================================================
212
    [..]
213
    This subsection provides a set of functions allowing to initialize the USART
214
    in asynchronous and in synchronous modes.
215
      (+) For the asynchronous mode only these parameters can be configured:
216
        (++) Baud Rate
217
        (++) Word Length
218
        (++) Stop Bit
219
        (++) Parity: If the parity is enabled, then the MSB bit of the data written
220
             in the data register is transmitted but is changed by the parity bit.
221
        (++) USART polarity
222
        (++) USART phase
223
        (++) USART LastBit
224
        (++) Receiver/transmitter modes
225
 
226
    [..]
227
    The HAL_USART_Init() function follows the USART  synchronous configuration
228
    procedure (details for the procedure are available in reference manual).
229
 
230
@endverbatim
231
 
232
  Depending on the frame length either defined by the M1 and M0 bits (7-bit,
233
  8-bit or 9-bit) or  by the M bit (8-bits or 9-bits), the possible USART formats
234
  are listed in the following table.
235
 
236
    Table 1. USART frame format.
237
    +-----------------------------------------------------------------------+
238
    |       M bit       |  PCE bit  |             USART frame               |
239
    |-------------------|-----------|---------------------------------------|
240
    |         0         |     0     |    | SB |    8-bit data   | STB |     |
241
    |-------------------|-----------|---------------------------------------|
242
    |         0         |     1     |    | SB | 7-bit data | PB | STB |     |
243
    |-------------------|-----------|---------------------------------------|
244
    |         1         |     0     |    | SB |    9-bit data   | STB |     |
245
    |-------------------|-----------|---------------------------------------|
246
    |         1         |     1     |    | SB | 8-bit data | PB | STB |     |
247
    +-----------------------------------------------------------------------+
248
    +-----------------------------------------------------------------------+
249
    |  M1 bit |  M0 bit |  PCE bit  |            USART frame                |
250
    |---------|---------|-----------|---------------------------------------|
251
    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
252
    |---------|---------|-----------|---------------------------------------|
253
    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
254
    |---------|---------|-----------|---------------------------------------|
255
    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
256
    |---------|---------|-----------|---------------------------------------|
257
    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
258
    |---------|---------|-----------|---------------------------------------|
259
    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
260
    |---------|---------|-----------|---------------------------------------|
261
    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
262
    +-----------------------------------------------------------------------+
263
 
264
  * @{
265
  */
266
 
267
/**
268
  * @brief  Initialize the USART mode according to the specified
269
  *         parameters in the USART_InitTypeDef and initialize the associated handle.
270
  * @param  husart USART handle.
271
  * @retval HAL status
272
  */
273
HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
274
{
275
  /* Check the USART handle allocation */
276
  if (husart == NULL)
277
  {
278
    return HAL_ERROR;
279
  }
280
 
281
  /* Check the parameters */
282
  assert_param(IS_USART_INSTANCE(husart->Instance));
283
 
284
  if (husart->State == HAL_USART_STATE_RESET)
285
  {
286
    /* Allocate lock resource and initialize it */
287
    husart->Lock = HAL_UNLOCKED;
288
 
289
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
290
    USART_InitCallbacksToDefault(husart);
291
 
292
    if (husart->MspInitCallback == NULL)
293
    {
294
      husart->MspInitCallback = HAL_USART_MspInit;
295
    }
296
 
297
    /* Init the low level hardware */
298
    husart->MspInitCallback(husart);
299
#else
300
    /* Init the low level hardware : GPIO, CLOCK */
301
    HAL_USART_MspInit(husart);
302
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
303
  }
304
 
305
  husart->State = HAL_USART_STATE_BUSY;
306
 
307
  /* Disable the Peripheral */
308
  __HAL_USART_DISABLE(husart);
309
 
310
  /* Set the Usart Communication parameters */
311
  if (USART_SetConfig(husart) == HAL_ERROR)
312
  {
313
    return HAL_ERROR;
314
  }
315
 
316
  /* In Synchronous mode, the following bits must be kept cleared:
317
  - LINEN bit (if LIN is supported) in the USART_CR2 register
318
  - SCEN (if Smartcard is supported), HDSEL and IREN (if IrDA is supported) bits in the USART_CR3 register.
319
  */
320
#if  defined (USART_CR2_LINEN)
321
  husart->Instance->CR2 &= ~USART_CR2_LINEN;
322
#endif /* USART_CR2_LINEN */
323
#if  defined (USART_CR3_SCEN)
324
#if  defined (USART_CR3_IREN)
325
  husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
326
#else
327
  husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL);
328
#endif /* USART_CR3_IREN */
329
#else
330
#if  defined (USART_CR3_IREN)
331
  husart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN);
332
#else
333
  husart->Instance->CR3 &= ~(USART_CR3_HDSEL);
334
#endif /* USART_CR3_IREN */
335
#endif /* USART_CR3_SCEN */
336
 
337
  /* Enable the Peripheral */
338
  __HAL_USART_ENABLE(husart);
339
 
340
  /* TEACK and/or REACK to check before moving husart->State to Ready */
341
  return (USART_CheckIdleState(husart));
342
}
343
 
344
/**
345
  * @brief DeInitialize the USART peripheral.
346
  * @param  husart USART handle.
347
  * @retval HAL status
348
  */
349
HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
350
{
351
  /* Check the USART handle allocation */
352
  if (husart == NULL)
353
  {
354
    return HAL_ERROR;
355
  }
356
 
357
  /* Check the parameters */
358
  assert_param(IS_USART_INSTANCE(husart->Instance));
359
 
360
  husart->State = HAL_USART_STATE_BUSY;
361
 
362
  husart->Instance->CR1 = 0x0U;
363
  husart->Instance->CR2 = 0x0U;
364
  husart->Instance->CR3 = 0x0U;
365
 
366
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
367
  if (husart->MspDeInitCallback == NULL)
368
  {
369
    husart->MspDeInitCallback = HAL_USART_MspDeInit;
370
  }
371
  /* DeInit the low level hardware */
372
  husart->MspDeInitCallback(husart);
373
#else
374
  /* DeInit the low level hardware */
375
  HAL_USART_MspDeInit(husart);
376
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
377
 
378
  husart->ErrorCode = HAL_USART_ERROR_NONE;
379
  husart->State = HAL_USART_STATE_RESET;
380
 
381
  /* Process Unlock */
382
  __HAL_UNLOCK(husart);
383
 
384
  return HAL_OK;
385
}
386
 
387
/**
388
  * @brief Initialize the USART MSP.
389
  * @param husart USART handle.
390
  * @retval None
391
  */
392
__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
393
{
394
  /* Prevent unused argument(s) compilation warning */
395
  UNUSED(husart);
396
 
397
  /* NOTE : This function should not be modified, when the callback is needed,
398
            the HAL_USART_MspInit can be implemented in the user file
399
   */
400
}
401
 
402
/**
403
  * @brief DeInitialize the USART MSP.
404
  * @param husart USART handle.
405
  * @retval None
406
  */
407
__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
408
{
409
  /* Prevent unused argument(s) compilation warning */
410
  UNUSED(husart);
411
 
412
  /* NOTE : This function should not be modified, when the callback is needed,
413
            the HAL_USART_MspDeInit can be implemented in the user file
414
   */
415
}
416
 
417
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
418
/**
419
  * @brief  Register a User USART Callback
420
  *         To be used instead of the weak predefined callback
421
  * @param  husart usart handle
422
  * @param  CallbackID ID of the callback to be registered
423
  *         This parameter can be one of the following values:
424
  *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
425
  *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
426
  *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
427
  *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
428
  *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
429
  *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
430
  *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
431
  *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
432
  *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
433
  * @param  pCallback pointer to the Callback function
434
  * @retval HAL status
435
+  */
436
HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
437
                                             pUSART_CallbackTypeDef pCallback)
438
{
439
  HAL_StatusTypeDef status = HAL_OK;
440
 
441
  if (pCallback == NULL)
442
  {
443
    /* Update the error code */
444
    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
445
 
446
    return HAL_ERROR;
447
  }
448
  /* Process locked */
449
  __HAL_LOCK(husart);
450
 
451
  if (husart->State == HAL_USART_STATE_READY)
452
  {
453
    switch (CallbackID)
454
    {
455
      case HAL_USART_TX_HALFCOMPLETE_CB_ID :
456
        husart->TxHalfCpltCallback = pCallback;
457
        break;
458
 
459
      case HAL_USART_TX_COMPLETE_CB_ID :
460
        husart->TxCpltCallback = pCallback;
461
        break;
462
 
463
      case HAL_USART_RX_HALFCOMPLETE_CB_ID :
464
        husart->RxHalfCpltCallback = pCallback;
465
        break;
466
 
467
      case HAL_USART_RX_COMPLETE_CB_ID :
468
        husart->RxCpltCallback = pCallback;
469
        break;
470
 
471
      case HAL_USART_TX_RX_COMPLETE_CB_ID :
472
        husart->TxRxCpltCallback = pCallback;
473
        break;
474
 
475
      case HAL_USART_ERROR_CB_ID :
476
        husart->ErrorCallback = pCallback;
477
        break;
478
 
479
      case HAL_USART_ABORT_COMPLETE_CB_ID :
480
        husart->AbortCpltCallback = pCallback;
481
        break;
482
 
483
 
484
      case HAL_USART_MSPINIT_CB_ID :
485
        husart->MspInitCallback = pCallback;
486
        break;
487
 
488
      case HAL_USART_MSPDEINIT_CB_ID :
489
        husart->MspDeInitCallback = pCallback;
490
        break;
491
 
492
      default :
493
        /* Update the error code */
494
        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
495
 
496
        /* Return error status */
497
        status =  HAL_ERROR;
498
        break;
499
    }
500
  }
501
  else if (husart->State == HAL_USART_STATE_RESET)
502
  {
503
    switch (CallbackID)
504
    {
505
      case HAL_USART_MSPINIT_CB_ID :
506
        husart->MspInitCallback = pCallback;
507
        break;
508
 
509
      case HAL_USART_MSPDEINIT_CB_ID :
510
        husart->MspDeInitCallback = pCallback;
511
        break;
512
 
513
      default :
514
        /* Update the error code */
515
        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
516
 
517
        /* Return error status */
518
        status =  HAL_ERROR;
519
        break;
520
    }
521
  }
522
  else
523
  {
524
    /* Update the error code */
525
    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
526
 
527
    /* Return error status */
528
    status =  HAL_ERROR;
529
  }
530
 
531
  /* Release Lock */
532
  __HAL_UNLOCK(husart);
533
 
534
  return status;
535
}
536
 
537
/**
538
  * @brief  Unregister an UART Callback
539
  *         UART callaback is redirected to the weak predefined callback
540
  * @param  husart uart handle
541
  * @param  CallbackID ID of the callback to be unregistered
542
  *         This parameter can be one of the following values:
543
  *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
544
  *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
545
  *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
546
  *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
547
  *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
548
  *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
549
  *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
550
  *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
551
  *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
552
  * @retval HAL status
553
  */
554
HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
555
{
556
  HAL_StatusTypeDef status = HAL_OK;
557
 
558
  /* Process locked */
559
  __HAL_LOCK(husart);
560
 
561
  if (HAL_USART_STATE_READY == husart->State)
562
  {
563
    switch (CallbackID)
564
    {
565
      case HAL_USART_TX_HALFCOMPLETE_CB_ID :
566
        husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback       */
567
        break;
568
 
569
      case HAL_USART_TX_COMPLETE_CB_ID :
570
        husart->TxCpltCallback = HAL_USART_TxCpltCallback;                       /* Legacy weak TxCpltCallback            */
571
        break;
572
 
573
      case HAL_USART_RX_HALFCOMPLETE_CB_ID :
574
        husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback        */
575
        break;
576
 
577
      case HAL_USART_RX_COMPLETE_CB_ID :
578
        husart->RxCpltCallback = HAL_USART_RxCpltCallback;                       /* Legacy weak RxCpltCallback            */
579
        break;
580
 
581
      case HAL_USART_TX_RX_COMPLETE_CB_ID :
582
        husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback;                   /* Legacy weak TxRxCpltCallback            */
583
        break;
584
 
585
      case HAL_USART_ERROR_CB_ID :
586
        husart->ErrorCallback = HAL_USART_ErrorCallback;                         /* Legacy weak ErrorCallback             */
587
        break;
588
 
589
      case HAL_USART_ABORT_COMPLETE_CB_ID :
590
        husart->AbortCpltCallback = HAL_USART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback         */
591
        break;
592
 
593
 
594
      case HAL_USART_MSPINIT_CB_ID :
595
        husart->MspInitCallback = HAL_USART_MspInit;                             /* Legacy weak MspInitCallback           */
596
        break;
597
 
598
      case HAL_USART_MSPDEINIT_CB_ID :
599
        husart->MspDeInitCallback = HAL_USART_MspDeInit;                         /* Legacy weak MspDeInitCallback         */
600
        break;
601
 
602
      default :
603
        /* Update the error code */
604
        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
605
 
606
        /* Return error status */
607
        status =  HAL_ERROR;
608
        break;
609
    }
610
  }
611
  else if (HAL_USART_STATE_RESET == husart->State)
612
  {
613
    switch (CallbackID)
614
    {
615
      case HAL_USART_MSPINIT_CB_ID :
616
        husart->MspInitCallback = HAL_USART_MspInit;
617
        break;
618
 
619
      case HAL_USART_MSPDEINIT_CB_ID :
620
        husart->MspDeInitCallback = HAL_USART_MspDeInit;
621
        break;
622
 
623
      default :
624
        /* Update the error code */
625
        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
626
 
627
        /* Return error status */
628
        status =  HAL_ERROR;
629
        break;
630
    }
631
  }
632
  else
633
  {
634
    /* Update the error code */
635
    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
636
 
637
    /* Return error status */
638
    status =  HAL_ERROR;
639
  }
640
 
641
  /* Release Lock */
642
  __HAL_UNLOCK(husart);
643
 
644
  return status;
645
}
646
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
647
 
648
 
649
/**
650
  * @}
651
  */
652
 
653
/** @defgroup USART_Exported_Functions_Group2 IO operation functions
654
  * @brief   USART Transmit and Receive functions
655
  *
656
@verbatim
657
 ===============================================================================
658
                      ##### IO operation functions #####
659
 ===============================================================================
660
    [..] This subsection provides a set of functions allowing to manage the USART synchronous
661
    data transfers.
662
 
663
    [..] The USART supports master mode only: it cannot receive or send data related to an input
664
         clock (SCLK is always an output).
665
 
666
    [..]
667
 
668
    (#) There are two modes of transfer:
669
        (++) Blocking mode: The communication is performed in polling mode.
670
             The HAL status of all data processing is returned by the same function
671
             after finishing transfer.
672
        (++) No-Blocking mode: The communication is performed using Interrupts
673
             or DMA, These API's return the HAL status.
674
             The end of the data processing will be indicated through the
675
             dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
676
             using DMA mode.
677
             The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
678
             will be executed respectively at the end of the transmit or Receive process
679
             The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
680
 
681
    (#) Blocking mode API's are :
682
        (++) HAL_USART_Transmit() in simplex mode
683
        (++) HAL_USART_Receive() in full duplex receive only
684
        (++) HAL_USART_TransmitReceive() in full duplex mode
685
 
686
    (#) Non-Blocking mode API's with Interrupt are :
687
        (++) HAL_USART_Transmit_IT() in simplex mode
688
        (++) HAL_USART_Receive_IT() in full duplex receive only
689
        (++) HAL_USART_TransmitReceive_IT() in full duplex mode
690
        (++) HAL_USART_IRQHandler()
691
 
692
    (#) No-Blocking mode API's  with DMA are :
693
        (++) HAL_USART_Transmit_DMA() in simplex mode
694
        (++) HAL_USART_Receive_DMA() in full duplex receive only
695
        (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
696
        (++) HAL_USART_DMAPause()
697
        (++) HAL_USART_DMAResume()
698
        (++) HAL_USART_DMAStop()
699
 
700
    (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
701
        (++) HAL_USART_TxCpltCallback()
702
        (++) HAL_USART_RxCpltCallback()
703
        (++) HAL_USART_TxHalfCpltCallback()
704
        (++) HAL_USART_RxHalfCpltCallback()
705
        (++) HAL_USART_ErrorCallback()
706
        (++) HAL_USART_TxRxCpltCallback()
707
 
708
    (#) Non-Blocking mode transfers could be aborted using Abort API's :
709
        (++) HAL_USART_Abort()
710
        (++) HAL_USART_Abort_IT()
711
 
712
    (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
713
        (++) HAL_USART_AbortCpltCallback()
714
 
715
    (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
716
        Errors are handled as follows :
717
        (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
718
             to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
719
             Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
720
             and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
721
             If user wants to abort it, Abort services should be called by user.
722
        (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
723
             This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
724
             Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
725
 
726
@endverbatim
727
  * @{
728
  */
729
 
730
/**
731
  * @brief  Simplex send an amount of data in blocking mode.
732
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
733
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
734
  *         of u16 provided through pTxData.
735
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
736
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
737
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
738
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData.
739
  * @param  husart USART handle.
740
  * @param  pTxData Pointer to data buffer (u8 or u16 data elements).
741
  * @param  Size Amount of data elements (u8 or u16) to be sent.
742
  * @param  Timeout Timeout duration.
743
  * @retval HAL status
744
  */
745
HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
746
{
747
  uint8_t  *ptxdata8bits;
748
  uint16_t *ptxdata16bits;
749
  uint32_t tickstart;
750
 
751
  if (husart->State == HAL_USART_STATE_READY)
752
  {
753
    if ((pTxData == NULL) || (Size == 0U))
754
    {
755
      return  HAL_ERROR;
756
    }
757
 
758
    /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
759
       should be aligned on a u16 frontier, as data to be filled into TDR will be
760
       handled through a u16 cast. */
761
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
762
    {
763
      if ((((uint32_t)pTxData) & 1U) != 0U)
764
      {
765
        return  HAL_ERROR;
766
      }
767
    }
768
 
769
    /* Process Locked */
770
    __HAL_LOCK(husart);
771
 
772
    husart->ErrorCode = HAL_USART_ERROR_NONE;
773
    husart->State = HAL_USART_STATE_BUSY_TX;
774
 
775
    /* Init tickstart for timeout managment*/
776
    tickstart = HAL_GetTick();
777
 
778
    husart->TxXferSize = Size;
779
    husart->TxXferCount = Size;
780
 
781
    /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
782
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
783
    {
784
      ptxdata8bits  = NULL;
785
      ptxdata16bits = (uint16_t *) pTxData;
786
    }
787
    else
788
    {
789
      ptxdata8bits  = pTxData;
790
      ptxdata16bits = NULL;
791
    }
792
 
793
    /* Check the remaining data to be sent */
794
    while (husart->TxXferCount > 0U)
795
    {
796
      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
797
      {
798
        return HAL_TIMEOUT;
799
      }
800
      if (ptxdata8bits == NULL)
801
      {
802
        husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
803
        ptxdata16bits++;
804
      }
805
      else
806
      {
807
        husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
808
        ptxdata8bits++;
809
      }
810
 
811
      husart->TxXferCount--;
812
    }
813
 
814
    if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
815
    {
816
      return HAL_TIMEOUT;
817
    }
818
 
819
    /* Clear Transmission Complete Flag */
820
    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
821
 
822
    /* Clear overrun flag and discard the received data */
823
    __HAL_USART_CLEAR_OREFLAG(husart);
824
    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
825
#if   defined(USART_RQR_TXFRQ)
826
    __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
827
#endif /* USART_RQR_TXFRQ */
828
 
829
    /* At end of Tx process, restore husart->State to Ready */
830
    husart->State = HAL_USART_STATE_READY;
831
 
832
    /* Process Unlocked */
833
    __HAL_UNLOCK(husart);
834
 
835
    return HAL_OK;
836
  }
837
  else
838
  {
839
    return HAL_BUSY;
840
  }
841
}
842
 
843
/**
844
  * @brief Receive an amount of data in blocking mode.
845
  * @note   To receive synchronous data, dummy data are simultaneously transmitted.
846
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
847
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
848
  *         of u16 available through pRxData.
849
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
850
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
851
  *         (as received data will be handled using u16 pointer cast). Depending on compilation chain,
852
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pRxData.
853
  * @param husart USART handle.
854
  * @param pRxData Pointer to data buffer (u8 or u16 data elements).
855
  * @param Size Amount of data elements (u8 or u16) to be received.
856
  * @param Timeout Timeout duration.
857
  * @retval HAL status
858
  */
859
HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
860
{
861
  uint8_t  *prxdata8bits;
862
  uint16_t *prxdata16bits;
863
  uint16_t uhMask;
864
  uint32_t tickstart;
865
 
866
  if (husart->State == HAL_USART_STATE_READY)
867
  {
868
    if ((pRxData == NULL) || (Size == 0U))
869
    {
870
      return  HAL_ERROR;
871
    }
872
 
873
    /* In case of 9bits/No Parity transfer, pRxData buffer provided as input parameter
874
       should be aligned on a u16 frontier, as data to be received from RDR will be
875
       handled through a u16 cast. */
876
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
877
    {
878
      if ((((uint32_t)pRxData) & 1U) != 0U)
879
      {
880
        return  HAL_ERROR;
881
      }
882
    }
883
 
884
    /* Process Locked */
885
    __HAL_LOCK(husart);
886
 
887
    husart->ErrorCode = HAL_USART_ERROR_NONE;
888
    husart->State = HAL_USART_STATE_BUSY_RX;
889
 
890
    /* Init tickstart for timeout managment*/
891
    tickstart = HAL_GetTick();
892
 
893
    husart->RxXferSize = Size;
894
    husart->RxXferCount = Size;
895
 
896
    /* Computation of USART mask to apply to RDR register */
897
    USART_MASK_COMPUTATION(husart);
898
    uhMask = husart->Mask;
899
 
900
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
901
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
902
    {
903
      prxdata8bits  = NULL;
904
      prxdata16bits = (uint16_t *) pRxData;
905
    }
906
    else
907
    {
908
      prxdata8bits  = pRxData;
909
      prxdata16bits = NULL;
910
    }
911
 
912
    /* as long as data have to be received */
913
    while (husart->RxXferCount > 0U)
914
    {
915
      {
916
        /* Wait until TXE flag is set to send dummy byte in order to generate the
917
        * clock for the slave to send data.
918
        * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
919
        * can be written for all the cases. */
920
        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
921
        {
922
          return HAL_TIMEOUT;
923
        }
924
        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
925
      }
926
 
927
      /* Wait for RXNE Flag */
928
      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
929
      {
930
        return HAL_TIMEOUT;
931
      }
932
 
933
      if (prxdata8bits == NULL)
934
      {
935
        *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
936
        prxdata16bits++;
937
      }
938
      else
939
      {
940
        *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
941
        prxdata8bits++;
942
      }
943
 
944
      husart->RxXferCount--;
945
 
946
    }
947
 
948
 
949
    /* At end of Rx process, restore husart->State to Ready */
950
    husart->State = HAL_USART_STATE_READY;
951
 
952
    /* Process Unlocked */
953
    __HAL_UNLOCK(husart);
954
 
955
    return HAL_OK;
956
  }
957
  else
958
  {
959
    return HAL_BUSY;
960
  }
961
}
962
 
963
/**
964
  * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
965
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
966
  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
967
  *         of u16 available through pTxData and through pRxData.
968
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
969
  *         address of user data buffers containing data to be sent/received, should be aligned on a half word frontier (16 bits)
970
  *         (as sent/received data will be handled using u16 pointer cast). Depending on compilation chain,
971
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData and pRxData.
972
  * @param  husart USART handle.
973
  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
974
  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
975
  * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
976
  * @param  Timeout Timeout duration.
977
  * @retval HAL status
978
  */
979
HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
980
                                            uint16_t Size, uint32_t Timeout)
981
{
982
  uint8_t  *prxdata8bits;
983
  uint16_t *prxdata16bits;
984
  uint8_t  *ptxdata8bits;
985
  uint16_t *ptxdata16bits;
986
  uint16_t uhMask;
987
  uint16_t rxdatacount;
988
  uint32_t tickstart;
989
 
990
  if (husart->State == HAL_USART_STATE_READY)
991
  {
992
    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
993
    {
994
      return  HAL_ERROR;
995
    }
996
 
997
    /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input parameter
998
       should be aligned on a u16 frontier, as data to be filled into TDR/retrieved from RDR will be
999
       handled through a u16 cast. */
1000
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1001
    {
1002
      if (((((uint32_t)pTxData) & 1U) != 0U) || ((((uint32_t)pRxData) & 1U) != 0U))
1003
      {
1004
        return  HAL_ERROR;
1005
      }
1006
    }
1007
 
1008
    /* Process Locked */
1009
    __HAL_LOCK(husart);
1010
 
1011
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1012
    husart->State = HAL_USART_STATE_BUSY_RX;
1013
 
1014
    /* Init tickstart for timeout managment*/
1015
    tickstart = HAL_GetTick();
1016
 
1017
    husart->RxXferSize = Size;
1018
    husart->TxXferSize = Size;
1019
    husart->TxXferCount = Size;
1020
    husart->RxXferCount = Size;
1021
 
1022
    /* Computation of USART mask to apply to RDR register */
1023
    USART_MASK_COMPUTATION(husart);
1024
    uhMask = husart->Mask;
1025
 
1026
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1027
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1028
    {
1029
      prxdata8bits  = NULL;
1030
      ptxdata8bits  = NULL;
1031
      ptxdata16bits = (uint16_t *) pTxData;
1032
      prxdata16bits = (uint16_t *) pRxData;
1033
    }
1034
    else
1035
    {
1036
      prxdata8bits  = pRxData;
1037
      ptxdata8bits  = pTxData;
1038
      ptxdata16bits = NULL;
1039
      prxdata16bits = NULL;
1040
    }
1041
 
1042
    if (husart->TxXferCount == 0x01U)
1043
    {
1044
      /* Wait until TXE flag is set to send data */
1045
      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1046
      {
1047
        return HAL_TIMEOUT;
1048
      }
1049
      if (ptxdata8bits == NULL)
1050
      {
1051
        husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1052
        ptxdata16bits++;
1053
      }
1054
      else
1055
      {
1056
        husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1057
        ptxdata8bits++;
1058
      }
1059
 
1060
      husart->TxXferCount--;
1061
    }
1062
 
1063
    /* Check the remain data to be sent */
1064
    /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1065
    rxdatacount = husart->RxXferCount;
1066
    while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
1067
    {
1068
      if (husart->TxXferCount > 0U)
1069
      {
1070
        /* Wait until TXE flag is set to send data */
1071
        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1072
        {
1073
          return HAL_TIMEOUT;
1074
        }
1075
        if (ptxdata8bits == NULL)
1076
        {
1077
          husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1078
          ptxdata16bits++;
1079
        }
1080
        else
1081
        {
1082
          husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1083
          ptxdata8bits++;
1084
        }
1085
 
1086
        husart->TxXferCount--;
1087
      }
1088
 
1089
      if (husart->RxXferCount > 0U)
1090
      {
1091
        /* Wait for RXNE Flag */
1092
        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1093
        {
1094
          return HAL_TIMEOUT;
1095
        }
1096
 
1097
        if (prxdata8bits == NULL)
1098
        {
1099
          *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1100
          prxdata16bits++;
1101
        }
1102
        else
1103
        {
1104
          *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1105
          prxdata8bits++;
1106
        }
1107
 
1108
        husart->RxXferCount--;
1109
      }
1110
      rxdatacount = husart->RxXferCount;
1111
    }
1112
 
1113
    /* At end of TxRx process, restore husart->State to Ready */
1114
    husart->State = HAL_USART_STATE_READY;
1115
 
1116
    /* Process Unlocked */
1117
    __HAL_UNLOCK(husart);
1118
 
1119
    return HAL_OK;
1120
  }
1121
  else
1122
  {
1123
    return HAL_BUSY;
1124
  }
1125
}
1126
 
1127
/**
1128
  * @brief  Send an amount of data in interrupt mode.
1129
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1130
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1131
  *         of u16 provided through pTxData.
1132
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1133
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1134
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1135
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData.
1136
  * @param  husart USART handle.
1137
  * @param  pTxData pointer to data buffer (u8 or u16 data elements).
1138
  * @param  Size amount of data elements (u8 or u16) to be sent.
1139
  * @retval HAL status
1140
  */
1141
HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
1142
{
1143
  if (husart->State == HAL_USART_STATE_READY)
1144
  {
1145
    if ((pTxData == NULL) || (Size == 0U))
1146
    {
1147
      return HAL_ERROR;
1148
    }
1149
 
1150
    /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
1151
       should be aligned on a u16 frontier, as data to be filled into TDR will be
1152
       handled through a u16 cast. */
1153
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1154
    {
1155
      if ((((uint32_t)pTxData) & 1U) != 0U)
1156
      {
1157
        return  HAL_ERROR;
1158
      }
1159
    }
1160
 
1161
    /* Process Locked */
1162
    __HAL_LOCK(husart);
1163
 
1164
    husart->pTxBuffPtr  = pTxData;
1165
    husart->TxXferSize  = Size;
1166
    husart->TxXferCount = Size;
1167
    husart->TxISR       = NULL;
1168
 
1169
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1170
    husart->State     = HAL_USART_STATE_BUSY_TX;
1171
 
1172
    /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1173
    are not managed by the USART Transmit Process to avoid the overrun interrupt
1174
    when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1175
    to benefit for the frame error and noise interrupts the usart mode should be
1176
    configured only for transmit "USART_MODE_TX" */
1177
 
1178
    {
1179
      /* Set the Tx ISR function pointer according to the data word length */
1180
      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1181
      {
1182
        husart->TxISR = USART_TxISR_16BIT;
1183
      }
1184
      else
1185
      {
1186
        husart->TxISR = USART_TxISR_8BIT;
1187
      }
1188
 
1189
      /* Process Unlocked */
1190
      __HAL_UNLOCK(husart);
1191
 
1192
      /* Enable the USART Transmit Data Register Empty Interrupt */
1193
      __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1194
    }
1195
 
1196
    return HAL_OK;
1197
  }
1198
  else
1199
  {
1200
    return HAL_BUSY;
1201
  }
1202
}
1203
 
1204
/**
1205
  * @brief Receive an amount of data in interrupt mode.
1206
  * @note   To receive synchronous data, dummy data are simultaneously transmitted.
1207
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1208
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
1209
  *         of u16 available through pRxData.
1210
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1211
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
1212
  *         (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1213
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pRxData.
1214
  * @param  husart USART handle.
1215
  * @param  pRxData pointer to data buffer (u8 or u16 data elements).
1216
  * @param  Size amount of data elements (u8 or u16) to be received.
1217
  * @retval HAL status
1218
  */
1219
HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1220
{
1221
 
1222
  if (husart->State == HAL_USART_STATE_READY)
1223
  {
1224
    if ((pRxData == NULL) || (Size == 0U))
1225
    {
1226
      return HAL_ERROR;
1227
    }
1228
 
1229
    /* In case of 9bits/No Parity transfer, pRxData buffer provided as input parameter
1230
       should be aligned on a u16 frontier, as data to be received from RDR will be
1231
       handled through a u16 cast. */
1232
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1233
    {
1234
      if ((((uint32_t)pRxData) & 1U) != 0U)
1235
      {
1236
        return  HAL_ERROR;
1237
      }
1238
    }
1239
 
1240
    /* Process Locked */
1241
    __HAL_LOCK(husart);
1242
 
1243
    husart->pRxBuffPtr  = pRxData;
1244
    husart->RxXferSize  = Size;
1245
    husart->RxXferCount = Size;
1246
    husart->RxISR       = NULL;
1247
 
1248
    USART_MASK_COMPUTATION(husart);
1249
 
1250
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1251
    husart->State = HAL_USART_STATE_BUSY_RX;
1252
 
1253
    /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1254
    SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1255
 
1256
    {
1257
      /* Set the Rx ISR function pointer according to the data word length */
1258
      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1259
      {
1260
        husart->RxISR = USART_RxISR_16BIT;
1261
      }
1262
      else
1263
      {
1264
        husart->RxISR = USART_RxISR_8BIT;
1265
      }
1266
 
1267
      /* Process Unlocked */
1268
      __HAL_UNLOCK(husart);
1269
 
1270
      /* Enable the USART Parity Error and Data Register not empty Interrupts */
1271
      SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1272
    }
1273
 
1274
    {
1275
      /* Send dummy data in order to generate the clock for the Slave to send the next data.
1276
      */
1277
      {
1278
        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1279
      }
1280
    }
1281
 
1282
    return HAL_OK;
1283
  }
1284
  else
1285
  {
1286
    return HAL_BUSY;
1287
  }
1288
}
1289
 
1290
/**
1291
  * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1292
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1293
  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1294
  *         of u16 available through pTxData and through pRxData.
1295
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1296
  *         address of user data buffers containing data to be sent/received, should be aligned on a half word frontier (16 bits)
1297
  *         (as sent/received data will be handled using u16 pointer cast). Depending on compilation chain,
1298
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData and pRxData.
1299
  * @param  husart USART handle.
1300
  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
1301
  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
1302
  * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1303
  * @retval HAL status
1304
  */
1305
HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
1306
                                               uint16_t Size)
1307
{
1308
 
1309
  if (husart->State == HAL_USART_STATE_READY)
1310
  {
1311
    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1312
    {
1313
      return HAL_ERROR;
1314
    }
1315
 
1316
    /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input parameter
1317
       should be aligned on a u16 frontier, as data to be filled into TDR/retrieved from RDR will be
1318
       handled through a u16 cast. */
1319
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1320
    {
1321
      if (((((uint32_t)pTxData) & 1U) != 0U) || ((((uint32_t)pRxData) & 1U) != 0U))
1322
      {
1323
        return  HAL_ERROR;
1324
      }
1325
    }
1326
 
1327
    /* Process Locked */
1328
    __HAL_LOCK(husart);
1329
 
1330
    husart->pRxBuffPtr = pRxData;
1331
    husart->RxXferSize = Size;
1332
    husart->RxXferCount = Size;
1333
    husart->pTxBuffPtr = pTxData;
1334
    husart->TxXferSize = Size;
1335
    husart->TxXferCount = Size;
1336
 
1337
    /* Computation of USART mask to apply to RDR register */
1338
    USART_MASK_COMPUTATION(husart);
1339
 
1340
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1341
    husart->State = HAL_USART_STATE_BUSY_TX_RX;
1342
 
1343
    {
1344
      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1345
      {
1346
        husart->TxISR = USART_TxISR_16BIT;
1347
        husart->RxISR = USART_RxISR_16BIT;
1348
      }
1349
      else
1350
      {
1351
        husart->TxISR = USART_TxISR_8BIT;
1352
        husart->RxISR = USART_RxISR_8BIT;
1353
      }
1354
 
1355
      /* Process Locked */
1356
      __HAL_UNLOCK(husart);
1357
 
1358
      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1359
      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1360
 
1361
      /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1362
      SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1363
 
1364
      /* Enable the USART Transmit Data Register Empty Interrupt */
1365
      SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
1366
    }
1367
 
1368
    return HAL_OK;
1369
  }
1370
  else
1371
  {
1372
    return HAL_BUSY;
1373
  }
1374
}
1375
 
1376
/**
1377
  * @brief Send an amount of data in DMA mode.
1378
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1379
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1380
  *         of u16 provided through pTxData.
1381
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1382
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1383
  *         (as sent data will be handled by DMA from halfword frontier). Depending on compilation chain,
1384
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData.
1385
  * @param  husart USART handle.
1386
  * @param  pTxData pointer to data buffer (u8 or u16 data elements).
1387
  * @param  Size amount of data elements (u8 or u16) to be sent.
1388
  * @retval HAL status
1389
  */
1390
HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
1391
{
1392
  HAL_StatusTypeDef status = HAL_OK;
1393
  uint32_t *tmp;
1394
 
1395
  if (husart->State == HAL_USART_STATE_READY)
1396
  {
1397
    if ((pTxData == NULL) || (Size == 0U))
1398
    {
1399
      return HAL_ERROR;
1400
    }
1401
 
1402
    /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
1403
       should be aligned on a u16 frontier, as data copy into TDR will be
1404
       handled by DMA from a u16 frontier. */
1405
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1406
    {
1407
      if ((((uint32_t)pTxData) & 1U) != 0U)
1408
      {
1409
        return  HAL_ERROR;
1410
      }
1411
    }
1412
 
1413
    /* Process Locked */
1414
    __HAL_LOCK(husart);
1415
 
1416
    husart->pTxBuffPtr = pTxData;
1417
    husart->TxXferSize = Size;
1418
    husart->TxXferCount = Size;
1419
 
1420
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1421
    husart->State = HAL_USART_STATE_BUSY_TX;
1422
 
1423
    if (husart->hdmatx != NULL)
1424
    {
1425
      /* Set the USART DMA transfer complete callback */
1426
      husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1427
 
1428
      /* Set the USART DMA Half transfer complete callback */
1429
      husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1430
 
1431
      /* Set the DMA error callback */
1432
      husart->hdmatx->XferErrorCallback = USART_DMAError;
1433
 
1434
      /* Enable the USART transmit DMA channel */
1435
      tmp = (uint32_t *)&pTxData;
1436
      status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1437
    }
1438
 
1439
    if (status == HAL_OK)
1440
    {
1441
      /* Clear the TC flag in the ICR register */
1442
      __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1443
 
1444
      /* Process Unlocked */
1445
      __HAL_UNLOCK(husart);
1446
 
1447
      /* Enable the DMA transfer for transmit request by setting the DMAT bit
1448
         in the USART CR3 register */
1449
      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1450
 
1451
      return HAL_OK;
1452
    }
1453
    else
1454
    {
1455
      /* Set error code to DMA */
1456
      husart->ErrorCode = HAL_USART_ERROR_DMA;
1457
 
1458
      /* Process Unlocked */
1459
      __HAL_UNLOCK(husart);
1460
 
1461
      /* Restore husart->State to ready */
1462
      husart->State = HAL_USART_STATE_READY;
1463
 
1464
      return HAL_ERROR;
1465
    }
1466
  }
1467
  else
1468
  {
1469
    return HAL_BUSY;
1470
  }
1471
}
1472
 
1473
/**
1474
  * @brief Receive an amount of data in DMA mode.
1475
  * @note   When the USART parity is enabled (PCE = 1), the received data contain
1476
  *         the parity bit (MSB position).
1477
  * @note   The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1478
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1479
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
1480
  *         of u16 available through pRxData.
1481
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1482
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
1483
  *         (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1484
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pRxData.
1485
  * @param  husart USART handle.
1486
  * @param  pRxData pointer to data buffer (u8 or u16 data elements).
1487
  * @param  Size amount of data elements (u8 or u16) to be received.
1488
  * @retval HAL status
1489
  */
1490
HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1491
{
1492
  HAL_StatusTypeDef status = HAL_OK;
1493
  uint32_t *tmp = (uint32_t *)&pRxData;
1494
 
1495
  /* Check that a Rx process is not already ongoing */
1496
  if (husart->State == HAL_USART_STATE_READY)
1497
  {
1498
    if ((pRxData == NULL) || (Size == 0U))
1499
    {
1500
      return HAL_ERROR;
1501
    }
1502
 
1503
    /* In case of 9bits/No Parity transfer, pRxData buffer provided as input parameter
1504
       should be aligned on a u16 frontier, as data copy from RDR will be
1505
       handled by DMA from a u16 frontier. */
1506
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1507
    {
1508
      if ((((uint32_t)pRxData) & 1U) != 0U)
1509
      {
1510
        return  HAL_ERROR;
1511
      }
1512
    }
1513
 
1514
    /* Process Locked */
1515
    __HAL_LOCK(husart);
1516
 
1517
    husart->pRxBuffPtr = pRxData;
1518
    husart->RxXferSize = Size;
1519
    husart->pTxBuffPtr = pRxData;
1520
    husart->TxXferSize = Size;
1521
 
1522
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1523
    husart->State = HAL_USART_STATE_BUSY_RX;
1524
 
1525
    if (husart->hdmarx != NULL)
1526
    {
1527
      /* Set the USART DMA Rx transfer complete callback */
1528
      husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1529
 
1530
      /* Set the USART DMA Half transfer complete callback */
1531
      husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1532
 
1533
      /* Set the USART DMA Rx transfer error callback */
1534
      husart->hdmarx->XferErrorCallback = USART_DMAError;
1535
 
1536
      /* Enable the USART receive DMA channel */
1537
      status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1538
    }
1539
 
1540
    {
1541
      /* Enable the USART transmit DMA channel: the transmit channel is used in order
1542
         to generate in the non-blocking mode the clock to the slave device,
1543
         this mode isn't a simplex receive mode but a full-duplex receive mode */
1544
 
1545
      /* Set the USART DMA Tx Complete and Error callback to Null */
1546
      if (husart->hdmatx != NULL)
1547
      {
1548
        husart->hdmatx->XferErrorCallback = NULL;
1549
        husart->hdmatx->XferHalfCpltCallback = NULL;
1550
        husart->hdmatx->XferCpltCallback = NULL;
1551
        status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1552
      }
1553
    }
1554
 
1555
    if (status == HAL_OK)
1556
    {
1557
      /* Process Unlocked */
1558
      __HAL_UNLOCK(husart);
1559
 
1560
      /* Enable the USART Parity Error Interrupt */
1561
      SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1562
 
1563
      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1564
      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1565
 
1566
      /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1567
         in the USART CR3 register */
1568
      SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1569
 
1570
      /* Enable the DMA transfer for transmit request by setting the DMAT bit
1571
         in the USART CR3 register */
1572
      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1573
 
1574
      return HAL_OK;
1575
    }
1576
    else
1577
    {
1578
      if (husart->hdmarx != NULL)
1579
      {
1580
        status = HAL_DMA_Abort(husart->hdmarx);
1581
      }
1582
 
1583
      /* No need to check on error code */
1584
      UNUSED(status);
1585
 
1586
      /* Set error code to DMA */
1587
      husart->ErrorCode = HAL_USART_ERROR_DMA;
1588
 
1589
      /* Process Unlocked */
1590
      __HAL_UNLOCK(husart);
1591
 
1592
      /* Restore husart->State to ready */
1593
      husart->State = HAL_USART_STATE_READY;
1594
 
1595
      return HAL_ERROR;
1596
    }
1597
  }
1598
  else
1599
  {
1600
    return HAL_BUSY;
1601
  }
1602
}
1603
 
1604
/**
1605
  * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1606
  * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1607
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1608
  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1609
  *         of u16 available through pTxData and through pRxData.
1610
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1611
  *         address of user data buffers containing data to be sent/received, should be aligned on a half word frontier (16 bits)
1612
  *         (as sent/received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1613
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData and pRxData.
1614
  * @param  husart USART handle.
1615
  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
1616
  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
1617
  * @param  Size amount of data elements (u8 or u16) to be received/sent.
1618
  * @retval HAL status
1619
  */
1620
HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
1621
                                                uint16_t Size)
1622
{
1623
  HAL_StatusTypeDef status;
1624
  uint32_t *tmp;
1625
 
1626
  if (husart->State == HAL_USART_STATE_READY)
1627
  {
1628
    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1629
    {
1630
      return HAL_ERROR;
1631
    }
1632
 
1633
    /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input parameter
1634
       should be aligned on a u16 frontier, as data copy to/from TDR/RDR will be
1635
       handled by DMA from a u16 frontier. */
1636
    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1637
    {
1638
      if (((((uint32_t)pTxData) & 1U) != 0U) || ((((uint32_t)pRxData) & 1U) != 0U))
1639
      {
1640
        return  HAL_ERROR;
1641
      }
1642
    }
1643
 
1644
    /* Process Locked */
1645
    __HAL_LOCK(husart);
1646
 
1647
    husart->pRxBuffPtr = pRxData;
1648
    husart->RxXferSize = Size;
1649
    husart->pTxBuffPtr = pTxData;
1650
    husart->TxXferSize = Size;
1651
 
1652
    husart->ErrorCode = HAL_USART_ERROR_NONE;
1653
    husart->State = HAL_USART_STATE_BUSY_TX_RX;
1654
 
1655
    if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1656
    {
1657
      /* Set the USART DMA Rx transfer complete callback */
1658
      husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1659
 
1660
      /* Set the USART DMA Half transfer complete callback */
1661
      husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1662
 
1663
      /* Set the USART DMA Tx transfer complete callback */
1664
      husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1665
 
1666
      /* Set the USART DMA Half transfer complete callback */
1667
      husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1668
 
1669
      /* Set the USART DMA Tx transfer error callback */
1670
      husart->hdmatx->XferErrorCallback = USART_DMAError;
1671
 
1672
      /* Set the USART DMA Rx transfer error callback */
1673
      husart->hdmarx->XferErrorCallback = USART_DMAError;
1674
 
1675
      /* Enable the USART receive DMA channel */
1676
      tmp = (uint32_t *)&pRxData;
1677
      status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1678
 
1679
      /* Enable the USART transmit DMA channel */
1680
      if (status == HAL_OK)
1681
      {
1682
        tmp = (uint32_t *)&pTxData;
1683
        status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1684
      }
1685
    }
1686
    else
1687
    {
1688
      status = HAL_ERROR;
1689
    }
1690
 
1691
    if (status == HAL_OK)
1692
    {
1693
      /* Process Unlocked */
1694
      __HAL_UNLOCK(husart);
1695
 
1696
      /* Enable the USART Parity Error Interrupt */
1697
      SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1698
 
1699
      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1700
      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1701
 
1702
      /* Clear the TC flag in the ICR register */
1703
      __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1704
 
1705
      /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1706
         in the USART CR3 register */
1707
      SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1708
 
1709
      /* Enable the DMA transfer for transmit request by setting the DMAT bit
1710
         in the USART CR3 register */
1711
      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1712
 
1713
      return HAL_OK;
1714
    }
1715
    else
1716
    {
1717
      if (husart->hdmarx != NULL)
1718
      {
1719
        status = HAL_DMA_Abort(husart->hdmarx);
1720
      }
1721
 
1722
      /* No need to check on error code */
1723
      UNUSED(status);
1724
 
1725
      /* Set error code to DMA */
1726
      husart->ErrorCode = HAL_USART_ERROR_DMA;
1727
 
1728
      /* Process Unlocked */
1729
      __HAL_UNLOCK(husart);
1730
 
1731
      /* Restore husart->State to ready */
1732
      husart->State = HAL_USART_STATE_READY;
1733
 
1734
      return HAL_ERROR;
1735
    }
1736
  }
1737
  else
1738
  {
1739
    return HAL_BUSY;
1740
  }
1741
}
1742
 
1743
/**
1744
  * @brief Pause the DMA Transfer.
1745
  * @param  husart USART handle.
1746
  * @retval HAL status
1747
  */
1748
HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1749
{
1750
  const HAL_USART_StateTypeDef state = husart->State;
1751
 
1752
  /* Process Locked */
1753
  __HAL_LOCK(husart);
1754
 
1755
  if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1756
      (state == HAL_USART_STATE_BUSY_TX))
1757
  {
1758
    /* Disable the USART DMA Tx request */
1759
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1760
  }
1761
  else if ((state == HAL_USART_STATE_BUSY_RX) ||
1762
           (state == HAL_USART_STATE_BUSY_TX_RX))
1763
  {
1764
    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1765
    {
1766
      /* Disable the USART DMA Tx request */
1767
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1768
    }
1769
    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1770
    {
1771
      /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1772
      CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1773
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1774
 
1775
      /* Disable the USART DMA Rx request */
1776
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1777
    }
1778
  }
1779
  else
1780
  {
1781
    /* Nothing to do */
1782
  }
1783
 
1784
  /* Process Unlocked */
1785
  __HAL_UNLOCK(husart);
1786
 
1787
  return HAL_OK;
1788
}
1789
 
1790
/**
1791
  * @brief Resume the DMA Transfer.
1792
  * @param  husart USART handle.
1793
  * @retval HAL status
1794
  */
1795
HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1796
{
1797
  const HAL_USART_StateTypeDef state = husart->State;
1798
 
1799
  /* Process Locked */
1800
  __HAL_LOCK(husart);
1801
 
1802
  if (state == HAL_USART_STATE_BUSY_TX)
1803
  {
1804
    /* Enable the USART DMA Tx request */
1805
    SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1806
  }
1807
  else if ((state == HAL_USART_STATE_BUSY_RX) ||
1808
           (state == HAL_USART_STATE_BUSY_TX_RX))
1809
  {
1810
    /* Clear the Overrun flag before resuming the Rx transfer*/
1811
    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
1812
 
1813
    /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1814
    SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1815
    SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1816
 
1817
    /* Enable the USART DMA Rx request  before the DMA Tx request */
1818
    SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1819
 
1820
    /* Enable the USART DMA Tx request */
1821
    SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1822
  }
1823
  else
1824
  {
1825
    /* Nothing to do */
1826
  }
1827
 
1828
  /* Process Unlocked */
1829
  __HAL_UNLOCK(husart);
1830
 
1831
  return HAL_OK;
1832
}
1833
 
1834
/**
1835
  * @brief Stop the DMA Transfer.
1836
  * @param  husart USART handle.
1837
  * @retval HAL status
1838
  */
1839
HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1840
{
1841
  /* The Lock is not implemented on this API to allow the user application
1842
     to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1843
     HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1844
     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1845
     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1846
     the stream and the corresponding call back is executed. */
1847
 
1848
  /* Disable the USART Tx/Rx DMA requests */
1849
  CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1850
  CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1851
 
1852
  /* Abort the USART DMA tx channel */
1853
  if (husart->hdmatx != NULL)
1854
  {
1855
    if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1856
    {
1857
      if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1858
      {
1859
        /* Set error code to DMA */
1860
        husart->ErrorCode = HAL_USART_ERROR_DMA;
1861
 
1862
        return HAL_TIMEOUT;
1863
      }
1864
    }
1865
  }
1866
  /* Abort the USART DMA rx channel */
1867
  if (husart->hdmarx != NULL)
1868
  {
1869
    if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1870
    {
1871
      if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1872
      {
1873
        /* Set error code to DMA */
1874
        husart->ErrorCode = HAL_USART_ERROR_DMA;
1875
 
1876
        return HAL_TIMEOUT;
1877
      }
1878
    }
1879
  }
1880
 
1881
  USART_EndTransfer(husart);
1882
  husart->State = HAL_USART_STATE_READY;
1883
 
1884
  return HAL_OK;
1885
}
1886
 
1887
/**
1888
  * @brief  Abort ongoing transfers (blocking mode).
1889
  * @param  husart USART handle.
1890
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1891
  *         This procedure performs following operations :
1892
  *           - Disable USART Interrupts (Tx and Rx)
1893
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1894
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1895
  *           - Set handle State to READY
1896
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1897
  * @retval HAL status
1898
  */
1899
HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
1900
{
1901
  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1902
  CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1903
 
1904
  /* Disable the USART DMA Tx request if enabled */
1905
  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1906
  {
1907
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1908
 
1909
    /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1910
    if (husart->hdmatx != NULL)
1911
    {
1912
      /* Set the USART DMA Abort callback to Null.
1913
         No call back execution at end of DMA abort procedure */
1914
      husart->hdmatx->XferAbortCallback = NULL;
1915
 
1916
      if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1917
      {
1918
        if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1919
        {
1920
          /* Set error code to DMA */
1921
          husart->ErrorCode = HAL_USART_ERROR_DMA;
1922
 
1923
          return HAL_TIMEOUT;
1924
        }
1925
      }
1926
    }
1927
  }
1928
 
1929
  /* Disable the USART DMA Rx request if enabled */
1930
  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1931
  {
1932
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1933
 
1934
    /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1935
    if (husart->hdmarx != NULL)
1936
    {
1937
      /* Set the USART DMA Abort callback to Null.
1938
         No call back execution at end of DMA abort procedure */
1939
      husart->hdmarx->XferAbortCallback = NULL;
1940
 
1941
      if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1942
      {
1943
        if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1944
        {
1945
          /* Set error code to DMA */
1946
          husart->ErrorCode = HAL_USART_ERROR_DMA;
1947
 
1948
          return HAL_TIMEOUT;
1949
        }
1950
      }
1951
    }
1952
  }
1953
 
1954
  /* Reset Tx and Rx transfer counters */
1955
  husart->TxXferCount = 0U;
1956
  husart->RxXferCount = 0U;
1957
 
1958
  /* Clear the Error flags in the ICR register */
1959
  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
1960
 
1961
 
1962
  /* Discard the received data */
1963
  __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
1964
 
1965
  /* Restore husart->State to Ready */
1966
  husart->State  = HAL_USART_STATE_READY;
1967
 
1968
  /* Reset Handle ErrorCode to No Error */
1969
  husart->ErrorCode = HAL_USART_ERROR_NONE;
1970
 
1971
  return HAL_OK;
1972
}
1973
 
1974
/**
1975
  * @brief  Abort ongoing transfers (Interrupt mode).
1976
  * @param  husart USART handle.
1977
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1978
  *         This procedure performs following operations :
1979
  *           - Disable USART Interrupts (Tx and Rx)
1980
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1981
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1982
  *           - Set handle State to READY
1983
  *           - At abort completion, call user abort complete callback
1984
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1985
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
1986
  * @retval HAL status
1987
  */
1988
HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
1989
{
1990
  uint32_t abortcplt = 1U;
1991
 
1992
  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1993
  CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1994
 
1995
  /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1996
     before any call to DMA Abort functions */
1997
  /* DMA Tx Handle is valid */
1998
  if (husart->hdmatx != NULL)
1999
  {
2000
    /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
2001
       Otherwise, set it to NULL */
2002
    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2003
    {
2004
      husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
2005
    }
2006
    else
2007
    {
2008
      husart->hdmatx->XferAbortCallback = NULL;
2009
    }
2010
  }
2011
  /* DMA Rx Handle is valid */
2012
  if (husart->hdmarx != NULL)
2013
  {
2014
    /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
2015
       Otherwise, set it to NULL */
2016
    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2017
    {
2018
      husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
2019
    }
2020
    else
2021
    {
2022
      husart->hdmarx->XferAbortCallback = NULL;
2023
    }
2024
  }
2025
 
2026
  /* Disable the USART DMA Tx request if enabled */
2027
  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2028
  {
2029
    /* Disable DMA Tx at USART level */
2030
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2031
 
2032
    /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2033
    if (husart->hdmatx != NULL)
2034
    {
2035
      /* USART Tx DMA Abort callback has already been initialised :
2036
         will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2037
 
2038
      /* Abort DMA TX */
2039
      if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2040
      {
2041
        husart->hdmatx->XferAbortCallback = NULL;
2042
      }
2043
      else
2044
      {
2045
        abortcplt = 0U;
2046
      }
2047
    }
2048
  }
2049
 
2050
  /* Disable the USART DMA Rx request if enabled */
2051
  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2052
  {
2053
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2054
 
2055
    /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2056
    if (husart->hdmarx != NULL)
2057
    {
2058
      /* USART Rx DMA Abort callback has already been initialised :
2059
         will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2060
 
2061
      /* Abort DMA RX */
2062
      if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2063
      {
2064
        husart->hdmarx->XferAbortCallback = NULL;
2065
        abortcplt = 1U;
2066
      }
2067
      else
2068
      {
2069
        abortcplt = 0U;
2070
      }
2071
    }
2072
  }
2073
 
2074
  /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2075
  if (abortcplt == 1U)
2076
  {
2077
    /* Reset Tx and Rx transfer counters */
2078
    husart->TxXferCount = 0U;
2079
    husart->RxXferCount = 0U;
2080
 
2081
    /* Reset errorCode */
2082
    husart->ErrorCode = HAL_USART_ERROR_NONE;
2083
 
2084
    /* Clear the Error flags in the ICR register */
2085
    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2086
 
2087
 
2088
    /* Discard the received data */
2089
    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2090
 
2091
    /* Restore husart->State to Ready */
2092
    husart->State  = HAL_USART_STATE_READY;
2093
 
2094
    /* As no DMA to be aborted, call directly user Abort complete callback */
2095
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2096
    /* Call registered Abort Complete Callback */
2097
    husart->AbortCpltCallback(husart);
2098
#else
2099
    /* Call legacy weak Abort Complete Callback */
2100
    HAL_USART_AbortCpltCallback(husart);
2101
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2102
  }
2103
 
2104
  return HAL_OK;
2105
}
2106
 
2107
/**
2108
  * @brief  Handle USART interrupt request.
2109
  * @param  husart USART handle.
2110
  * @retval None
2111
  */
2112
void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
2113
{
2114
  uint32_t isrflags   = READ_REG(husart->Instance->ISR);
2115
  uint32_t cr1its     = READ_REG(husart->Instance->CR1);
2116
  uint32_t cr3its     = READ_REG(husart->Instance->CR3);
2117
 
2118
  uint32_t errorflags;
2119
  uint32_t errorcode;
2120
 
2121
  /* If no error occurs */
2122
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
2123
  if (errorflags == 0U)
2124
  {
2125
    /* USART in mode Receiver ---------------------------------------------------*/
2126
    if (((isrflags & USART_ISR_RXNE) != 0U)
2127
        && ((cr1its & USART_CR1_RXNEIE) != 0U))
2128
    {
2129
      if (husart->RxISR != NULL)
2130
      {
2131
        husart->RxISR(husart);
2132
      }
2133
      return;
2134
    }
2135
  }
2136
 
2137
  /* If some errors occur */
2138
  if ((errorflags != 0U)
2139
      && (((cr3its & USART_CR3_EIE) != 0U)
2140
          || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != 0U)))
2141
  {
2142
    /* USART parity error interrupt occurred -------------------------------------*/
2143
    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2144
    {
2145
      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2146
 
2147
      husart->ErrorCode |= HAL_USART_ERROR_PE;
2148
    }
2149
 
2150
    /* USART frame error interrupt occurred --------------------------------------*/
2151
    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2152
    {
2153
      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2154
 
2155
      husart->ErrorCode |= HAL_USART_ERROR_FE;
2156
    }
2157
 
2158
    /* USART noise error interrupt occurred --------------------------------------*/
2159
    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2160
    {
2161
      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2162
 
2163
      husart->ErrorCode |= HAL_USART_ERROR_NE;
2164
    }
2165
 
2166
    /* USART Over-Run interrupt occurred -----------------------------------------*/
2167
    if (((isrflags & USART_ISR_ORE) != 0U)
2168
        && (((cr1its & USART_CR1_RXNEIE) != 0U) ||
2169
            ((cr3its & USART_CR3_EIE) != 0U)))
2170
    {
2171
      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2172
 
2173
      husart->ErrorCode |= HAL_USART_ERROR_ORE;
2174
    }
2175
 
2176
 
2177
    /* Call USART Error Call back function if need be --------------------------*/
2178
    if (husart->ErrorCode != HAL_USART_ERROR_NONE)
2179
    {
2180
      /* USART in mode Receiver ---------------------------------------------------*/
2181
      if (((isrflags & USART_ISR_RXNE) != 0U)
2182
          && ((cr1its & USART_CR1_RXNEIE) != 0U))
2183
      {
2184
        if (husart->RxISR != NULL)
2185
        {
2186
          husart->RxISR(husart);
2187
        }
2188
      }
2189
 
2190
      /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2191
         consider error as blocking */
2192
      errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
2193
      if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
2194
          (errorcode != 0U))
2195
      {
2196
        /* Blocking error : transfer is aborted
2197
           Set the USART state ready to be able to start again the process,
2198
           Disable Interrupts, and disable DMA requests, if ongoing */
2199
        USART_EndTransfer(husart);
2200
 
2201
        /* Disable the USART DMA Rx request if enabled */
2202
        if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2203
        {
2204
          CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2205
 
2206
          /* Abort the USART DMA Tx channel */
2207
          if (husart->hdmatx != NULL)
2208
          {
2209
            /* Set the USART Tx DMA Abort callback to NULL : no callback
2210
               executed at end of DMA abort procedure */
2211
            husart->hdmatx->XferAbortCallback = NULL;
2212
 
2213
            /* Abort DMA TX */
2214
            (void)HAL_DMA_Abort_IT(husart->hdmatx);
2215
          }
2216
 
2217
          /* Abort the USART DMA Rx channel */
2218
          if (husart->hdmarx != NULL)
2219
          {
2220
            /* Set the USART Rx DMA Abort callback :
2221
               will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2222
            husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
2223
 
2224
            /* Abort DMA RX */
2225
            if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2226
            {
2227
              /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2228
              husart->hdmarx->XferAbortCallback(husart->hdmarx);
2229
            }
2230
          }
2231
          else
2232
          {
2233
            /* Call user error callback */
2234
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2235
            /* Call registered Error Callback */
2236
            husart->ErrorCallback(husart);
2237
#else
2238
            /* Call legacy weak Error Callback */
2239
            HAL_USART_ErrorCallback(husart);
2240
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2241
          }
2242
        }
2243
        else
2244
        {
2245
          /* Call user error callback */
2246
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2247
          /* Call registered Error Callback */
2248
          husart->ErrorCallback(husart);
2249
#else
2250
          /* Call legacy weak Error Callback */
2251
          HAL_USART_ErrorCallback(husart);
2252
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2253
        }
2254
      }
2255
      else
2256
      {
2257
        /* Non Blocking error : transfer could go on.
2258
           Error is notified to user through user error callback */
2259
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2260
        /* Call registered Error Callback */
2261
        husart->ErrorCallback(husart);
2262
#else
2263
        /* Call legacy weak Error Callback */
2264
        HAL_USART_ErrorCallback(husart);
2265
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2266
        husart->ErrorCode = HAL_USART_ERROR_NONE;
2267
      }
2268
    }
2269
    return;
2270
 
2271
  } /* End if some error occurs */
2272
 
2273
 
2274
  /* USART in mode Transmitter ------------------------------------------------*/
2275
  if (((isrflags & USART_ISR_TXE) != 0U)
2276
      && ((cr1its & USART_CR1_TXEIE) != 0U))
2277
  {
2278
    if (husart->TxISR != NULL)
2279
    {
2280
      husart->TxISR(husart);
2281
    }
2282
    return;
2283
  }
2284
 
2285
  /* USART in mode Transmitter (transmission end) -----------------------------*/
2286
  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2287
  {
2288
    USART_EndTransmit_IT(husart);
2289
    return;
2290
  }
2291
 
2292
}
2293
 
2294
/**
2295
  * @brief Tx Transfer completed callback.
2296
  * @param husart USART handle.
2297
  * @retval None
2298
  */
2299
__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2300
{
2301
  /* Prevent unused argument(s) compilation warning */
2302
  UNUSED(husart);
2303
 
2304
  /* NOTE : This function should not be modified, when the callback is needed,
2305
            the HAL_USART_TxCpltCallback can be implemented in the user file.
2306
   */
2307
}
2308
 
2309
/**
2310
  * @brief  Tx Half Transfer completed callback.
2311
  * @param husart USART handle.
2312
  * @retval None
2313
  */
2314
__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2315
{
2316
  /* Prevent unused argument(s) compilation warning */
2317
  UNUSED(husart);
2318
 
2319
  /* NOTE: This function should not be modified, when the callback is needed,
2320
           the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2321
   */
2322
}
2323
 
2324
/**
2325
  * @brief  Rx Transfer completed callback.
2326
  * @param husart USART handle.
2327
  * @retval None
2328
  */
2329
__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2330
{
2331
  /* Prevent unused argument(s) compilation warning */
2332
  UNUSED(husart);
2333
 
2334
  /* NOTE: This function should not be modified, when the callback is needed,
2335
           the HAL_USART_RxCpltCallback can be implemented in the user file.
2336
   */
2337
}
2338
 
2339
/**
2340
  * @brief Rx Half Transfer completed callback.
2341
  * @param husart USART handle.
2342
  * @retval None
2343
  */
2344
__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2345
{
2346
  /* Prevent unused argument(s) compilation warning */
2347
  UNUSED(husart);
2348
 
2349
  /* NOTE : This function should not be modified, when the callback is needed,
2350
            the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2351
   */
2352
}
2353
 
2354
/**
2355
  * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2356
  * @param husart USART handle.
2357
  * @retval None
2358
  */
2359
__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2360
{
2361
  /* Prevent unused argument(s) compilation warning */
2362
  UNUSED(husart);
2363
 
2364
  /* NOTE : This function should not be modified, when the callback is needed,
2365
            the HAL_USART_TxRxCpltCallback can be implemented in the user file
2366
   */
2367
}
2368
 
2369
/**
2370
  * @brief USART error callback.
2371
  * @param husart USART handle.
2372
  * @retval None
2373
  */
2374
__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2375
{
2376
  /* Prevent unused argument(s) compilation warning */
2377
  UNUSED(husart);
2378
 
2379
  /* NOTE : This function should not be modified, when the callback is needed,
2380
            the HAL_USART_ErrorCallback can be implemented in the user file.
2381
   */
2382
}
2383
 
2384
/**
2385
  * @brief  USART Abort Complete callback.
2386
  * @param  husart USART handle.
2387
  * @retval None
2388
  */
2389
__weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2390
{
2391
  /* Prevent unused argument(s) compilation warning */
2392
  UNUSED(husart);
2393
 
2394
  /* NOTE : This function should not be modified, when the callback is needed,
2395
            the HAL_USART_AbortCpltCallback can be implemented in the user file.
2396
   */
2397
}
2398
 
2399
/**
2400
  * @}
2401
  */
2402
 
2403
/** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2404
  *  @brief   USART Peripheral State and Error functions
2405
  *
2406
@verbatim
2407
  ==============================================================================
2408
            ##### Peripheral State and Error functions #####
2409
  ==============================================================================
2410
    [..]
2411
    This subsection provides functions allowing to :
2412
      (+) Return the USART handle state
2413
      (+) Return the USART handle error code
2414
 
2415
@endverbatim
2416
  * @{
2417
  */
2418
 
2419
 
2420
/**
2421
  * @brief Return the USART handle state.
2422
  * @param husart pointer to a USART_HandleTypeDef structure that contains
2423
  *              the configuration information for the specified USART.
2424
  * @retval USART handle state
2425
  */
2426
HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
2427
{
2428
  return husart->State;
2429
}
2430
 
2431
/**
2432
  * @brief Return the USART error code.
2433
  * @param husart pointer to a USART_HandleTypeDef structure that contains
2434
  *              the configuration information for the specified USART.
2435
  * @retval USART handle Error Code
2436
  */
2437
uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
2438
{
2439
  return husart->ErrorCode;
2440
}
2441
 
2442
/**
2443
  * @}
2444
  */
2445
 
2446
/**
2447
  * @}
2448
  */
2449
 
2450
/** @defgroup USART_Private_Functions USART Private Functions
2451
  * @{
2452
  */
2453
 
2454
/**
2455
  * @brief  Initialize the callbacks to their default values.
2456
  * @param  husart USART handle.
2457
  * @retval none
2458
  */
2459
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2460
void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
2461
{
2462
  /* Init the USART Callback settings */
2463
  husart->TxHalfCpltCallback        = HAL_USART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2464
  husart->TxCpltCallback            = HAL_USART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2465
  husart->RxHalfCpltCallback        = HAL_USART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2466
  husart->RxCpltCallback            = HAL_USART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2467
  husart->TxRxCpltCallback          = HAL_USART_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback          */
2468
  husart->ErrorCallback             = HAL_USART_ErrorCallback;             /* Legacy weak ErrorCallback             */
2469
  husart->AbortCpltCallback         = HAL_USART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2470
}
2471
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2472
 
2473
/**
2474
  * @brief  End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2475
  * @param  husart USART handle.
2476
  * @retval None
2477
  */
2478
static void USART_EndTransfer(USART_HandleTypeDef *husart)
2479
{
2480
  /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2481
  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
2482
  CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2483
 
2484
  /* At end of process, restore husart->State to Ready */
2485
  husart->State = HAL_USART_STATE_READY;
2486
}
2487
 
2488
/**
2489
  * @brief DMA USART transmit process complete callback.
2490
  * @param  hdma DMA handle.
2491
  * @retval None
2492
  */
2493
static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2494
{
2495
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2496
 
2497
  /* DMA Normal mode */
2498
  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2499
  {
2500
    husart->TxXferCount = 0U;
2501
 
2502
    if (husart->State == HAL_USART_STATE_BUSY_TX)
2503
    {
2504
      /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2505
         in the USART CR3 register */
2506
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2507
 
2508
      /* Enable the USART Transmit Complete Interrupt */
2509
      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2510
    }
2511
  }
2512
  /* DMA Circular mode */
2513
  else
2514
  {
2515
    if (husart->State == HAL_USART_STATE_BUSY_TX)
2516
    {
2517
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2518
      /* Call registered Tx Complete Callback */
2519
      husart->TxCpltCallback(husart);
2520
#else
2521
      /* Call legacy weak Tx Complete Callback */
2522
      HAL_USART_TxCpltCallback(husart);
2523
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2524
    }
2525
  }
2526
}
2527
 
2528
/**
2529
  * @brief DMA USART transmit process half complete callback.
2530
  * @param  hdma DMA handle.
2531
  * @retval None
2532
  */
2533
static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2534
{
2535
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2536
 
2537
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2538
  /* Call registered Tx Half Complete Callback */
2539
  husart->TxHalfCpltCallback(husart);
2540
#else
2541
  /* Call legacy weak Tx Half Complete Callback */
2542
  HAL_USART_TxHalfCpltCallback(husart);
2543
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2544
}
2545
 
2546
/**
2547
  * @brief DMA USART receive process complete callback.
2548
  * @param  hdma DMA handle.
2549
  * @retval None
2550
  */
2551
static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2552
{
2553
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2554
 
2555
  /* DMA Normal mode */
2556
  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2557
  {
2558
    husart->RxXferCount = 0U;
2559
 
2560
    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2561
    CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2562
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2563
 
2564
    /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2565
       in USART CR3 register */
2566
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2567
    /* similarly, disable the DMA TX transfer that was started to provide the
2568
       clock to the slave device */
2569
    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2570
 
2571
    if (husart->State == HAL_USART_STATE_BUSY_RX)
2572
    {
2573
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2574
      /* Call registered Rx Complete Callback */
2575
      husart->RxCpltCallback(husart);
2576
#else
2577
      /* Call legacy weak Rx Complete Callback */
2578
      HAL_USART_RxCpltCallback(husart);
2579
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2580
    }
2581
    /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2582
    else
2583
    {
2584
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2585
      /* Call registered Tx Rx Complete Callback */
2586
      husart->TxRxCpltCallback(husart);
2587
#else
2588
      /* Call legacy weak Tx Rx Complete Callback */
2589
      HAL_USART_TxRxCpltCallback(husart);
2590
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2591
    }
2592
    husart->State = HAL_USART_STATE_READY;
2593
  }
2594
  /* DMA circular mode */
2595
  else
2596
  {
2597
    if (husart->State == HAL_USART_STATE_BUSY_RX)
2598
    {
2599
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2600
      /* Call registered Rx Complete Callback */
2601
      husart->RxCpltCallback(husart);
2602
#else
2603
      /* Call legacy weak Rx Complete Callback */
2604
      HAL_USART_RxCpltCallback(husart);
2605
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2606
    }
2607
    /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2608
    else
2609
    {
2610
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2611
      /* Call registered Tx Rx Complete Callback */
2612
      husart->TxRxCpltCallback(husart);
2613
#else
2614
      /* Call legacy weak Tx Rx Complete Callback */
2615
      HAL_USART_TxRxCpltCallback(husart);
2616
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2617
    }
2618
  }
2619
}
2620
 
2621
/**
2622
  * @brief DMA USART receive process half complete callback.
2623
  * @param  hdma DMA handle.
2624
  * @retval None
2625
  */
2626
static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2627
{
2628
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2629
 
2630
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2631
  /* Call registered Rx Half Complete Callback */
2632
  husart->RxHalfCpltCallback(husart);
2633
#else
2634
  /* Call legacy weak Rx Half Complete Callback */
2635
  HAL_USART_RxHalfCpltCallback(husart);
2636
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2637
}
2638
 
2639
/**
2640
  * @brief DMA USART communication error callback.
2641
  * @param  hdma DMA handle.
2642
  * @retval None
2643
  */
2644
static void USART_DMAError(DMA_HandleTypeDef *hdma)
2645
{
2646
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2647
 
2648
  husart->RxXferCount = 0U;
2649
  husart->TxXferCount = 0U;
2650
  USART_EndTransfer(husart);
2651
 
2652
  husart->ErrorCode |= HAL_USART_ERROR_DMA;
2653
  husart->State = HAL_USART_STATE_READY;
2654
 
2655
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2656
  /* Call registered Error Callback */
2657
  husart->ErrorCallback(husart);
2658
#else
2659
  /* Call legacy weak Error Callback */
2660
  HAL_USART_ErrorCallback(husart);
2661
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2662
}
2663
 
2664
/**
2665
  * @brief  DMA USART communication abort callback, when initiated by HAL services on Error
2666
  *         (To be called at end of DMA Abort procedure following error occurrence).
2667
  * @param  hdma DMA handle.
2668
  * @retval None
2669
  */
2670
static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2671
{
2672
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2673
  husart->RxXferCount = 0U;
2674
  husart->TxXferCount = 0U;
2675
 
2676
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2677
  /* Call registered Error Callback */
2678
  husart->ErrorCallback(husart);
2679
#else
2680
  /* Call legacy weak Error Callback */
2681
  HAL_USART_ErrorCallback(husart);
2682
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2683
}
2684
 
2685
/**
2686
  * @brief  DMA USART Tx communication abort callback, when initiated by user
2687
  *         (To be called at end of DMA Tx Abort procedure following user abort request).
2688
  * @note   When this callback is executed, User Abort complete call back is called only if no
2689
  *         Abort still ongoing for Rx DMA Handle.
2690
  * @param  hdma DMA handle.
2691
  * @retval None
2692
  */
2693
static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2694
{
2695
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2696
 
2697
  husart->hdmatx->XferAbortCallback = NULL;
2698
 
2699
  /* Check if an Abort process is still ongoing */
2700
  if (husart->hdmarx != NULL)
2701
  {
2702
    if (husart->hdmarx->XferAbortCallback != NULL)
2703
    {
2704
      return;
2705
    }
2706
  }
2707
 
2708
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2709
  husart->TxXferCount = 0U;
2710
  husart->RxXferCount = 0U;
2711
 
2712
  /* Reset errorCode */
2713
  husart->ErrorCode = HAL_USART_ERROR_NONE;
2714
 
2715
  /* Clear the Error flags in the ICR register */
2716
  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2717
 
2718
  /* Restore husart->State to Ready */
2719
  husart->State = HAL_USART_STATE_READY;
2720
 
2721
  /* Call user Abort complete callback */
2722
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2723
  /* Call registered Abort Complete Callback */
2724
  husart->AbortCpltCallback(husart);
2725
#else
2726
  /* Call legacy weak Abort Complete Callback */
2727
  HAL_USART_AbortCpltCallback(husart);
2728
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2729
 
2730
}
2731
 
2732
 
2733
/**
2734
  * @brief  DMA USART Rx communication abort callback, when initiated by user
2735
  *         (To be called at end of DMA Rx Abort procedure following user abort request).
2736
  * @note   When this callback is executed, User Abort complete call back is called only if no
2737
  *         Abort still ongoing for Tx DMA Handle.
2738
  * @param  hdma DMA handle.
2739
  * @retval None
2740
  */
2741
static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2742
{
2743
  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2744
 
2745
  husart->hdmarx->XferAbortCallback = NULL;
2746
 
2747
  /* Check if an Abort process is still ongoing */
2748
  if (husart->hdmatx != NULL)
2749
  {
2750
    if (husart->hdmatx->XferAbortCallback != NULL)
2751
    {
2752
      return;
2753
    }
2754
  }
2755
 
2756
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2757
  husart->TxXferCount = 0U;
2758
  husart->RxXferCount = 0U;
2759
 
2760
  /* Reset errorCode */
2761
  husart->ErrorCode = HAL_USART_ERROR_NONE;
2762
 
2763
  /* Clear the Error flags in the ICR register */
2764
  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2765
 
2766
  /* Restore husart->State to Ready */
2767
  husart->State  = HAL_USART_STATE_READY;
2768
 
2769
  /* Call user Abort complete callback */
2770
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2771
  /* Call registered Abort Complete Callback */
2772
  husart->AbortCpltCallback(husart);
2773
#else
2774
  /* Call legacy weak Abort Complete Callback */
2775
  HAL_USART_AbortCpltCallback(husart);
2776
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2777
}
2778
 
2779
 
2780
/**
2781
  * @brief  Handle USART Communication Timeout.
2782
  * @param  husart USART handle.
2783
  * @param  Flag Specifies the USART flag to check.
2784
  * @param  Status the Flag status (SET or RESET).
2785
  * @param  Tickstart Tick start value
2786
  * @param  Timeout timeout duration.
2787
  * @retval HAL status
2788
  */
2789
static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
2790
                                                      uint32_t Tickstart, uint32_t Timeout)
2791
{
2792
  /* Wait until flag is set */
2793
  while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
2794
  {
2795
    /* Check for the Timeout */
2796
    if (Timeout != HAL_MAX_DELAY)
2797
    {
2798
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2799
      {
2800
        husart->State = HAL_USART_STATE_READY;
2801
 
2802
        /* Process Unlocked */
2803
        __HAL_UNLOCK(husart);
2804
 
2805
        return HAL_TIMEOUT;
2806
      }
2807
    }
2808
  }
2809
  return HAL_OK;
2810
}
2811
 
2812
/**
2813
  * @brief Configure the USART peripheral.
2814
  * @param husart USART handle.
2815
  * @retval HAL status
2816
  */
2817
static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
2818
{
2819
  uint32_t tmpreg;
2820
  USART_ClockSourceTypeDef clocksource;
2821
  HAL_StatusTypeDef ret                = HAL_OK;
2822
  uint16_t brrtemp;
2823
  uint32_t usartdiv                    = 0x00000000;
2824
  uint32_t pclk;
2825
 
2826
  /* Check the parameters */
2827
  assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
2828
  assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
2829
  assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
2830
  assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
2831
  assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
2832
  assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
2833
  assert_param(IS_USART_PARITY(husart->Init.Parity));
2834
  assert_param(IS_USART_MODE(husart->Init.Mode));
2835
 
2836
  /*-------------------------- USART CR1 Configuration -----------------------*/
2837
  /* Clear M, PCE, PS, TE and RE bits and configure
2838
  *  the USART Word Length, Parity and Mode:
2839
  *  set the M bits according to husart->Init.WordLength value
2840
  *  set PCE and PS bits according to husart->Init.Parity value
2841
  *  set TE and RE bits according to husart->Init.Mode value
2842
  *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2843
  tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
2844
  MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2845
 
2846
  /*---------------------------- USART CR2 Configuration ---------------------*/
2847
  /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
2848
   * set CPOL bit according to husart->Init.CLKPolarity value
2849
   * set CPHA bit according to husart->Init.CLKPhase value
2850
   * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
2851
   * set STOP[13:12] bits according to husart->Init.StopBits value */
2852
  tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
2853
  tmpreg |= (uint32_t)husart->Init.CLKLastBit;
2854
  tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
2855
  tmpreg |= (uint32_t)husart->Init.StopBits;
2856
  MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
2857
 
2858
 
2859
  /*-------------------------- USART BRR Configuration -----------------------*/
2860
  /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */
2861
  USART_GETCLOCKSOURCE(husart, clocksource);
2862
 
2863
  switch (clocksource)
2864
  {
2865
    case USART_CLOCKSOURCE_PCLK1:
2866
      pclk = HAL_RCC_GetPCLK1Freq();
2867
      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate));
2868
      break;
2869
    case USART_CLOCKSOURCE_HSI:
2870
      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate));
2871
      break;
2872
    case USART_CLOCKSOURCE_SYSCLK:
2873
      pclk = HAL_RCC_GetSysClockFreq();
2874
      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate));
2875
      break;
2876
    case USART_CLOCKSOURCE_LSE:
2877
      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate));
2878
      break;
2879
    default:
2880
      ret = HAL_ERROR;
2881
      break;
2882
  }
2883
 
2884
  /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2885
  if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
2886
  {
2887
    brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
2888
    brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
2889
    husart->Instance->BRR = brrtemp;
2890
  }
2891
  else
2892
  {
2893
    ret = HAL_ERROR;
2894
  }
2895
 
2896
 
2897
  /* Clear ISR function pointers */
2898
  husart->RxISR   = NULL;
2899
  husart->TxISR   = NULL;
2900
 
2901
  return ret;
2902
}
2903
 
2904
/**
2905
  * @brief Check the USART Idle State.
2906
  * @param husart USART handle.
2907
  * @retval HAL status
2908
  */
2909
static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
2910
{
2911
  uint32_t tickstart;
2912
 
2913
  /* Initialize the USART ErrorCode */
2914
  husart->ErrorCode = HAL_USART_ERROR_NONE;
2915
 
2916
  /* Init tickstart for timeout managment*/
2917
  tickstart = HAL_GetTick();
2918
 
2919
  /* Check if the Transmitter is enabled */
2920
  if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2921
  {
2922
    /* Wait until TEACK flag is set */
2923
    if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
2924
    {
2925
      /* Timeout occurred */
2926
      return HAL_TIMEOUT;
2927
    }
2928
  }
2929
  /* Check if the Receiver is enabled */
2930
  if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2931
  {
2932
    /* Wait until REACK flag is set */
2933
    if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
2934
    {
2935
      /* Timeout occurred */
2936
      return HAL_TIMEOUT;
2937
    }
2938
  }
2939
 
2940
  /* Initialize the USART state*/
2941
  husart->State = HAL_USART_STATE_READY;
2942
 
2943
  /* Process Unlocked */
2944
  __HAL_UNLOCK(husart);
2945
 
2946
  return HAL_OK;
2947
}
2948
 
2949
/**
2950
  * @brief  Simplex send an amount of data in non-blocking mode.
2951
  * @note   Function called under interruption only, once
2952
  *         interruptions have been enabled by HAL_USART_Transmit_IT().
2953
  * @note   The USART errors are not managed to avoid the overrun error.
2954
  * @note   ISR function executed when data word length is less than 9 bits long.
2955
  * @param  husart USART handle.
2956
  * @retval None
2957
  */
2958
static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
2959
{
2960
  const HAL_USART_StateTypeDef state = husart->State;
2961
 
2962
  /* Check that a Tx process is ongoing */
2963
  if ((state == HAL_USART_STATE_BUSY_TX) ||
2964
      (state == HAL_USART_STATE_BUSY_TX_RX))
2965
  {
2966
    if (husart->TxXferCount == 0U)
2967
    {
2968
      /* Disable the USART Transmit data register empty interrupt */
2969
      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
2970
 
2971
      /* Enable the USART Transmit Complete Interrupt */
2972
      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2973
    }
2974
    else
2975
    {
2976
      husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
2977
      husart->pTxBuffPtr++;
2978
      husart->TxXferCount--;
2979
    }
2980
  }
2981
}
2982
 
2983
/**
2984
  * @brief  Simplex send an amount of data in non-blocking mode.
2985
  * @note   Function called under interruption only, once
2986
  *         interruptions have been enabled by HAL_USART_Transmit_IT().
2987
  * @note   The USART errors are not managed to avoid the overrun error.
2988
  * @note   ISR function executed when data word length is 9 bits long.
2989
  * @param  husart USART handle.
2990
  * @retval None
2991
  */
2992
static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
2993
{
2994
  const HAL_USART_StateTypeDef state = husart->State;
2995
  uint16_t *tmp;
2996
 
2997
  if ((state == HAL_USART_STATE_BUSY_TX) ||
2998
      (state == HAL_USART_STATE_BUSY_TX_RX))
2999
  {
3000
    if (husart->TxXferCount == 0U)
3001
    {
3002
      /* Disable the USART Transmit data register empty interrupt */
3003
      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3004
 
3005
      /* Enable the USART Transmit Complete Interrupt */
3006
      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3007
    }
3008
    else
3009
    {
3010
      tmp = (uint16_t *) husart->pTxBuffPtr;
3011
      husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3012
      husart->pTxBuffPtr += 2U;
3013
      husart->TxXferCount--;
3014
    }
3015
  }
3016
}
3017
 
3018
 
3019
/**
3020
  * @brief  Wraps up transmission in non-blocking mode.
3021
  * @param  husart Pointer to a USART_HandleTypeDef structure that contains
3022
  *                the configuration information for the specified USART module.
3023
  * @retval None
3024
  */
3025
static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3026
{
3027
  /* Disable the USART Transmit Complete Interrupt */
3028
  __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3029
 
3030
  /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3031
  __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3032
 
3033
  /* Clear TxISR function pointer */
3034
  husart->TxISR = NULL;
3035
 
3036
  if (husart->State == HAL_USART_STATE_BUSY_TX)
3037
  {
3038
    /* Clear overrun flag and discard the received data */
3039
    __HAL_USART_CLEAR_OREFLAG(husart);
3040
    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3041
 
3042
    /* Tx process is completed, restore husart->State to Ready */
3043
    husart->State = HAL_USART_STATE_READY;
3044
 
3045
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3046
    /* Call registered Tx Complete Callback */
3047
    husart->TxCpltCallback(husart);
3048
#else
3049
    /* Call legacy weak Tx Complete Callback */
3050
    HAL_USART_TxCpltCallback(husart);
3051
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3052
  }
3053
  else if (husart->RxXferCount == 0U)
3054
  {
3055
    /* TxRx process is completed, restore husart->State to Ready */
3056
    husart->State = HAL_USART_STATE_READY;
3057
 
3058
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3059
    /* Call registered Tx Rx Complete Callback */
3060
    husart->TxRxCpltCallback(husart);
3061
#else
3062
    /* Call legacy weak Tx Rx Complete Callback */
3063
    HAL_USART_TxRxCpltCallback(husart);
3064
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3065
  }
3066
  else
3067
  {
3068
    /* Nothing to do */
3069
  }
3070
}
3071
 
3072
 
3073
/**
3074
  * @brief  Simplex receive an amount of data in non-blocking mode.
3075
  * @note   Function called under interruption only, once
3076
  *         interruptions have been enabled by HAL_USART_Receive_IT().
3077
  * @note   ISR function executed when data word length is less than 9 bits long.
3078
  * @param  husart USART handle
3079
  * @retval None
3080
  */
3081
static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3082
{
3083
  const HAL_USART_StateTypeDef state = husart->State;
3084
  uint16_t txdatacount;
3085
  uint16_t uhMask = husart->Mask;
3086
 
3087
  if ((state == HAL_USART_STATE_BUSY_RX) ||
3088
      (state == HAL_USART_STATE_BUSY_TX_RX))
3089
  {
3090
    *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3091
    husart->pRxBuffPtr++;
3092
    husart->RxXferCount--;
3093
 
3094
    if (husart->RxXferCount == 0U)
3095
    {
3096
      /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3097
      CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3098
 
3099
      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3100
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3101
 
3102
      /* Clear RxISR function pointer */
3103
      husart->RxISR = NULL;
3104
 
3105
      /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
3106
      txdatacount = husart->TxXferCount;
3107
 
3108
      if (state == HAL_USART_STATE_BUSY_RX)
3109
      {
3110
 
3111
        /* Rx process is completed, restore husart->State to Ready */
3112
        husart->State = HAL_USART_STATE_READY;
3113
 
3114
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3115
        /* Call registered Rx Complete Callback */
3116
        husart->RxCpltCallback(husart);
3117
#else
3118
        /* Call legacy weak Rx Complete Callback */
3119
        HAL_USART_RxCpltCallback(husart);
3120
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3121
      }
3122
      else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3123
               (txdatacount == 0U))
3124
      {
3125
        /* TxRx process is completed, restore husart->State to Ready */
3126
        husart->State = HAL_USART_STATE_READY;
3127
 
3128
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3129
        /* Call registered Tx Rx Complete Callback */
3130
        husart->TxRxCpltCallback(husart);
3131
#else
3132
        /* Call legacy weak Tx Rx Complete Callback */
3133
        HAL_USART_TxRxCpltCallback(husart);
3134
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3135
      }
3136
      else
3137
      {
3138
        /* Nothing to do */
3139
      }
3140
    }
3141
    else if (state == HAL_USART_STATE_BUSY_RX)
3142
    {
3143
      /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3144
      husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3145
    }
3146
    else
3147
    {
3148
      /* Nothing to do */
3149
    }
3150
  }
3151
}
3152
 
3153
/**
3154
  * @brief  Simplex receive an amount of data in non-blocking mode.
3155
  * @note   Function called under interruption only, once
3156
  *         interruptions have been enabled by HAL_USART_Receive_IT().
3157
  * @note   ISR function executed when data word length is 9 bits long.
3158
  * @param  husart USART handle
3159
  * @retval None
3160
  */
3161
static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3162
{
3163
  const HAL_USART_StateTypeDef state = husart->State;
3164
  uint16_t txdatacount;
3165
  uint16_t *tmp;
3166
  uint16_t uhMask = husart->Mask;
3167
 
3168
  if ((state == HAL_USART_STATE_BUSY_RX) ||
3169
      (state == HAL_USART_STATE_BUSY_TX_RX))
3170
  {
3171
    tmp = (uint16_t *) husart->pRxBuffPtr;
3172
    *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3173
    husart->pRxBuffPtr += 2U;
3174
    husart->RxXferCount--;
3175
 
3176
    if (husart->RxXferCount == 0U)
3177
    {
3178
      /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3179
      CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3180
 
3181
      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3182
      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3183
 
3184
      /* Clear RxISR function pointer */
3185
      husart->RxISR = NULL;
3186
 
3187
      /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
3188
      txdatacount = husart->TxXferCount;
3189
 
3190
      if (state == HAL_USART_STATE_BUSY_RX)
3191
      {
3192
 
3193
        /* Rx process is completed, restore husart->State to Ready */
3194
        husart->State = HAL_USART_STATE_READY;
3195
 
3196
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3197
        /* Call registered Rx Complete Callback */
3198
        husart->RxCpltCallback(husart);
3199
#else
3200
        /* Call legacy weak Rx Complete Callback */
3201
        HAL_USART_RxCpltCallback(husart);
3202
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3203
      }
3204
      else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3205
               (txdatacount == 0U))
3206
      {
3207
        /* TxRx process is completed, restore husart->State to Ready */
3208
        husart->State = HAL_USART_STATE_READY;
3209
 
3210
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3211
        /* Call registered Tx Rx Complete Callback */
3212
        husart->TxRxCpltCallback(husart);
3213
#else
3214
        /* Call legacy weak Tx Rx Complete Callback */
3215
        HAL_USART_TxRxCpltCallback(husart);
3216
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3217
      }
3218
      else
3219
      {
3220
        /* Nothing to do */
3221
      }
3222
    }
3223
    else if (state == HAL_USART_STATE_BUSY_RX)
3224
    {
3225
      /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3226
      husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3227
    }
3228
    else
3229
    {
3230
      /* Nothing to do */
3231
    }
3232
  }
3233
}
3234
 
3235
 
3236
/**
3237
  * @}
3238
  */
3239
 
3240
#endif /* HAL_USART_MODULE_ENABLED */
3241
/**
3242
  * @}
3243
  */
3244
 
3245
/**
3246
  * @}
3247
  */
3248
 
3249
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/