Subversion Repositories DashDisplay

Rev

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

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