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