Subversion Repositories FuelGauge

Rev

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

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