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