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