xref: /btstack/port/stm32-wb55xx-nucleo-freertos/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_uart.c (revision 0561b2d8d5dba972c7daa57d5e677f7a1327edfd)
1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_hal_uart.c
4   * @author  MCD Application Team
5   * @brief   UART HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *
12   *
13   @verbatim
14  ===============================================================================
15                         ##### How to use this driver #####
16  ===============================================================================
17   [..]
18     The UART HAL driver can be used as follows:
19 
20     (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
21     (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
22         (++) Enable the USARTx interface clock.
23         (++) UART pins configuration:
24             (+++) Enable the clock for the UART GPIOs.
25             (+++) Configure these UART pins as alternate function pull-up.
26         (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
27              and HAL_UART_Receive_IT() APIs):
28             (+++) Configure the USARTx interrupt priority.
29             (+++) Enable the NVIC USART IRQ handle.
30         (++) UART interrupts handling:
31               -@@-  The specific UART interrupts (Transmission complete interrupt,
32                 RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
33                 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
34                 inside the transmit and receive processes.
35         (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
36              and HAL_UART_Receive_DMA() APIs):
37             (+++) Declare a DMA handle structure for the Tx/Rx channel.
38             (+++) Enable the DMAx interface clock.
39             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40             (+++) Configure the DMA Tx/Rx channel.
41             (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
42             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
43 
44     (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
45         flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
46 
47     (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
48         in the huart handle AdvancedInit structure.
49 
50     (#) For the UART asynchronous mode, initialize the UART registers by calling
51         the HAL_UART_Init() API.
52 
53     (#) For the UART Half duplex mode, initialize the UART registers by calling
54         the HAL_HalfDuplex_Init() API.
55 
56     (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
57         by calling the HAL_LIN_Init() API.
58 
59     (#) For the UART Multiprocessor mode, initialize the UART registers
60         by calling the HAL_MultiProcessor_Init() API.
61 
62     (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
63         by calling the HAL_RS485Ex_Init() API.
64 
65     [..]
66     (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
67         also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
68         calling the customized HAL_UART_MspInit() API.
69 
70     ##### Callback registration #####
71     ==================================
72 
73     [..]
74     The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
75     allows the user to configure dynamically the driver callbacks.
76 
77     [..]
78     Use Function @ref HAL_UART_RegisterCallback() to register a user callback.
79     Function @ref HAL_UART_RegisterCallback() allows to register following callbacks:
80     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
81     (+) TxCpltCallback            : Tx Complete Callback.
82     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
83     (+) RxCpltCallback            : Rx Complete Callback.
84     (+) ErrorCallback             : Error Callback.
85     (+) AbortCpltCallback         : Abort Complete Callback.
86     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
87     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
88     (+) WakeupCallback            : Wakeup Callback.
89     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
90     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
91     (+) MspInitCallback           : UART MspInit.
92     (+) MspDeInitCallback         : UART MspDeInit.
93     This function takes as parameters the HAL peripheral handle, the Callback ID
94     and a pointer to the user callback function.
95 
96     [..]
97     Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default
98     weak (surcharged) function.
99     @ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
100     and the Callback ID.
101     This function allows to reset following callbacks:
102     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
103     (+) TxCpltCallback            : Tx Complete Callback.
104     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
105     (+) RxCpltCallback            : Rx Complete Callback.
106     (+) ErrorCallback             : Error Callback.
107     (+) AbortCpltCallback         : Abort Complete Callback.
108     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
109     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
110     (+) WakeupCallback            : Wakeup Callback.
111     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
112     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
113     (+) MspInitCallback           : UART MspInit.
114     (+) MspDeInitCallback         : UART MspDeInit.
115 
116     [..]
117     By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
118     all callbacks are set to the corresponding weak (surcharged) functions:
119     examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback().
120     Exception done for MspInit and MspDeInit functions that are respectively
121     reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init()
122     and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
123     If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit()
124     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
125 
126     [..]
127     Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
128     Exception done MspInit/MspDeInit that can be registered/unregistered
129     in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
130     MspInit/DeInit callbacks can be used during the Init/DeInit.
131     In that case first register the MspInit/MspDeInit user callbacks
132     using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit()
133     or @ref HAL_UART_Init() function.
134 
135     [..]
136     When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
137     not defined, the callback registration feature is not available
138     and weak (surcharged) callbacks are used.
139 
140 
141   @endverbatim
142   ******************************************************************************
143   * @attention
144   *
145   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
146   * All rights reserved.</center></h2>
147   *
148   * This software component is licensed by ST under BSD 3-Clause license,
149   * the "License"; You may not use this file except in compliance with the
150   * License. You may obtain a copy of the License at:
151   *                        opensource.org/licenses/BSD-3-Clause
152   *
153   ******************************************************************************
154   */
155 
156 /* Includes ------------------------------------------------------------------*/
157 #include "stm32wbxx_hal.h"
158 
159 /** @addtogroup STM32WBxx_HAL_Driver
160   * @{
161   */
162 
163 /** @defgroup UART UART
164   * @brief HAL UART module driver
165   * @{
166   */
167 
168 #ifdef HAL_UART_MODULE_ENABLED
169 
170 /* Private typedef -----------------------------------------------------------*/
171 /* Private define ------------------------------------------------------------*/
172 /** @defgroup UART_Private_Constants UART Private Constants
173   * @{
174   */
175 #define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
176                                       USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8| \
177                                       USART_CR1_FIFOEN ))                      /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
178 
179 #define USART_CR3_FIELDS  ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT| \
180                                       USART_CR3_TXFTCFG | USART_CR3_RXFTCFG ))  /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
181 
182 #if defined(LPUART1)
183 #define LPUART_BRR_MIN  0x00000300U  /* LPUART BRR minimum authorized value */
184 #define LPUART_BRR_MAX  0x000FFFFFU  /* LPUART BRR maximum authorized value */
185 #endif
186 
187 #define UART_BRR_MIN    0x10U        /* UART BRR minimum authorized value */
188 #define UART_BRR_MAX    0x0000FFFFU  /* UART BRR maximum authorized value */
189 
190 /**
191   * @}
192   */
193 
194 /* Private macros ------------------------------------------------------------*/
195 /* Private variables ---------------------------------------------------------*/
196 /* Private function prototypes -----------------------------------------------*/
197 /** @addtogroup UART_Private_Functions
198   * @{
199   */
200 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
201 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
202 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
203 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
204 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
205 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
206 static void UART_DMAError(DMA_HandleTypeDef *hdma);
207 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
208 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
209 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
210 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
211 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
212 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
213 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
214 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
215 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
216 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
217 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
218 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
219 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
220 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
221 /**
222   * @}
223   */
224 
225 /* Exported functions --------------------------------------------------------*/
226 
227 /** @defgroup UART_Exported_Functions UART Exported Functions
228   * @{
229   */
230 
231 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
232   *  @brief    Initialization and Configuration functions
233   *
234 @verbatim
235 ===============================================================================
236             ##### Initialization and Configuration functions #####
237  ===============================================================================
238     [..]
239     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
240     in asynchronous mode.
241       (+) For the asynchronous mode the parameters below can be configured:
242         (++) Baud Rate
243         (++) Word Length
244         (++) Stop Bit
245         (++) Parity: If the parity is enabled, then the MSB bit of the data written
246              in the data register is transmitted but is changed by the parity bit.
247         (++) Hardware flow control
248         (++) Receiver/transmitter modes
249         (++) Over Sampling Method
250         (++) One-Bit Sampling Method
251       (+) For the asynchronous mode, the following advanced features can be configured as well:
252         (++) TX and/or RX pin level inversion
253         (++) data logical level inversion
254         (++) RX and TX pins swap
255         (++) RX overrun detection disabling
256         (++) DMA disabling on RX error
257         (++) MSB first on communication line
258         (++) auto Baud rate detection
259     [..]
260     The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
261     follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
262     and UART multiprocessor mode configuration procedures (details for the procedures
263     are available in reference manual).
264 
265 @endverbatim
266 
267   Depending on the frame length defined by the M1 and M0 bits (7-bit,
268   8-bit or 9-bit), the possible UART formats are listed in the
269   following table.
270 
271   Table 1. UART frame format.
272     +-----------------------------------------------------------------------+
273     |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
274     |---------|---------|-----------|---------------------------------------|
275     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
276     |---------|---------|-----------|---------------------------------------|
277     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
278     |---------|---------|-----------|---------------------------------------|
279     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
280     |---------|---------|-----------|---------------------------------------|
281     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
282     |---------|---------|-----------|---------------------------------------|
283     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
284     |---------|---------|-----------|---------------------------------------|
285     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
286     +-----------------------------------------------------------------------+
287 
288   * @{
289   */
290 
291 /**
292   * @brief Initialize the UART mode according to the specified
293   *        parameters in the UART_InitTypeDef and initialize the associated handle.
294   * @param huart UART handle.
295   * @retval HAL status
296   */
HAL_UART_Init(UART_HandleTypeDef * huart)297 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
298 {
299   /* Check the UART handle allocation */
300   if (huart == NULL)
301   {
302     return HAL_ERROR;
303   }
304 
305   if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
306   {
307     /* Check the parameters */
308     assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
309   }
310   else
311   {
312     /* Check the parameters */
313 #if defined(LPUART1)
314     assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
315 #else
316     assert_param(IS_UART_INSTANCE(huart->Instance));
317 #endif
318   }
319 
320   if (huart->gState == HAL_UART_STATE_RESET)
321   {
322     /* Allocate lock resource and initialize it */
323     huart->Lock = HAL_UNLOCKED;
324 
325 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
326     UART_InitCallbacksToDefault(huart);
327 
328     if (huart->MspInitCallback == NULL)
329     {
330       huart->MspInitCallback = HAL_UART_MspInit;
331     }
332 
333     /* Init the low level hardware */
334     huart->MspInitCallback(huart);
335 #else
336     /* Init the low level hardware : GPIO, CLOCK */
337     HAL_UART_MspInit(huart);
338 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
339   }
340 
341   huart->gState = HAL_UART_STATE_BUSY;
342 
343   __HAL_UART_DISABLE(huart);
344 
345   /* Set the UART Communication parameters */
346   if (UART_SetConfig(huart) == HAL_ERROR)
347   {
348     return HAL_ERROR;
349   }
350 
351   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
352   {
353     UART_AdvFeatureConfig(huart);
354   }
355 
356   /* In asynchronous mode, the following bits must be kept cleared:
357   - LINEN and CLKEN bits in the USART_CR2 register,
358   - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/
359   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
360   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
361 
362   __HAL_UART_ENABLE(huart);
363 
364   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
365   return (UART_CheckIdleState(huart));
366 }
367 
368 /**
369   * @brief Initialize the half-duplex mode according to the specified
370   *        parameters in the UART_InitTypeDef and creates the associated handle.
371   * @param huart UART handle.
372   * @retval HAL status
373   */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)374 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
375 {
376   /* Check the UART handle allocation */
377   if (huart == NULL)
378   {
379     return HAL_ERROR;
380   }
381 
382   /* Check UART instance */
383   assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
384 
385   if (huart->gState == HAL_UART_STATE_RESET)
386   {
387     /* Allocate lock resource and initialize it */
388     huart->Lock = HAL_UNLOCKED;
389 
390 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
391     UART_InitCallbacksToDefault(huart);
392 
393     if (huart->MspInitCallback == NULL)
394     {
395       huart->MspInitCallback = HAL_UART_MspInit;
396     }
397 
398     /* Init the low level hardware */
399     huart->MspInitCallback(huart);
400 #else
401     /* Init the low level hardware : GPIO, CLOCK */
402     HAL_UART_MspInit(huart);
403 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
404   }
405 
406   huart->gState = HAL_UART_STATE_BUSY;
407 
408   __HAL_UART_DISABLE(huart);
409 
410   /* Set the UART Communication parameters */
411   if (UART_SetConfig(huart) == HAL_ERROR)
412   {
413     return HAL_ERROR;
414   }
415 
416   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
417   {
418     UART_AdvFeatureConfig(huart);
419   }
420 
421   /* In half-duplex mode, the following bits must be kept cleared:
422   - LINEN and CLKEN bits in the USART_CR2 register,
423   - SCEN and IREN bits in the USART_CR3 register.*/
424   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
425   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
426 
427   /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
428   SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
429 
430   __HAL_UART_ENABLE(huart);
431 
432   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
433   return (UART_CheckIdleState(huart));
434 }
435 
436 
437 /**
438   * @brief Initialize the LIN mode according to the specified
439   *        parameters in the UART_InitTypeDef and creates the associated handle.
440   * @param huart             UART handle.
441   * @param BreakDetectLength Specifies the LIN break detection length.
442   *        This parameter can be one of the following values:
443   *          @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
444   *          @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
445   * @retval HAL status
446   */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)447 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
448 {
449   /* Check the UART handle allocation */
450   if (huart == NULL)
451   {
452     return HAL_ERROR;
453   }
454 
455   /* Check the LIN UART instance */
456   assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
457   /* Check the Break detection length parameter */
458   assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
459 
460   /* LIN mode limited to 16-bit oversampling only */
461   if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
462   {
463     return HAL_ERROR;
464   }
465   /* LIN mode limited to 8-bit data length */
466   if (huart->Init.WordLength != UART_WORDLENGTH_8B)
467   {
468     return HAL_ERROR;
469   }
470 
471   if (huart->gState == HAL_UART_STATE_RESET)
472   {
473     /* Allocate lock resource and initialize it */
474     huart->Lock = HAL_UNLOCKED;
475 
476 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
477     UART_InitCallbacksToDefault(huart);
478 
479     if (huart->MspInitCallback == NULL)
480     {
481       huart->MspInitCallback = HAL_UART_MspInit;
482     }
483 
484     /* Init the low level hardware */
485     huart->MspInitCallback(huart);
486 #else
487     /* Init the low level hardware : GPIO, CLOCK */
488     HAL_UART_MspInit(huart);
489 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
490   }
491 
492   huart->gState = HAL_UART_STATE_BUSY;
493 
494   __HAL_UART_DISABLE(huart);
495 
496   /* Set the UART Communication parameters */
497   if (UART_SetConfig(huart) == HAL_ERROR)
498   {
499     return HAL_ERROR;
500   }
501 
502   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
503   {
504     UART_AdvFeatureConfig(huart);
505   }
506 
507   /* In LIN mode, the following bits must be kept cleared:
508   - LINEN and CLKEN bits in the USART_CR2 register,
509   - SCEN and IREN bits in the USART_CR3 register.*/
510   CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
511   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
512 
513   /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
514   SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
515 
516   /* Set the USART LIN Break detection length. */
517   MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
518 
519   __HAL_UART_ENABLE(huart);
520 
521   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
522   return (UART_CheckIdleState(huart));
523 }
524 
525 
526 /**
527   * @brief Initialize the multiprocessor mode according to the specified
528   *        parameters in the UART_InitTypeDef and initialize the associated handle.
529   * @param huart        UART handle.
530   * @param Address      UART node address (4-, 6-, 7- or 8-bit long).
531   * @param WakeUpMethod Specifies the UART wakeup method.
532   *        This parameter can be one of the following values:
533   *          @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
534   *          @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
535   * @note  If the user resorts to idle line detection wake up, the Address parameter
536   *        is useless and ignored by the initialization function.
537   * @note  If the user resorts to address mark wake up, the address length detection
538   *        is configured by default to 4 bits only. For the UART to be able to
539   *        manage 6-, 7- or 8-bit long addresses detection, the API
540   *        HAL_MultiProcessorEx_AddressLength_Set() must be called after
541   *        HAL_MultiProcessor_Init().
542   * @retval HAL status
543   */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)544 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
545 {
546   /* Check the UART handle allocation */
547   if (huart == NULL)
548   {
549     return HAL_ERROR;
550   }
551 
552   /* Check the wake up method parameter */
553   assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
554 
555   if (huart->gState == HAL_UART_STATE_RESET)
556   {
557     /* Allocate lock resource and initialize it */
558     huart->Lock = HAL_UNLOCKED;
559 
560 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
561     UART_InitCallbacksToDefault(huart);
562 
563     if (huart->MspInitCallback == NULL)
564     {
565       huart->MspInitCallback = HAL_UART_MspInit;
566     }
567 
568     /* Init the low level hardware */
569     huart->MspInitCallback(huart);
570 #else
571     /* Init the low level hardware : GPIO, CLOCK */
572     HAL_UART_MspInit(huart);
573 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
574   }
575 
576   huart->gState = HAL_UART_STATE_BUSY;
577 
578   __HAL_UART_DISABLE(huart);
579 
580   /* Set the UART Communication parameters */
581   if (UART_SetConfig(huart) == HAL_ERROR)
582   {
583     return HAL_ERROR;
584   }
585 
586   if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
587   {
588     UART_AdvFeatureConfig(huart);
589   }
590 
591   /* In multiprocessor mode, the following bits must be kept cleared:
592   - LINEN and CLKEN bits in the USART_CR2 register,
593   - SCEN, HDSEL and IREN  bits in the USART_CR3 register. */
594   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
595   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
596 
597   if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
598   {
599     /* If address mark wake up method is chosen, set the USART address node */
600     MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
601   }
602 
603   /* Set the wake up method by setting the WAKE bit in the CR1 register */
604   MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
605 
606   __HAL_UART_ENABLE(huart);
607 
608   /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
609   return (UART_CheckIdleState(huart));
610 }
611 
612 
613 /**
614   * @brief DeInitialize the UART peripheral.
615   * @param huart UART handle.
616   * @retval HAL status
617   */
HAL_UART_DeInit(UART_HandleTypeDef * huart)618 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
619 {
620   /* Check the UART handle allocation */
621   if (huart == NULL)
622   {
623     return HAL_ERROR;
624   }
625 
626   /* Check the parameters */
627 #if defined(LPUART1)
628   assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
629 #else
630   assert_param(IS_UART_INSTANCE(huart->Instance));
631 #endif
632 
633   huart->gState = HAL_UART_STATE_BUSY;
634 
635   __HAL_UART_DISABLE(huart);
636 
637   huart->Instance->CR1 = 0x0U;
638   huart->Instance->CR2 = 0x0U;
639   huart->Instance->CR3 = 0x0U;
640 
641 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
642   if (huart->MspDeInitCallback == NULL)
643   {
644     huart->MspDeInitCallback = HAL_UART_MspDeInit;
645   }
646   /* DeInit the low level hardware */
647   huart->MspDeInitCallback(huart);
648 #else
649   /* DeInit the low level hardware */
650   HAL_UART_MspDeInit(huart);
651 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
652 
653   huart->ErrorCode = HAL_UART_ERROR_NONE;
654   huart->gState = HAL_UART_STATE_RESET;
655   huart->RxState = HAL_UART_STATE_RESET;
656 
657   __HAL_UNLOCK(huart);
658 
659   return HAL_OK;
660 }
661 
662 /**
663   * @brief Initialize the UART MSP.
664   * @param huart UART handle.
665   * @retval None
666   */
HAL_UART_MspInit(UART_HandleTypeDef * huart)667 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
668 {
669   /* Prevent unused argument(s) compilation warning */
670   UNUSED(huart);
671 
672   /* NOTE : This function should not be modified, when the callback is needed,
673             the HAL_UART_MspInit can be implemented in the user file
674    */
675 }
676 
677 /**
678   * @brief DeInitialize the UART MSP.
679   * @param huart UART handle.
680   * @retval None
681   */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)682 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
683 {
684   /* Prevent unused argument(s) compilation warning */
685   UNUSED(huart);
686 
687   /* NOTE : This function should not be modified, when the callback is needed,
688             the HAL_UART_MspDeInit can be implemented in the user file
689    */
690 }
691 
692 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
693 /**
694   * @brief  Register a User UART Callback
695   *         To be used instead of the weak predefined callback
696   * @param  huart uart handle
697   * @param  CallbackID ID of the callback to be registered
698   *         This parameter can be one of the following values:
699   *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
700   *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
701   *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
702   *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
703   *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
704   *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
705   *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
706   *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
707   *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
708   *           @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
709   *           @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
710   *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
711   *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
712   * @param  pCallback pointer to the Callback function
713   * @retval HAL status
714   */
HAL_UART_RegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID,pUART_CallbackTypeDef pCallback)715 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
716                                             pUART_CallbackTypeDef pCallback)
717 {
718   HAL_StatusTypeDef status = HAL_OK;
719 
720   if (pCallback == NULL)
721   {
722     huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
723 
724     return HAL_ERROR;
725   }
726 
727   __HAL_LOCK(huart);
728 
729   if (huart->gState == HAL_UART_STATE_READY)
730   {
731     switch (CallbackID)
732     {
733       case HAL_UART_TX_HALFCOMPLETE_CB_ID :
734         huart->TxHalfCpltCallback = pCallback;
735         break;
736 
737       case HAL_UART_TX_COMPLETE_CB_ID :
738         huart->TxCpltCallback = pCallback;
739         break;
740 
741       case HAL_UART_RX_HALFCOMPLETE_CB_ID :
742         huart->RxHalfCpltCallback = pCallback;
743         break;
744 
745       case HAL_UART_RX_COMPLETE_CB_ID :
746         huart->RxCpltCallback = pCallback;
747         break;
748 
749       case HAL_UART_ERROR_CB_ID :
750         huart->ErrorCallback = pCallback;
751         break;
752 
753       case HAL_UART_ABORT_COMPLETE_CB_ID :
754         huart->AbortCpltCallback = pCallback;
755         break;
756 
757       case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
758         huart->AbortTransmitCpltCallback = pCallback;
759         break;
760 
761       case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
762         huart->AbortReceiveCpltCallback = pCallback;
763         break;
764 
765       case HAL_UART_WAKEUP_CB_ID :
766         huart->WakeupCallback = pCallback;
767         break;
768 
769       case HAL_UART_RX_FIFO_FULL_CB_ID :
770         huart->RxFifoFullCallback = pCallback;
771         break;
772 
773       case HAL_UART_TX_FIFO_EMPTY_CB_ID :
774         huart->TxFifoEmptyCallback = pCallback;
775         break;
776 
777       case HAL_UART_MSPINIT_CB_ID :
778         huart->MspInitCallback = pCallback;
779         break;
780 
781       case HAL_UART_MSPDEINIT_CB_ID :
782         huart->MspDeInitCallback = pCallback;
783         break;
784 
785       default :
786         huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
787 
788         status =  HAL_ERROR;
789         break;
790     }
791   }
792   else if (huart->gState == HAL_UART_STATE_RESET)
793   {
794     switch (CallbackID)
795     {
796       case HAL_UART_MSPINIT_CB_ID :
797         huart->MspInitCallback = pCallback;
798         break;
799 
800       case HAL_UART_MSPDEINIT_CB_ID :
801         huart->MspDeInitCallback = pCallback;
802         break;
803 
804       default :
805         huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
806 
807         status =  HAL_ERROR;
808         break;
809     }
810   }
811   else
812   {
813     huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
814 
815     status =  HAL_ERROR;
816   }
817 
818   __HAL_UNLOCK(huart);
819 
820   return status;
821 }
822 
823 /**
824   * @brief  Unregister an UART Callback
825   *         UART callaback is redirected to the weak predefined callback
826   * @param  huart uart handle
827   * @param  CallbackID ID of the callback to be unregistered
828   *         This parameter can be one of the following values:
829   *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
830   *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
831   *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
832   *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
833   *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
834   *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
835   *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
836   *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
837   *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
838   *           @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
839   *           @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
840   *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
841   *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
842   * @retval HAL status
843   */
HAL_UART_UnRegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID)844 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
845 {
846   HAL_StatusTypeDef status = HAL_OK;
847 
848   __HAL_LOCK(huart);
849 
850   if (HAL_UART_STATE_READY == huart->gState)
851   {
852     switch (CallbackID)
853     {
854       case HAL_UART_TX_HALFCOMPLETE_CB_ID :
855         huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback       */
856         break;
857 
858       case HAL_UART_TX_COMPLETE_CB_ID :
859         huart->TxCpltCallback = HAL_UART_TxCpltCallback;                       /* Legacy weak TxCpltCallback            */
860         break;
861 
862       case HAL_UART_RX_HALFCOMPLETE_CB_ID :
863         huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback        */
864         break;
865 
866       case HAL_UART_RX_COMPLETE_CB_ID :
867         huart->RxCpltCallback = HAL_UART_RxCpltCallback;                       /* Legacy weak RxCpltCallback            */
868         break;
869 
870       case HAL_UART_ERROR_CB_ID :
871         huart->ErrorCallback = HAL_UART_ErrorCallback;                         /* Legacy weak ErrorCallback             */
872         break;
873 
874       case HAL_UART_ABORT_COMPLETE_CB_ID :
875         huart->AbortCpltCallback = HAL_UART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback         */
876         break;
877 
878       case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
879         huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
880         break;
881 
882       case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
883         huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback;   /* Legacy weak AbortReceiveCpltCallback  */
884         break;
885 
886       case HAL_UART_WAKEUP_CB_ID :
887         huart->WakeupCallback = HAL_UARTEx_WakeupCallback;                     /* Legacy weak WakeupCallback            */
888         break;
889 
890       case HAL_UART_RX_FIFO_FULL_CB_ID :
891         huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback;             /* Legacy weak RxFifoFullCallback        */
892         break;
893 
894       case HAL_UART_TX_FIFO_EMPTY_CB_ID :
895         huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback;           /* Legacy weak TxFifoEmptyCallback       */
896         break;
897 
898       case HAL_UART_MSPINIT_CB_ID :
899         huart->MspInitCallback = HAL_UART_MspInit;                             /* Legacy weak MspInitCallback           */
900         break;
901 
902       case HAL_UART_MSPDEINIT_CB_ID :
903         huart->MspDeInitCallback = HAL_UART_MspDeInit;                         /* Legacy weak MspDeInitCallback         */
904         break;
905 
906       default :
907         huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
908 
909         status =  HAL_ERROR;
910         break;
911     }
912   }
913   else if (HAL_UART_STATE_RESET == huart->gState)
914   {
915     switch (CallbackID)
916     {
917       case HAL_UART_MSPINIT_CB_ID :
918         huart->MspInitCallback = HAL_UART_MspInit;
919         break;
920 
921       case HAL_UART_MSPDEINIT_CB_ID :
922         huart->MspDeInitCallback = HAL_UART_MspDeInit;
923         break;
924 
925       default :
926         huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
927 
928         status =  HAL_ERROR;
929         break;
930     }
931   }
932   else
933   {
934     huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
935 
936     status =  HAL_ERROR;
937   }
938 
939   __HAL_UNLOCK(huart);
940 
941   return status;
942 }
943 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
944 
945 /**
946   * @}
947   */
948 
949 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
950   * @brief UART Transmit/Receive functions
951   *
952 @verbatim
953  ===============================================================================
954                       ##### IO operation functions #####
955  ===============================================================================
956     This subsection provides a set of functions allowing to manage the UART asynchronous
957     and Half duplex data transfers.
958 
959     (#) There are two mode of transfer:
960        (+) Blocking mode: The communication is performed in polling mode.
961            The HAL status of all data processing is returned by the same function
962            after finishing transfer.
963        (+) Non-Blocking mode: The communication is performed using Interrupts
964            or DMA, These API's return the HAL status.
965            The end of the data processing will be indicated through the
966            dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
967            using DMA mode.
968            The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
969            will be executed respectively at the end of the transmit or Receive process
970            The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
971 
972     (#) Blocking mode API's are :
973         (+) HAL_UART_Transmit()
974         (+) HAL_UART_Receive()
975 
976     (#) Non-Blocking mode API's with Interrupt are :
977         (+) HAL_UART_Transmit_IT()
978         (+) HAL_UART_Receive_IT()
979         (+) HAL_UART_IRQHandler()
980 
981     (#) Non-Blocking mode API's with DMA are :
982         (+) HAL_UART_Transmit_DMA()
983         (+) HAL_UART_Receive_DMA()
984         (+) HAL_UART_DMAPause()
985         (+) HAL_UART_DMAResume()
986         (+) HAL_UART_DMAStop()
987 
988     (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
989         (+) HAL_UART_TxHalfCpltCallback()
990         (+) HAL_UART_TxCpltCallback()
991         (+) HAL_UART_RxHalfCpltCallback()
992         (+) HAL_UART_RxCpltCallback()
993         (+) HAL_UART_ErrorCallback()
994 
995     (#) Non-Blocking mode transfers could be aborted using Abort API's :
996         (+) HAL_UART_Abort()
997         (+) HAL_UART_AbortTransmit()
998         (+) HAL_UART_AbortReceive()
999         (+) HAL_UART_Abort_IT()
1000         (+) HAL_UART_AbortTransmit_IT()
1001         (+) HAL_UART_AbortReceive_IT()
1002 
1003     (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1004         (+) HAL_UART_AbortCpltCallback()
1005         (+) HAL_UART_AbortTransmitCpltCallback()
1006         (+) HAL_UART_AbortReceiveCpltCallback()
1007 
1008     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1009         Errors are handled as follows :
1010        (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1011            to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
1012            Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
1013            and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
1014            If user wants to abort it, Abort services should be called by user.
1015        (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1016            This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1017            Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1018 
1019     -@- In the Half duplex communication, it is forbidden to run the transmit
1020         and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1021 
1022 @endverbatim
1023   * @{
1024   */
1025 
1026 /**
1027   * @brief Send an amount of data in blocking mode.
1028   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1029   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1030   *         of u16 provided through pData.
1031   * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1032   *       data to the TXFIFO. Write operations to the TDR register are performed
1033   *       when TXFNF flag is set. From hardware perspective, TXFNF flag and
1034   *       TXE are mapped on the same bit-field.
1035   * @param huart   UART handle.
1036   * @param pData   Pointer to data buffer (u8 or u16 data elements).
1037   * @param Size    Amount of data elements (u8 or u16) to be sent.
1038   * @param Timeout Timeout duration.
1039   * @retval HAL status
1040   */
HAL_UART_Transmit(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1041 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1042 {
1043   uint8_t  *pdata8bits;
1044   uint16_t *pdata16bits;
1045   uint32_t tickstart;
1046 
1047   /* Check that a Tx process is not already ongoing */
1048   if (huart->gState == HAL_UART_STATE_READY)
1049   {
1050     if ((pData == NULL) || (Size == 0U))
1051     {
1052       return  HAL_ERROR;
1053     }
1054 
1055     __HAL_LOCK(huart);
1056 
1057     huart->ErrorCode = HAL_UART_ERROR_NONE;
1058     huart->gState = HAL_UART_STATE_BUSY_TX;
1059 
1060     /* Init tickstart for timeout managment*/
1061     tickstart = HAL_GetTick();
1062 
1063     huart->TxXferSize  = Size;
1064     huart->TxXferCount = Size;
1065 
1066     /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1067     if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1068     {
1069       pdata8bits  = NULL;
1070       pdata16bits = (uint16_t *) pData;
1071     }
1072     else
1073     {
1074       pdata8bits  = pData;
1075       pdata16bits = NULL;
1076     }
1077 
1078     __HAL_UNLOCK(huart);
1079 
1080     while (huart->TxXferCount > 0U)
1081     {
1082       if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1083       {
1084         return HAL_TIMEOUT;
1085       }
1086       if (pdata8bits == NULL)
1087       {
1088         huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1089         pdata16bits++;
1090       }
1091       else
1092       {
1093         huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1094         pdata8bits++;
1095       }
1096       huart->TxXferCount--;
1097     }
1098 
1099     if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1100     {
1101       return HAL_TIMEOUT;
1102     }
1103 
1104     /* At end of Tx process, restore huart->gState to Ready */
1105     huart->gState = HAL_UART_STATE_READY;
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 blocking mode.
1117   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1118   *         the received data is handled as a set of u16. In this case, Size must indicate the number
1119   *         of u16 available through pData.
1120   * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1121   *       is not empty. Read operations from the RDR register are performed when
1122   *       RXFNE flag is set. From hardware perspective, RXFNE flag and
1123   *       RXNE are mapped on the same bit-field.
1124   * @param huart   UART handle.
1125   * @param pData   Pointer to data buffer (u8 or u16 data elements).
1126   * @param Size    Amount of data elements (u8 or u16) to be received.
1127   * @param Timeout Timeout duration.
1128   * @retval HAL status
1129   */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1130 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1131 {
1132   uint8_t  *pdata8bits;
1133   uint16_t *pdata16bits;
1134   uint16_t uhMask;
1135   uint32_t tickstart;
1136 
1137   /* Check that a Rx process is not already ongoing */
1138   if (huart->RxState == HAL_UART_STATE_READY)
1139   {
1140     if ((pData == NULL) || (Size == 0U))
1141     {
1142       return  HAL_ERROR;
1143     }
1144 
1145     __HAL_LOCK(huart);
1146 
1147     huart->ErrorCode = HAL_UART_ERROR_NONE;
1148     huart->RxState = HAL_UART_STATE_BUSY_RX;
1149 
1150     /* Init tickstart for timeout managment*/
1151     tickstart = HAL_GetTick();
1152 
1153     huart->RxXferSize  = Size;
1154     huart->RxXferCount = Size;
1155 
1156     /* Computation of UART mask to apply to RDR register */
1157     UART_MASK_COMPUTATION(huart);
1158     uhMask = huart->Mask;
1159 
1160     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1161     if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1162     {
1163       pdata8bits  = NULL;
1164       pdata16bits = (uint16_t *) pData;
1165     }
1166     else
1167     {
1168       pdata8bits  = pData;
1169       pdata16bits = NULL;
1170     }
1171 
1172     __HAL_UNLOCK(huart);
1173 
1174     /* as long as data have to be received */
1175     while (huart->RxXferCount > 0U)
1176     {
1177       if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1178       {
1179         return HAL_TIMEOUT;
1180       }
1181       if (pdata8bits == NULL)
1182       {
1183         *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1184         pdata16bits++;
1185       }
1186       else
1187       {
1188         *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1189         pdata8bits++;
1190       }
1191       huart->RxXferCount--;
1192     }
1193 
1194     /* At end of Rx process, restore huart->RxState to Ready */
1195     huart->RxState = HAL_UART_STATE_READY;
1196 
1197     return HAL_OK;
1198   }
1199   else
1200   {
1201     return HAL_BUSY;
1202   }
1203 }
1204 
1205 /**
1206   * @brief Send an amount of data in interrupt mode.
1207   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1208   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1209   *         of u16 provided through pData.
1210   * @param huart UART handle.
1211   * @param pData Pointer to data buffer (u8 or u16 data elements).
1212   * @param Size  Amount of data elements (u8 or u16) to be sent.
1213   * @retval HAL status
1214   */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1215 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1216 {
1217   /* Check that a Tx process is not already ongoing */
1218   if (huart->gState == HAL_UART_STATE_READY)
1219   {
1220     if ((pData == NULL) || (Size == 0U))
1221     {
1222       return HAL_ERROR;
1223     }
1224 
1225     __HAL_LOCK(huart);
1226 
1227     huart->pTxBuffPtr  = pData;
1228     huart->TxXferSize  = Size;
1229     huart->TxXferCount = Size;
1230     huart->TxISR       = NULL;
1231 
1232     huart->ErrorCode = HAL_UART_ERROR_NONE;
1233     huart->gState = HAL_UART_STATE_BUSY_TX;
1234 
1235     /* Configure Tx interrupt processing */
1236     if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1237     {
1238       /* Set the Tx ISR function pointer according to the data word length */
1239       if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1240       {
1241         huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1242       }
1243       else
1244       {
1245         huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1246       }
1247 
1248       __HAL_UNLOCK(huart);
1249 
1250       /* Enable the TX FIFO threshold interrupt */
1251       SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1252     }
1253     else
1254     {
1255       /* Set the Tx ISR function pointer according to the data word length */
1256       if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1257       {
1258         huart->TxISR = UART_TxISR_16BIT;
1259       }
1260       else
1261       {
1262         huart->TxISR = UART_TxISR_8BIT;
1263       }
1264 
1265       __HAL_UNLOCK(huart);
1266 
1267       /* Enable the Transmit Data Register Empty interrupt */
1268       SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1269     }
1270 
1271     return HAL_OK;
1272   }
1273   else
1274   {
1275     return HAL_BUSY;
1276   }
1277 }
1278 
1279 /**
1280   * @brief Receive an amount of data in interrupt mode.
1281   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1282   *         the received data is handled as a set of u16. In this case, Size must indicate the number
1283   *         of u16 available through pData.
1284   * @param huart UART handle.
1285   * @param pData Pointer to data buffer (u8 or u16 data elements).
1286   * @param Size  Amount of data elements (u8 or u16) to be received.
1287   * @retval HAL status
1288   */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1289 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1290 {
1291   /* Check that a Rx process is not already ongoing */
1292   if (huart->RxState == HAL_UART_STATE_READY)
1293   {
1294     if ((pData == NULL) || (Size == 0U))
1295     {
1296       return HAL_ERROR;
1297     }
1298 
1299     __HAL_LOCK(huart);
1300 
1301     huart->pRxBuffPtr  = pData;
1302     huart->RxXferSize  = Size;
1303     huart->RxXferCount = Size;
1304     huart->RxISR       = NULL;
1305 
1306     /* Computation of UART mask to apply to RDR register */
1307     UART_MASK_COMPUTATION(huart);
1308 
1309     huart->ErrorCode = HAL_UART_ERROR_NONE;
1310     huart->RxState = HAL_UART_STATE_BUSY_RX;
1311 
1312     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1313     SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1314 
1315     /* Configure Rx interrupt processing*/
1316     if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
1317     {
1318       /* Set the Rx ISR function pointer according to the data word length */
1319       if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1320       {
1321         huart->RxISR = UART_RxISR_16BIT_FIFOEN;
1322       }
1323       else
1324       {
1325         huart->RxISR = UART_RxISR_8BIT_FIFOEN;
1326       }
1327 
1328       __HAL_UNLOCK(huart);
1329 
1330       /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
1331       SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1332       SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
1333     }
1334     else
1335     {
1336       /* Set the Rx ISR function pointer according to the data word length */
1337       if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1338       {
1339         huart->RxISR = UART_RxISR_16BIT;
1340       }
1341       else
1342       {
1343         huart->RxISR = UART_RxISR_8BIT;
1344       }
1345 
1346       __HAL_UNLOCK(huart);
1347 
1348       /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
1349       SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1350     }
1351 
1352     return HAL_OK;
1353   }
1354   else
1355   {
1356     return HAL_BUSY;
1357   }
1358 }
1359 
1360 /**
1361   * @brief Send an amount of data in DMA mode.
1362   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1363   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1364   *         of u16 provided through pData.
1365   * @param huart UART handle.
1366   * @param pData Pointer to data buffer (u8 or u16 data elements).
1367   * @param Size  Amount of data elements (u8 or u16) to be sent.
1368   * @retval HAL status
1369   */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1370 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1371 {
1372   /* Check that a Tx process is not already ongoing */
1373   if (huart->gState == HAL_UART_STATE_READY)
1374   {
1375     if ((pData == NULL) || (Size == 0U))
1376     {
1377       return HAL_ERROR;
1378     }
1379 
1380     __HAL_LOCK(huart);
1381 
1382     huart->pTxBuffPtr  = pData;
1383     huart->TxXferSize  = Size;
1384     huart->TxXferCount = Size;
1385 
1386     huart->ErrorCode = HAL_UART_ERROR_NONE;
1387     huart->gState = HAL_UART_STATE_BUSY_TX;
1388 
1389     if (huart->hdmatx != NULL)
1390     {
1391       /* Set the UART DMA transfer complete callback */
1392       huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1393 
1394       /* Set the UART DMA Half transfer complete callback */
1395       huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1396 
1397       /* Set the DMA error callback */
1398       huart->hdmatx->XferErrorCallback = UART_DMAError;
1399 
1400       /* Set the DMA abort callback */
1401       huart->hdmatx->XferAbortCallback = NULL;
1402 
1403       /* Enable the UART transmit DMA channel */
1404       if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
1405       {
1406         /* Set error code to DMA */
1407         huart->ErrorCode = HAL_UART_ERROR_DMA;
1408 
1409         __HAL_UNLOCK(huart);
1410 
1411         /* Restore huart->gState to ready */
1412         huart->gState = HAL_UART_STATE_READY;
1413 
1414         return HAL_ERROR;
1415       }
1416     }
1417     /* Clear the TC flag in the ICR register */
1418     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1419 
1420     __HAL_UNLOCK(huart);
1421 
1422     /* Enable the DMA transfer for transmit request by setting the DMAT bit
1423     in the UART CR3 register */
1424     SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1425 
1426     return HAL_OK;
1427   }
1428   else
1429   {
1430     return HAL_BUSY;
1431   }
1432 }
1433 
1434 /**
1435   * @brief Receive an amount of data in DMA mode.
1436   * @note   When the UART parity is enabled (PCE = 1), the received data contain
1437   *         the parity bit (MSB position).
1438   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1439   *         the received data is handled as a set of u16. In this case, Size must indicate the number
1440   *         of u16 available through pData.
1441   * @param huart UART handle.
1442   * @param pData Pointer to data buffer (u8 or u16 data elements).
1443   * @param Size  Amount of data elements (u8 or u16) to be received.
1444   * @retval HAL status
1445   */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1446 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1447 {
1448   /* Check that a Rx process is not already ongoing */
1449   if (huart->RxState == HAL_UART_STATE_READY)
1450   {
1451     if ((pData == NULL) || (Size == 0U))
1452     {
1453       return HAL_ERROR;
1454     }
1455 
1456     __HAL_LOCK(huart);
1457 
1458     huart->pRxBuffPtr = pData;
1459     huart->RxXferSize = Size;
1460 
1461     huart->ErrorCode = HAL_UART_ERROR_NONE;
1462     huart->RxState = HAL_UART_STATE_BUSY_RX;
1463 
1464     if (huart->hdmarx != NULL)
1465     {
1466       /* Set the UART DMA transfer complete callback */
1467       huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
1468 
1469       /* Set the UART DMA Half transfer complete callback */
1470       huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
1471 
1472       /* Set the DMA error callback */
1473       huart->hdmarx->XferErrorCallback = UART_DMAError;
1474 
1475       /* Set the DMA abort callback */
1476       huart->hdmarx->XferAbortCallback = NULL;
1477 
1478       /* Enable the DMA channel */
1479       if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
1480       {
1481         /* Set error code to DMA */
1482         huart->ErrorCode = HAL_UART_ERROR_DMA;
1483 
1484         __HAL_UNLOCK(huart);
1485 
1486         /* Restore huart->gState to ready */
1487         huart->gState = HAL_UART_STATE_READY;
1488 
1489         return HAL_ERROR;
1490       }
1491     }
1492     __HAL_UNLOCK(huart);
1493 
1494     /* Enable the UART Parity Error Interrupt */
1495     SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1496 
1497     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1498     SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1499 
1500     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1501     in the UART CR3 register */
1502     SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1503 
1504     return HAL_OK;
1505   }
1506   else
1507   {
1508     return HAL_BUSY;
1509   }
1510 }
1511 
1512 /**
1513   * @brief Pause the DMA Transfer.
1514   * @param huart UART handle.
1515   * @retval HAL status
1516   */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1517 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1518 {
1519   const HAL_UART_StateTypeDef gstate = huart->gState;
1520   const HAL_UART_StateTypeDef rxstate = huart->RxState;
1521 
1522   __HAL_LOCK(huart);
1523 
1524   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1525       (gstate == HAL_UART_STATE_BUSY_TX))
1526   {
1527     /* Disable the UART DMA Tx request */
1528     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1529   }
1530   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1531       (rxstate == HAL_UART_STATE_BUSY_RX))
1532   {
1533     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1534     CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1535     CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1536 
1537     /* Disable the UART DMA Rx request */
1538     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1539   }
1540 
1541   __HAL_UNLOCK(huart);
1542 
1543   return HAL_OK;
1544 }
1545 
1546 /**
1547   * @brief Resume the DMA Transfer.
1548   * @param huart UART handle.
1549   * @retval HAL status
1550   */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1551 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1552 {
1553   __HAL_LOCK(huart);
1554 
1555   if (huart->gState == HAL_UART_STATE_BUSY_TX)
1556   {
1557     /* Enable the UART DMA Tx request */
1558     SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1559   }
1560   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1561   {
1562     /* Clear the Overrun flag before resuming the Rx transfer */
1563     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1564 
1565     /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1566     SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1567     SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1568 
1569     /* Enable the UART DMA Rx request */
1570     SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1571   }
1572 
1573   __HAL_UNLOCK(huart);
1574 
1575   return HAL_OK;
1576 }
1577 
1578 /**
1579   * @brief Stop the DMA Transfer.
1580   * @param huart UART handle.
1581   * @retval HAL status
1582   */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1583 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1584 {
1585   /* The Lock is not implemented on this API to allow the user application
1586      to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1587      HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1588      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1589      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1590      the stream and the corresponding call back is executed. */
1591 
1592   const HAL_UART_StateTypeDef gstate = huart->gState;
1593   const HAL_UART_StateTypeDef rxstate = huart->RxState;
1594 
1595   /* Stop UART DMA Tx request if ongoing */
1596   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1597       (gstate == HAL_UART_STATE_BUSY_TX))
1598   {
1599     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1600 
1601     /* Abort the UART DMA Tx channel */
1602     if (huart->hdmatx != NULL)
1603     {
1604       if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1605       {
1606         if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1607         {
1608           /* Set error code to DMA */
1609           huart->ErrorCode = HAL_UART_ERROR_DMA;
1610 
1611           return HAL_TIMEOUT;
1612         }
1613       }
1614     }
1615 
1616     UART_EndTxTransfer(huart);
1617   }
1618 
1619   /* Stop UART DMA Rx request if ongoing */
1620   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1621       (rxstate == HAL_UART_STATE_BUSY_RX))
1622   {
1623     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1624 
1625     /* Abort the UART DMA Rx channel */
1626     if (huart->hdmarx != NULL)
1627     {
1628       if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1629       {
1630         if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1631         {
1632           /* Set error code to DMA */
1633           huart->ErrorCode = HAL_UART_ERROR_DMA;
1634 
1635           return HAL_TIMEOUT;
1636         }
1637       }
1638     }
1639 
1640     UART_EndRxTransfer(huart);
1641   }
1642 
1643   return HAL_OK;
1644 }
1645 
1646 /**
1647   * @brief  Abort ongoing transfers (blocking mode).
1648   * @param  huart UART handle.
1649   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1650   *         This procedure performs following operations :
1651   *           - Disable UART Interrupts (Tx and Rx)
1652   *           - Disable the DMA transfer in the peripheral register (if enabled)
1653   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1654   *           - Set handle State to READY
1655   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1656   * @retval HAL status
1657   */
HAL_UART_Abort(UART_HandleTypeDef * huart)1658 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1659 {
1660   /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1661   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1662   CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1663 
1664   /* Disable the UART DMA Tx request if enabled */
1665   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1666   {
1667     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1668 
1669     /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1670     if (huart->hdmatx != NULL)
1671     {
1672       /* Set the UART DMA Abort callback to Null.
1673          No call back execution at end of DMA abort procedure */
1674       huart->hdmatx->XferAbortCallback = NULL;
1675 
1676       if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1677       {
1678         if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1679         {
1680           /* Set error code to DMA */
1681           huart->ErrorCode = HAL_UART_ERROR_DMA;
1682 
1683           return HAL_TIMEOUT;
1684         }
1685       }
1686     }
1687   }
1688 
1689   /* Disable the UART DMA Rx request if enabled */
1690   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1691   {
1692     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1693 
1694     /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1695     if (huart->hdmarx != NULL)
1696     {
1697       /* Set the UART DMA Abort callback to Null.
1698          No call back execution at end of DMA abort procedure */
1699       huart->hdmarx->XferAbortCallback = NULL;
1700 
1701       if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1702       {
1703         if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1704         {
1705           /* Set error code to DMA */
1706           huart->ErrorCode = HAL_UART_ERROR_DMA;
1707 
1708           return HAL_TIMEOUT;
1709         }
1710       }
1711     }
1712   }
1713 
1714   /* Reset Tx and Rx transfer counters */
1715   huart->TxXferCount = 0U;
1716   huart->RxXferCount = 0U;
1717 
1718   /* Clear the Error flags in the ICR register */
1719   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1720 
1721   /* Flush the whole TX FIFO (if needed) */
1722   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1723   {
1724     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1725   }
1726 
1727   /* Discard the received data */
1728   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1729 
1730   /* Restore huart->gState and huart->RxState to Ready */
1731   huart->gState  = HAL_UART_STATE_READY;
1732   huart->RxState = HAL_UART_STATE_READY;
1733 
1734   huart->ErrorCode = HAL_UART_ERROR_NONE;
1735 
1736   return HAL_OK;
1737 }
1738 
1739 /**
1740   * @brief  Abort ongoing Transmit transfer (blocking mode).
1741   * @param  huart UART handle.
1742   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1743   *         This procedure performs following operations :
1744   *           - Disable UART Interrupts (Tx)
1745   *           - Disable the DMA transfer in the peripheral register (if enabled)
1746   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1747   *           - Set handle State to READY
1748   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1749   * @retval HAL status
1750   */
HAL_UART_AbortTransmit(UART_HandleTypeDef * huart)1751 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1752 {
1753   /* Disable TCIE, TXEIE and TXFTIE interrupts */
1754   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1755   CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1756 
1757   /* Disable the UART DMA Tx request if enabled */
1758   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1759   {
1760     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1761 
1762     /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1763     if (huart->hdmatx != NULL)
1764     {
1765       /* Set the UART DMA Abort callback to Null.
1766          No call back execution at end of DMA abort procedure */
1767       huart->hdmatx->XferAbortCallback = NULL;
1768 
1769       if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1770       {
1771         if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1772         {
1773           /* Set error code to DMA */
1774           huart->ErrorCode = HAL_UART_ERROR_DMA;
1775 
1776           return HAL_TIMEOUT;
1777         }
1778       }
1779     }
1780   }
1781 
1782   /* Reset Tx transfer counter */
1783   huart->TxXferCount = 0U;
1784 
1785   /* Flush the whole TX FIFO (if needed) */
1786   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1787   {
1788     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1789   }
1790 
1791   /* Restore huart->gState to Ready */
1792   huart->gState = HAL_UART_STATE_READY;
1793 
1794   return HAL_OK;
1795 }
1796 
1797 /**
1798   * @brief  Abort ongoing Receive transfer (blocking mode).
1799   * @param  huart UART handle.
1800   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1801   *         This procedure performs following operations :
1802   *           - Disable UART Interrupts (Rx)
1803   *           - Disable the DMA transfer in the peripheral register (if enabled)
1804   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1805   *           - Set handle State to READY
1806   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1807   * @retval HAL status
1808   */
HAL_UART_AbortReceive(UART_HandleTypeDef * huart)1809 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1810 {
1811   /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1812   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1813   CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1814 
1815   /* Disable the UART DMA Rx request if enabled */
1816   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1817   {
1818     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1819 
1820     /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1821     if (huart->hdmarx != NULL)
1822     {
1823       /* Set the UART DMA Abort callback to Null.
1824          No call back execution at end of DMA abort procedure */
1825       huart->hdmarx->XferAbortCallback = NULL;
1826 
1827       if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1828       {
1829         if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1830         {
1831           /* Set error code to DMA */
1832           huart->ErrorCode = HAL_UART_ERROR_DMA;
1833 
1834           return HAL_TIMEOUT;
1835         }
1836       }
1837     }
1838   }
1839 
1840   /* Reset Rx transfer counter */
1841   huart->RxXferCount = 0U;
1842 
1843   /* Clear the Error flags in the ICR register */
1844   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1845 
1846   /* Discard the received data */
1847   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1848 
1849   /* Restore huart->RxState to Ready */
1850   huart->RxState = HAL_UART_STATE_READY;
1851 
1852   return HAL_OK;
1853 }
1854 
1855 /**
1856   * @brief  Abort ongoing transfers (Interrupt mode).
1857   * @param  huart UART handle.
1858   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1859   *         This procedure performs following operations :
1860   *           - Disable UART Interrupts (Tx and Rx)
1861   *           - Disable the DMA transfer in the peripheral register (if enabled)
1862   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1863   *           - Set handle State to READY
1864   *           - At abort completion, call user abort complete callback
1865   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1866   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1867   * @retval HAL status
1868   */
HAL_UART_Abort_IT(UART_HandleTypeDef * huart)1869 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1870 {
1871   uint32_t abortcplt = 1U;
1872 
1873   /* Disable interrupts */
1874   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_TXEIE_TXFNFIE));
1875   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1876 
1877   /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1878      before any call to DMA Abort functions */
1879   /* DMA Tx Handle is valid */
1880   if (huart->hdmatx != NULL)
1881   {
1882     /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
1883        Otherwise, set it to NULL */
1884     if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1885     {
1886       huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
1887     }
1888     else
1889     {
1890       huart->hdmatx->XferAbortCallback = NULL;
1891     }
1892   }
1893   /* DMA Rx Handle is valid */
1894   if (huart->hdmarx != NULL)
1895   {
1896     /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
1897        Otherwise, set it to NULL */
1898     if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1899     {
1900       huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
1901     }
1902     else
1903     {
1904       huart->hdmarx->XferAbortCallback = NULL;
1905     }
1906   }
1907 
1908   /* Disable the UART DMA Tx request if enabled */
1909   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1910   {
1911     /* Disable DMA Tx at UART level */
1912     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1913 
1914     /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
1915     if (huart->hdmatx != NULL)
1916     {
1917       /* UART Tx DMA Abort callback has already been initialised :
1918          will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1919 
1920       /* Abort DMA TX */
1921       if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
1922       {
1923         huart->hdmatx->XferAbortCallback = NULL;
1924       }
1925       else
1926       {
1927         abortcplt = 0U;
1928       }
1929     }
1930   }
1931 
1932   /* Disable the UART DMA Rx request if enabled */
1933   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1934   {
1935     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1936 
1937     /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
1938     if (huart->hdmarx != NULL)
1939     {
1940       /* UART Rx DMA Abort callback has already been initialised :
1941          will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1942 
1943       /* Abort DMA RX */
1944       if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
1945       {
1946         huart->hdmarx->XferAbortCallback = NULL;
1947         abortcplt = 1U;
1948       }
1949       else
1950       {
1951         abortcplt = 0U;
1952       }
1953     }
1954   }
1955 
1956   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1957   if (abortcplt == 1U)
1958   {
1959     /* Reset Tx and Rx transfer counters */
1960     huart->TxXferCount = 0U;
1961     huart->RxXferCount = 0U;
1962 
1963     /* Clear ISR function pointers */
1964     huart->RxISR = NULL;
1965     huart->TxISR = NULL;
1966 
1967     /* Reset errorCode */
1968     huart->ErrorCode = HAL_UART_ERROR_NONE;
1969 
1970     /* Clear the Error flags in the ICR register */
1971     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1972 
1973     /* Flush the whole TX FIFO (if needed) */
1974     if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1975     {
1976       __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1977     }
1978 
1979     /* Discard the received data */
1980     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1981 
1982     /* Restore huart->gState and huart->RxState to Ready */
1983     huart->gState  = HAL_UART_STATE_READY;
1984     huart->RxState = HAL_UART_STATE_READY;
1985 
1986     /* As no DMA to be aborted, call directly user Abort complete callback */
1987 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
1988     /* Call registered Abort complete callback */
1989     huart->AbortCpltCallback(huart);
1990 #else
1991     /* Call legacy weak Abort complete callback */
1992     HAL_UART_AbortCpltCallback(huart);
1993 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1994   }
1995 
1996   return HAL_OK;
1997 }
1998 
1999 /**
2000   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
2001   * @param  huart UART handle.
2002   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
2003   *         This procedure performs following operations :
2004   *           - Disable UART Interrupts (Tx)
2005   *           - Disable the DMA transfer in the peripheral register (if enabled)
2006   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2007   *           - Set handle State to READY
2008   *           - At abort completion, call user abort complete callback
2009   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
2010   *         considered as completed only when user abort complete callback is executed (not when exiting function).
2011   * @retval HAL status
2012   */
HAL_UART_AbortTransmit_IT(UART_HandleTypeDef * huart)2013 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2014 {
2015   /* Disable interrupts */
2016   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
2017   CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
2018 
2019   /* Disable the UART DMA Tx request if enabled */
2020   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2021   {
2022     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2023 
2024     /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2025     if (huart->hdmatx != NULL)
2026     {
2027       /* Set the UART DMA Abort callback :
2028          will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2029       huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2030 
2031       /* Abort DMA TX */
2032       if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2033       {
2034         /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2035         huart->hdmatx->XferAbortCallback(huart->hdmatx);
2036       }
2037     }
2038     else
2039     {
2040       /* Reset Tx transfer counter */
2041       huart->TxXferCount = 0U;
2042 
2043       /* Clear TxISR function pointers */
2044       huart->TxISR = NULL;
2045 
2046       /* Restore huart->gState to Ready */
2047       huart->gState = HAL_UART_STATE_READY;
2048 
2049       /* As no DMA to be aborted, call directly user Abort complete callback */
2050 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2051       /* Call registered Abort Transmit Complete Callback */
2052       huart->AbortTransmitCpltCallback(huart);
2053 #else
2054       /* Call legacy weak Abort Transmit Complete Callback */
2055       HAL_UART_AbortTransmitCpltCallback(huart);
2056 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2057     }
2058   }
2059   else
2060   {
2061     /* Reset Tx transfer counter */
2062     huart->TxXferCount = 0U;
2063 
2064     /* Clear TxISR function pointers */
2065     huart->TxISR = NULL;
2066 
2067     /* Flush the whole TX FIFO (if needed) */
2068     if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2069     {
2070       __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2071     }
2072 
2073     /* Restore huart->gState to Ready */
2074     huart->gState = HAL_UART_STATE_READY;
2075 
2076     /* As no DMA to be aborted, call directly user Abort complete callback */
2077 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2078     /* Call registered Abort Transmit Complete Callback */
2079     huart->AbortTransmitCpltCallback(huart);
2080 #else
2081     /* Call legacy weak Abort Transmit Complete Callback */
2082     HAL_UART_AbortTransmitCpltCallback(huart);
2083 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2084   }
2085 
2086   return HAL_OK;
2087 }
2088 
2089 /**
2090   * @brief  Abort ongoing Receive transfer (Interrupt mode).
2091   * @param  huart UART handle.
2092   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2093   *         This procedure performs following operations :
2094   *           - Disable UART Interrupts (Rx)
2095   *           - Disable the DMA transfer in the peripheral register (if enabled)
2096   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2097   *           - Set handle State to READY
2098   *           - At abort completion, call user abort complete callback
2099   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
2100   *         considered as completed only when user abort complete callback is executed (not when exiting function).
2101   * @retval HAL status
2102   */
HAL_UART_AbortReceive_IT(UART_HandleTypeDef * huart)2103 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2104 {
2105   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2106   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2107   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2108 
2109   /* Disable the UART DMA Rx request if enabled */
2110   if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2111   {
2112     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2113 
2114     /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2115     if (huart->hdmarx != NULL)
2116     {
2117       /* Set the UART DMA Abort callback :
2118          will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2119       huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2120 
2121       /* Abort DMA RX */
2122       if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2123       {
2124         /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2125         huart->hdmarx->XferAbortCallback(huart->hdmarx);
2126       }
2127     }
2128     else
2129     {
2130       /* Reset Rx transfer counter */
2131       huart->RxXferCount = 0U;
2132 
2133       /* Clear RxISR function pointer */
2134       huart->pRxBuffPtr = NULL;
2135 
2136       /* Clear the Error flags in the ICR register */
2137       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2138 
2139       /* Discard the received data */
2140       __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2141 
2142       /* Restore huart->RxState to Ready */
2143       huart->RxState = HAL_UART_STATE_READY;
2144 
2145       /* As no DMA to be aborted, call directly user Abort complete callback */
2146 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2147       /* Call registered Abort Receive Complete Callback */
2148       huart->AbortReceiveCpltCallback(huart);
2149 #else
2150       /* Call legacy weak Abort Receive Complete Callback */
2151       HAL_UART_AbortReceiveCpltCallback(huart);
2152 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2153     }
2154   }
2155   else
2156   {
2157     /* Reset Rx transfer counter */
2158     huart->RxXferCount = 0U;
2159 
2160     /* Clear RxISR function pointer */
2161     huart->pRxBuffPtr = NULL;
2162 
2163     /* Clear the Error flags in the ICR register */
2164     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2165 
2166     /* Restore huart->RxState to Ready */
2167     huart->RxState = HAL_UART_STATE_READY;
2168 
2169     /* As no DMA to be aborted, call directly user Abort complete callback */
2170 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2171     /* Call registered Abort Receive Complete Callback */
2172     huart->AbortReceiveCpltCallback(huart);
2173 #else
2174     /* Call legacy weak Abort Receive Complete Callback */
2175     HAL_UART_AbortReceiveCpltCallback(huart);
2176 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2177   }
2178 
2179   return HAL_OK;
2180 }
2181 
2182 /**
2183   * @brief Handle UART interrupt request.
2184   * @param huart UART handle.
2185   * @retval None
2186   */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)2187 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2188 {
2189   uint32_t isrflags   = READ_REG(huart->Instance->ISR);
2190   uint32_t cr1its     = READ_REG(huart->Instance->CR1);
2191   uint32_t cr3its     = READ_REG(huart->Instance->CR3);
2192 
2193   uint32_t errorflags;
2194   uint32_t errorcode;
2195 
2196   /* If no error occurs */
2197   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2198   if (errorflags == 0U)
2199   {
2200     /* UART in mode Receiver ---------------------------------------------------*/
2201     if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2202         && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2203             || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2204     {
2205       if (huart->RxISR != NULL)
2206       {
2207         huart->RxISR(huart);
2208       }
2209       return;
2210     }
2211   }
2212 
2213   /* If some errors occur */
2214   if ((errorflags != 0U)
2215       && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2216            || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
2217   {
2218     /* UART parity error interrupt occurred -------------------------------------*/
2219     if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2220     {
2221       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2222 
2223       huart->ErrorCode |= HAL_UART_ERROR_PE;
2224     }
2225 
2226     /* UART frame error interrupt occurred --------------------------------------*/
2227     if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2228     {
2229       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2230 
2231       huart->ErrorCode |= HAL_UART_ERROR_FE;
2232     }
2233 
2234     /* UART noise error interrupt occurred --------------------------------------*/
2235     if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2236     {
2237       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2238 
2239       huart->ErrorCode |= HAL_UART_ERROR_NE;
2240     }
2241 
2242     /* UART Over-Run interrupt occurred -----------------------------------------*/
2243     if (((isrflags & USART_ISR_ORE) != 0U)
2244         && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2245             ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2246     {
2247       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2248 
2249       huart->ErrorCode |= HAL_UART_ERROR_ORE;
2250     }
2251 
2252     /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2253     if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2254     {
2255       __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2256 
2257       huart->ErrorCode |= HAL_UART_ERROR_RTO;
2258     }
2259 
2260     /* Call UART Error Call back function if need be ----------------------------*/
2261     if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2262     {
2263       /* UART in mode Receiver --------------------------------------------------*/
2264       if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2265           && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2266               || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2267       {
2268         if (huart->RxISR != NULL)
2269         {
2270           huart->RxISR(huart);
2271         }
2272       }
2273 
2274       /* If Error is to be considered as blocking :
2275           - Receiver Timeout error in Reception
2276           - Overrun error in Reception
2277           - any error occurs in DMA mode reception
2278       */
2279       errorcode = huart->ErrorCode;
2280       if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2281           ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2282       {
2283         /* Blocking error : transfer is aborted
2284            Set the UART state ready to be able to start again the process,
2285            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2286         UART_EndRxTransfer(huart);
2287 
2288         /* Disable the UART DMA Rx request if enabled */
2289         if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2290         {
2291           CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2292 
2293           /* Abort the UART DMA Rx channel */
2294           if (huart->hdmarx != NULL)
2295           {
2296             /* Set the UART DMA Abort callback :
2297                will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2298             huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2299 
2300             /* Abort DMA RX */
2301             if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2302             {
2303               /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2304               huart->hdmarx->XferAbortCallback(huart->hdmarx);
2305             }
2306           }
2307           else
2308           {
2309             /* Call user error callback */
2310 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2311             /*Call registered error callback*/
2312             huart->ErrorCallback(huart);
2313 #else
2314             /*Call legacy weak error callback*/
2315             HAL_UART_ErrorCallback(huart);
2316 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2317 
2318           }
2319         }
2320         else
2321         {
2322           /* Call user error callback */
2323 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2324           /*Call registered error callback*/
2325           huart->ErrorCallback(huart);
2326 #else
2327           /*Call legacy weak error callback*/
2328           HAL_UART_ErrorCallback(huart);
2329 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2330         }
2331       }
2332       else
2333       {
2334         /* Non Blocking error : transfer could go on.
2335            Error is notified to user through user error callback */
2336 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2337         /*Call registered error callback*/
2338         huart->ErrorCallback(huart);
2339 #else
2340         /*Call legacy weak error callback*/
2341         HAL_UART_ErrorCallback(huart);
2342 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2343         huart->ErrorCode = HAL_UART_ERROR_NONE;
2344       }
2345     }
2346     return;
2347 
2348   } /* End if some error occurs */
2349 
2350   /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2351   if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2352   {
2353     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2354 
2355     /* UART Rx state is not reset as a reception process might be ongoing.
2356        If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2357 
2358 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2359     /* Call registered Wakeup Callback */
2360     huart->WakeupCallback(huart);
2361 #else
2362     /* Call legacy weak Wakeup Callback */
2363     HAL_UARTEx_WakeupCallback(huart);
2364 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2365     return;
2366   }
2367 
2368   /* UART in mode Transmitter ------------------------------------------------*/
2369   if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2370       && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2371           || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2372   {
2373     if (huart->TxISR != NULL)
2374     {
2375       huart->TxISR(huart);
2376     }
2377     return;
2378   }
2379 
2380   /* UART in mode Transmitter (transmission end) -----------------------------*/
2381   if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2382   {
2383     UART_EndTransmit_IT(huart);
2384     return;
2385   }
2386 
2387   /* UART TX Fifo Empty occurred ----------------------------------------------*/
2388   if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2389   {
2390 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2391     /* Call registered Tx Fifo Empty Callback */
2392     huart->TxFifoEmptyCallback(huart);
2393 #else
2394     /* Call legacy weak Tx Fifo Empty Callback */
2395     HAL_UARTEx_TxFifoEmptyCallback(huart);
2396 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2397     return;
2398   }
2399 
2400   /* UART RX Fifo Full occurred ----------------------------------------------*/
2401   if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2402   {
2403 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2404     /* Call registered Rx Fifo Full Callback */
2405     huart->RxFifoFullCallback(huart);
2406 #else
2407     /* Call legacy weak Rx Fifo Full Callback */
2408     HAL_UARTEx_RxFifoFullCallback(huart);
2409 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2410     return;
2411   }
2412 }
2413 
2414 /**
2415   * @brief Tx Transfer completed callback.
2416   * @param huart UART handle.
2417   * @retval None
2418   */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2419 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2420 {
2421   /* Prevent unused argument(s) compilation warning */
2422   UNUSED(huart);
2423 
2424   /* NOTE : This function should not be modified, when the callback is needed,
2425             the HAL_UART_TxCpltCallback can be implemented in the user file.
2426    */
2427 }
2428 
2429 /**
2430   * @brief  Tx Half Transfer completed callback.
2431   * @param  huart UART handle.
2432   * @retval None
2433   */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2434 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2435 {
2436   /* Prevent unused argument(s) compilation warning */
2437   UNUSED(huart);
2438 
2439   /* NOTE: This function should not be modified, when the callback is needed,
2440            the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2441    */
2442 }
2443 
2444 /**
2445   * @brief  Rx Transfer completed callback.
2446   * @param  huart UART handle.
2447   * @retval None
2448   */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2449 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2450 {
2451   /* Prevent unused argument(s) compilation warning */
2452   UNUSED(huart);
2453 
2454   /* NOTE : This function should not be modified, when the callback is needed,
2455             the HAL_UART_RxCpltCallback can be implemented in the user file.
2456    */
2457 }
2458 
2459 /**
2460   * @brief  Rx Half Transfer completed callback.
2461   * @param  huart UART handle.
2462   * @retval None
2463   */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2464 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2465 {
2466   /* Prevent unused argument(s) compilation warning */
2467   UNUSED(huart);
2468 
2469   /* NOTE: This function should not be modified, when the callback is needed,
2470            the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2471    */
2472 }
2473 
2474 /**
2475   * @brief  UART error callback.
2476   * @param  huart UART handle.
2477   * @retval None
2478   */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2479 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2480 {
2481   /* Prevent unused argument(s) compilation warning */
2482   UNUSED(huart);
2483 
2484   /* NOTE : This function should not be modified, when the callback is needed,
2485             the HAL_UART_ErrorCallback can be implemented in the user file.
2486    */
2487 }
2488 
2489 /**
2490   * @brief  UART Abort Complete callback.
2491   * @param  huart UART handle.
2492   * @retval None
2493   */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2494 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2495 {
2496   /* Prevent unused argument(s) compilation warning */
2497   UNUSED(huart);
2498 
2499   /* NOTE : This function should not be modified, when the callback is needed,
2500             the HAL_UART_AbortCpltCallback can be implemented in the user file.
2501    */
2502 }
2503 
2504 /**
2505   * @brief  UART Abort Complete callback.
2506   * @param  huart UART handle.
2507   * @retval None
2508   */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2509 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2510 {
2511   /* Prevent unused argument(s) compilation warning */
2512   UNUSED(huart);
2513 
2514   /* NOTE : This function should not be modified, when the callback is needed,
2515             the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2516    */
2517 }
2518 
2519 /**
2520   * @brief  UART Abort Receive Complete callback.
2521   * @param  huart UART handle.
2522   * @retval None
2523   */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2524 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2525 {
2526   /* Prevent unused argument(s) compilation warning */
2527   UNUSED(huart);
2528 
2529   /* NOTE : This function should not be modified, when the callback is needed,
2530             the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2531    */
2532 }
2533 
2534 /**
2535   * @}
2536   */
2537 
2538 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2539   *  @brief   UART control functions
2540   *
2541 @verbatim
2542  ===============================================================================
2543                       ##### Peripheral Control functions #####
2544  ===============================================================================
2545     [..]
2546     This subsection provides a set of functions allowing to control the UART.
2547      (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2548      (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2549      (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2550      (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2551      (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2552      (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2553      (+) UART_SetConfig() API configures the UART peripheral
2554      (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2555      (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2556      (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2557      (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2558      (+) HAL_LIN_SendBreak() API transmits the break characters
2559 @endverbatim
2560   * @{
2561   */
2562 
2563 /**
2564   * @brief  Update on the fly the receiver timeout value in RTOR register.
2565   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2566   *                    the configuration information for the specified UART module.
2567   * @param  TimeoutValue receiver timeout value in number of baud blocks. The timeout
2568   *                     value must be less or equal to 0x0FFFFFFFF.
2569   * @retval None
2570   */
HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef * huart,uint32_t TimeoutValue)2571 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2572 {
2573   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2574   {
2575     assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2576     MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2577   }
2578 }
2579 
2580 /**
2581   * @brief  Enable the UART receiver timeout feature.
2582   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2583   *                    the configuration information for the specified UART module.
2584   * @retval HAL status
2585   */
HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef * huart)2586 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2587 {
2588   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2589   {
2590     if (huart->gState == HAL_UART_STATE_READY)
2591     {
2592       /* Process Locked */
2593       __HAL_LOCK(huart);
2594 
2595       huart->gState = HAL_UART_STATE_BUSY;
2596 
2597       /* Set the USART RTOEN bit */
2598       SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2599 
2600       huart->gState = HAL_UART_STATE_READY;
2601 
2602       /* Process Unlocked */
2603       __HAL_UNLOCK(huart);
2604 
2605       return HAL_OK;
2606     }
2607     else
2608     {
2609       return HAL_BUSY;
2610     }
2611   }
2612   else
2613   {
2614     return HAL_ERROR;
2615   }
2616 }
2617 
2618 /**
2619   * @brief  Disable the UART receiver timeout feature.
2620   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2621   *                    the configuration information for the specified UART module.
2622   * @retval HAL status
2623   */
HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef * huart)2624 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2625 {
2626   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2627   {
2628     if (huart->gState == HAL_UART_STATE_READY)
2629     {
2630       /* Process Locked */
2631       __HAL_LOCK(huart);
2632 
2633       huart->gState = HAL_UART_STATE_BUSY;
2634 
2635       /* Clear the USART RTOEN bit */
2636       CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2637 
2638       huart->gState = HAL_UART_STATE_READY;
2639 
2640       /* Process Unlocked */
2641       __HAL_UNLOCK(huart);
2642 
2643       return HAL_OK;
2644     }
2645     else
2646     {
2647       return HAL_BUSY;
2648     }
2649   }
2650   else
2651   {
2652     return HAL_ERROR;
2653   }
2654 }
2655 
2656 /**
2657   * @brief  Enable UART in mute mode (does not mean UART enters mute mode;
2658   *         to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2659   * @param  huart UART handle.
2660   * @retval HAL status
2661   */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2662 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2663 {
2664   __HAL_LOCK(huart);
2665 
2666   huart->gState = HAL_UART_STATE_BUSY;
2667 
2668   /* Enable USART mute mode by setting the MME bit in the CR1 register */
2669   SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2670 
2671   huart->gState = HAL_UART_STATE_READY;
2672 
2673   return (UART_CheckIdleState(huart));
2674 }
2675 
2676 /**
2677   * @brief  Disable UART mute mode (does not mean the UART actually exits mute mode
2678   *         as it may not have been in mute mode at this very moment).
2679   * @param  huart UART handle.
2680   * @retval HAL status
2681   */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2682 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2683 {
2684   __HAL_LOCK(huart);
2685 
2686   huart->gState = HAL_UART_STATE_BUSY;
2687 
2688   /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2689   CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2690 
2691   huart->gState = HAL_UART_STATE_READY;
2692 
2693   return (UART_CheckIdleState(huart));
2694 }
2695 
2696 /**
2697   * @brief Enter UART mute mode (means UART actually enters mute mode).
2698   * @note  To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2699   * @param huart UART handle.
2700   * @retval None
2701   */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2702 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2703 {
2704   __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2705 }
2706 
2707 /**
2708   * @brief  Enable the UART transmitter and disable the UART receiver.
2709   * @param  huart UART handle.
2710   * @retval HAL status
2711   */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2712 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2713 {
2714   __HAL_LOCK(huart);
2715   huart->gState = HAL_UART_STATE_BUSY;
2716 
2717   /* Clear TE and RE bits */
2718   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2719 
2720   /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2721   SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2722 
2723   huart->gState = HAL_UART_STATE_READY;
2724 
2725   __HAL_UNLOCK(huart);
2726 
2727   return HAL_OK;
2728 }
2729 
2730 /**
2731   * @brief  Enable the UART receiver and disable the UART transmitter.
2732   * @param  huart UART handle.
2733   * @retval HAL status.
2734   */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2735 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2736 {
2737   __HAL_LOCK(huart);
2738   huart->gState = HAL_UART_STATE_BUSY;
2739 
2740   /* Clear TE and RE bits */
2741   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2742 
2743   /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2744   SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2745 
2746   huart->gState = HAL_UART_STATE_READY;
2747 
2748   __HAL_UNLOCK(huart);
2749 
2750   return HAL_OK;
2751 }
2752 
2753 
2754 /**
2755   * @brief  Transmit break characters.
2756   * @param  huart UART handle.
2757   * @retval HAL status
2758   */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)2759 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2760 {
2761   /* Check the parameters */
2762   assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2763 
2764   __HAL_LOCK(huart);
2765 
2766   huart->gState = HAL_UART_STATE_BUSY;
2767 
2768   /* Send break characters */
2769   __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
2770 
2771   huart->gState = HAL_UART_STATE_READY;
2772 
2773   __HAL_UNLOCK(huart);
2774 
2775   return HAL_OK;
2776 }
2777 
2778 /**
2779   * @}
2780   */
2781 
2782 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
2783   *  @brief   UART Peripheral State functions
2784   *
2785 @verbatim
2786   ==============================================================================
2787             ##### Peripheral State and Error functions #####
2788   ==============================================================================
2789     [..]
2790     This subsection provides functions allowing to :
2791       (+) Return the UART handle state.
2792       (+) Return the UART handle error code
2793 
2794 @endverbatim
2795   * @{
2796   */
2797 
2798 /**
2799   * @brief Return the UART handle state.
2800   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2801   *               the configuration information for the specified UART.
2802   * @retval HAL state
2803   */
HAL_UART_GetState(UART_HandleTypeDef * huart)2804 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
2805 {
2806   uint32_t temp1;
2807   uint32_t temp2;
2808   temp1 = huart->gState;
2809   temp2 = huart->RxState;
2810 
2811   return (HAL_UART_StateTypeDef)(temp1 | temp2);
2812 }
2813 
2814 /**
2815   * @brief  Return the UART handle error code.
2816   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2817   *               the configuration information for the specified UART.
2818   * @retval UART Error Code
2819   */
HAL_UART_GetError(UART_HandleTypeDef * huart)2820 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
2821 {
2822   return huart->ErrorCode;
2823 }
2824 /**
2825   * @}
2826   */
2827 
2828 /**
2829   * @}
2830   */
2831 
2832 /** @defgroup UART_Private_Functions UART Private Functions
2833   * @{
2834   */
2835 
2836 /**
2837   * @brief  Initialize the callbacks to their default values.
2838   * @param  huart UART handle.
2839   * @retval none
2840   */
2841 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)2842 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
2843 {
2844   /* Init the UART Callback settings */
2845   huart->TxHalfCpltCallback        = HAL_UART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2846   huart->TxCpltCallback            = HAL_UART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2847   huart->RxHalfCpltCallback        = HAL_UART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2848   huart->RxCpltCallback            = HAL_UART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2849   huart->ErrorCallback             = HAL_UART_ErrorCallback;             /* Legacy weak ErrorCallback             */
2850   huart->AbortCpltCallback         = HAL_UART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2851   huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2852   huart->AbortReceiveCpltCallback  = HAL_UART_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
2853   huart->WakeupCallback            = HAL_UARTEx_WakeupCallback;          /* Legacy weak WakeupCallback            */
2854   huart->RxFifoFullCallback        = HAL_UARTEx_RxFifoFullCallback;      /* Legacy weak RxFifoFullCallback        */
2855   huart->TxFifoEmptyCallback       = HAL_UARTEx_TxFifoEmptyCallback;     /* Legacy weak TxFifoEmptyCallback       */
2856 
2857 }
2858 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2859 
2860 /**
2861   * @brief Configure the UART peripheral.
2862   * @param huart UART handle.
2863   * @retval HAL status
2864   */
UART_SetConfig(UART_HandleTypeDef * huart)2865 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
2866 {
2867   uint32_t tmpreg;
2868   uint16_t brrtemp;
2869   UART_ClockSourceTypeDef clocksource;
2870   uint32_t usartdiv                   = 0x00000000U;
2871   HAL_StatusTypeDef ret               = HAL_OK;
2872 #if defined(LPUART1)
2873   uint32_t lpuart_ker_ck_pres         = 0x00000000U;
2874 #endif
2875   uint32_t pclk;
2876 
2877   /* Check the parameters */
2878   assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
2879   assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
2880 #if defined(LPUART1)
2881   if (UART_INSTANCE_LOWPOWER(huart))
2882   {
2883     assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
2884   }
2885   else
2886   {
2887     assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
2888     assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
2889   }
2890 #else
2891   assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
2892   assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
2893 #endif
2894 
2895   assert_param(IS_UART_PARITY(huart->Init.Parity));
2896   assert_param(IS_UART_MODE(huart->Init.Mode));
2897   assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
2898   assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
2899   assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
2900 
2901   /*-------------------------- USART CR1 Configuration -----------------------*/
2902   /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
2903   *  the UART Word Length, Parity, Mode and oversampling:
2904   *  set the M bits according to huart->Init.WordLength value
2905   *  set PCE and PS bits according to huart->Init.Parity value
2906   *  set TE and RE bits according to huart->Init.Mode value
2907   *  set OVER8 bit according to huart->Init.OverSampling value */
2908   tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
2909   tmpreg |= (uint32_t)huart->FifoMode;
2910   MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2911 
2912   /*-------------------------- USART CR2 Configuration -----------------------*/
2913   /* Configure the UART Stop Bits: Set STOP[13:12] bits according
2914   * to huart->Init.StopBits value */
2915   MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
2916 
2917   /*-------------------------- USART CR3 Configuration -----------------------*/
2918   /* Configure
2919   * - UART HardWare Flow Control: set CTSE and RTSE bits according
2920   *   to huart->Init.HwFlowCtl value
2921   * - one-bit sampling method versus three samples' majority rule according
2922   *   to huart->Init.OneBitSampling (not applicable to LPUART) */
2923   tmpreg = (uint32_t)huart->Init.HwFlowCtl;
2924 
2925 #if defined(LPUART1)
2926   if (!(UART_INSTANCE_LOWPOWER(huart)))
2927   {
2928     tmpreg |= huart->Init.OneBitSampling;
2929   }
2930 #else
2931   tmpreg |= huart->Init.OneBitSampling;
2932 #endif
2933   MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
2934 
2935   /*-------------------------- USART PRESC Configuration -----------------------*/
2936   /* Configure
2937   * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
2938   MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
2939 
2940   /*-------------------------- USART BRR Configuration -----------------------*/
2941   UART_GETCLOCKSOURCE(huart, clocksource);
2942 
2943 #if defined(LPUART1)
2944   /* Check LPUART instance */
2945   if (UART_INSTANCE_LOWPOWER(huart))
2946   {
2947     /* Retrieve frequency clock */
2948     switch (clocksource)
2949     {
2950       case UART_CLOCKSOURCE_PCLK1:
2951         lpuart_ker_ck_pres = (HAL_RCC_GetPCLK1Freq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2952         break;
2953       case UART_CLOCKSOURCE_HSI:
2954         lpuart_ker_ck_pres = ((uint32_t)HSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2955         break;
2956       case UART_CLOCKSOURCE_SYSCLK:
2957         lpuart_ker_ck_pres = (HAL_RCC_GetSysClockFreq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2958         break;
2959       case UART_CLOCKSOURCE_LSE:
2960         lpuart_ker_ck_pres = ((uint32_t)LSE_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2961         break;
2962       default:
2963         ret = HAL_ERROR;
2964         break;
2965     }
2966 
2967     /* if proper clock source reported */
2968     if (lpuart_ker_ck_pres != 0U)
2969     {
2970       /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
2971       if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
2972           (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
2973       {
2974         ret = HAL_ERROR;
2975       }
2976       else
2977       {
2978         switch (clocksource)
2979         {
2980           case UART_CLOCKSOURCE_PCLK1:
2981             pclk = HAL_RCC_GetPCLK1Freq();
2982             usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2983             break;
2984           case UART_CLOCKSOURCE_HSI:
2985             usartdiv = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2986             break;
2987           case UART_CLOCKSOURCE_SYSCLK:
2988             pclk = HAL_RCC_GetSysClockFreq();
2989             usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2990             break;
2991           case UART_CLOCKSOURCE_LSE:
2992             usartdiv = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2993             break;
2994           default:
2995             ret = HAL_ERROR;
2996             break;
2997         }
2998 
2999         /* It is forbidden to write values lower than 0x300 in the LPUART_BRR register */
3000         if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
3001         {
3002           huart->Instance->BRR = usartdiv;
3003         }
3004         else
3005         {
3006           ret = HAL_ERROR;
3007         }
3008       } /*   if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
3009     } /* if (lpuart_ker_ck_pres != 0) */
3010   }
3011   /* Check UART Over Sampling to set Baud Rate Register */
3012   else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3013 #else
3014   if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3015 #endif /* LPUART1 */
3016   {
3017     switch (clocksource)
3018     {
3019       case UART_CLOCKSOURCE_PCLK2:
3020         pclk = HAL_RCC_GetPCLK2Freq();
3021         usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3022         break;
3023       case UART_CLOCKSOURCE_HSI:
3024         usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3025         break;
3026       case UART_CLOCKSOURCE_SYSCLK:
3027         pclk = HAL_RCC_GetSysClockFreq();
3028         usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3029         break;
3030       case UART_CLOCKSOURCE_LSE:
3031         usartdiv = (uint16_t)(UART_DIV_SAMPLING8((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3032         break;
3033       default:
3034         ret = HAL_ERROR;
3035         break;
3036     }
3037 
3038     /* USARTDIV must be greater than or equal to 0d16 */
3039     if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3040     {
3041       brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3042       brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3043       huart->Instance->BRR = brrtemp;
3044     }
3045     else
3046     {
3047       ret = HAL_ERROR;
3048     }
3049   }
3050   else
3051   {
3052     switch (clocksource)
3053     {
3054       case UART_CLOCKSOURCE_PCLK2:
3055         pclk = HAL_RCC_GetPCLK2Freq();
3056         usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3057         break;
3058       case UART_CLOCKSOURCE_HSI:
3059         usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3060         break;
3061       case UART_CLOCKSOURCE_SYSCLK:
3062         pclk = HAL_RCC_GetSysClockFreq();
3063         usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3064         break;
3065       case UART_CLOCKSOURCE_LSE:
3066         usartdiv = (uint16_t)(UART_DIV_SAMPLING16((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3067         break;
3068       default:
3069         ret = HAL_ERROR;
3070         break;
3071     }
3072 
3073     /* USARTDIV must be greater than or equal to 0d16 */
3074     if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3075     {
3076       huart->Instance->BRR = usartdiv;
3077     }
3078     else
3079     {
3080       ret = HAL_ERROR;
3081     }
3082   }
3083 
3084   /* Initialize the number of data to process during RX/TX ISR execution */
3085   huart->NbTxDataToProcess = 1;
3086   huart->NbRxDataToProcess = 1;
3087 
3088   /* Clear ISR function pointers */
3089   huart->RxISR = NULL;
3090   huart->TxISR = NULL;
3091 
3092   return ret;
3093 }
3094 
3095 /**
3096   * @brief Configure the UART peripheral advanced features.
3097   * @param huart UART handle.
3098   * @retval None
3099   */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3100 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3101 {
3102   /* Check whether the set of advanced features to configure is properly set */
3103   assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3104 
3105   /* if required, configure TX pin active level inversion */
3106   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3107   {
3108     assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3109     MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3110   }
3111 
3112   /* if required, configure RX pin active level inversion */
3113   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3114   {
3115     assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3116     MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3117   }
3118 
3119   /* if required, configure data inversion */
3120   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3121   {
3122     assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3123     MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3124   }
3125 
3126   /* if required, configure RX/TX pins swap */
3127   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3128   {
3129     assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3130     MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3131   }
3132 
3133   /* if required, configure RX overrun detection disabling */
3134   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3135   {
3136     assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3137     MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3138   }
3139 
3140   /* if required, configure DMA disabling on reception error */
3141   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3142   {
3143     assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3144     MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3145   }
3146 
3147   /* if required, configure auto Baud rate detection scheme */
3148   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3149   {
3150     assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3151     assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3152     MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3153     /* set auto Baudrate detection parameters if detection is enabled */
3154     if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3155     {
3156       assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3157       MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3158     }
3159   }
3160 
3161   /* if required, configure MSB first on communication line */
3162   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3163   {
3164     assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3165     MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3166   }
3167 }
3168 
3169 /**
3170   * @brief Check the UART Idle State.
3171   * @param huart UART handle.
3172   * @retval HAL status
3173   */
UART_CheckIdleState(UART_HandleTypeDef * huart)3174 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3175 {
3176   uint32_t tickstart;
3177 
3178   /* Initialize the UART ErrorCode */
3179   huart->ErrorCode = HAL_UART_ERROR_NONE;
3180 
3181   /* Init tickstart for timeout managment*/
3182   tickstart = HAL_GetTick();
3183 
3184   /* Check if the Transmitter is enabled */
3185   if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3186   {
3187     /* Wait until TEACK flag is set */
3188     if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3189     {
3190       /* Timeout occurred */
3191       return HAL_TIMEOUT;
3192     }
3193   }
3194 
3195   /* Check if the Receiver is enabled */
3196   if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3197   {
3198     /* Wait until REACK flag is set */
3199     if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3200     {
3201       /* Timeout occurred */
3202       return HAL_TIMEOUT;
3203     }
3204   }
3205 
3206   /* Initialize the UART State */
3207   huart->gState = HAL_UART_STATE_READY;
3208   huart->RxState = HAL_UART_STATE_READY;
3209 
3210   __HAL_UNLOCK(huart);
3211 
3212   return HAL_OK;
3213 }
3214 
3215 /**
3216   * @brief  Handle UART Communication Timeout.
3217   * @param huart     UART handle.
3218   * @param Flag      Specifies the UART flag to check
3219   * @param Status    Flag status (SET or RESET)
3220   * @param Tickstart Tick start value
3221   * @param Timeout   Timeout duration
3222   * @retval HAL status
3223   */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3224 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3225                                               uint32_t Tickstart, uint32_t Timeout)
3226 {
3227   /* Wait until flag is set */
3228   while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3229   {
3230     /* Check for the Timeout */
3231     if (Timeout != HAL_MAX_DELAY)
3232     {
3233       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3234       {
3235         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
3236         CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
3237         CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3238 
3239         huart->gState = HAL_UART_STATE_READY;
3240         huart->RxState = HAL_UART_STATE_READY;
3241 
3242         __HAL_UNLOCK(huart);
3243 
3244         return HAL_TIMEOUT;
3245       }
3246 
3247       if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
3248       {
3249         if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3250         {
3251           /* Clear Receiver Timeout flag*/
3252           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3253 
3254           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
3255           CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
3256           CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3257 
3258           huart->gState = HAL_UART_STATE_READY;
3259           huart->RxState = HAL_UART_STATE_READY;
3260           huart->ErrorCode = HAL_UART_ERROR_RTO;
3261 
3262           /* Process Unlocked */
3263           __HAL_UNLOCK(huart);
3264 
3265           return HAL_TIMEOUT;
3266         }
3267       }
3268     }
3269   }
3270   return HAL_OK;
3271 }
3272 
3273 
3274 /**
3275   * @brief  End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3276   * @param  huart UART handle.
3277   * @retval None
3278   */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3279 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3280 {
3281   /* Disable TXEIE, TCIE, TXFT interrupts */
3282   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3283   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3284 
3285   /* At end of Tx process, restore huart->gState to Ready */
3286   huart->gState = HAL_UART_STATE_READY;
3287 }
3288 
3289 
3290 /**
3291   * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3292   * @param  huart UART handle.
3293   * @retval None
3294   */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3295 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3296 {
3297   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3298   CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3299   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3300 
3301   /* At end of Rx process, restore huart->RxState to Ready */
3302   huart->RxState = HAL_UART_STATE_READY;
3303 
3304   /* Reset RxIsr function pointer */
3305   huart->RxISR = NULL;
3306 }
3307 
3308 
3309 /**
3310   * @brief DMA UART transmit process complete callback.
3311   * @param hdma DMA handle.
3312   * @retval None
3313   */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3314 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3315 {
3316   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3317 
3318   /* DMA Normal mode */
3319   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3320   {
3321     huart->TxXferCount = 0U;
3322 
3323     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3324        in the UART CR3 register */
3325     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3326 
3327     /* Enable the UART Transmit Complete Interrupt */
3328     SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3329   }
3330   /* DMA Circular mode */
3331   else
3332   {
3333 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3334     /*Call registered Tx complete callback*/
3335     huart->TxCpltCallback(huart);
3336 #else
3337     /*Call legacy weak Tx complete callback*/
3338     HAL_UART_TxCpltCallback(huart);
3339 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3340   }
3341 }
3342 
3343 /**
3344   * @brief DMA UART transmit process half complete callback.
3345   * @param hdma DMA handle.
3346   * @retval None
3347   */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3348 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3349 {
3350   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3351 
3352 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3353   /*Call registered Tx Half complete callback*/
3354   huart->TxHalfCpltCallback(huart);
3355 #else
3356   /*Call legacy weak Tx Half complete callback*/
3357   HAL_UART_TxHalfCpltCallback(huart);
3358 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3359 }
3360 
3361 /**
3362   * @brief DMA UART receive process complete callback.
3363   * @param hdma DMA handle.
3364   * @retval None
3365   */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3366 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3367 {
3368   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3369 
3370   /* DMA Normal mode */
3371   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3372   {
3373     huart->RxXferCount = 0U;
3374 
3375     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3376     CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3377     CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3378 
3379     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3380        in the UART CR3 register */
3381     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3382 
3383     /* At end of Rx process, restore huart->RxState to Ready */
3384     huart->RxState = HAL_UART_STATE_READY;
3385   }
3386 
3387 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3388   /*Call registered Rx complete callback*/
3389   huart->RxCpltCallback(huart);
3390 #else
3391   /*Call legacy weak Rx complete callback*/
3392   HAL_UART_RxCpltCallback(huart);
3393 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3394 }
3395 
3396 /**
3397   * @brief DMA UART receive process half complete callback.
3398   * @param hdma DMA handle.
3399   * @retval None
3400   */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3401 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3402 {
3403   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3404 
3405 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3406   /*Call registered Rx Half complete callback*/
3407   huart->RxHalfCpltCallback(huart);
3408 #else
3409   /*Call legacy weak Rx Half complete callback*/
3410   HAL_UART_RxHalfCpltCallback(huart);
3411 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3412 }
3413 
3414 /**
3415   * @brief DMA UART communication error callback.
3416   * @param hdma DMA handle.
3417   * @retval None
3418   */
UART_DMAError(DMA_HandleTypeDef * hdma)3419 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3420 {
3421   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3422 
3423   const HAL_UART_StateTypeDef gstate = huart->gState;
3424   const HAL_UART_StateTypeDef rxstate = huart->RxState;
3425 
3426   /* Stop UART DMA Tx request if ongoing */
3427   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3428       (gstate == HAL_UART_STATE_BUSY_TX))
3429   {
3430     huart->TxXferCount = 0U;
3431     UART_EndTxTransfer(huart);
3432   }
3433 
3434   /* Stop UART DMA Rx request if ongoing */
3435   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3436       (rxstate == HAL_UART_STATE_BUSY_RX))
3437   {
3438     huart->RxXferCount = 0U;
3439     UART_EndRxTransfer(huart);
3440   }
3441 
3442   huart->ErrorCode |= HAL_UART_ERROR_DMA;
3443 
3444 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3445   /*Call registered error callback*/
3446   huart->ErrorCallback(huart);
3447 #else
3448   /*Call legacy weak error callback*/
3449   HAL_UART_ErrorCallback(huart);
3450 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3451 }
3452 
3453 /**
3454   * @brief  DMA UART communication abort callback, when initiated by HAL services on Error
3455   *         (To be called at end of DMA Abort procedure following error occurrence).
3456   * @param  hdma DMA handle.
3457   * @retval None
3458   */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3459 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3460 {
3461   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3462   huart->RxXferCount = 0U;
3463   huart->TxXferCount = 0U;
3464 
3465 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3466   /*Call registered error callback*/
3467   huart->ErrorCallback(huart);
3468 #else
3469   /*Call legacy weak error callback*/
3470   HAL_UART_ErrorCallback(huart);
3471 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3472 }
3473 
3474 /**
3475   * @brief  DMA UART Tx communication abort callback, when initiated by user
3476   *         (To be called at end of DMA Tx Abort procedure following user abort request).
3477   * @note   When this callback is executed, User Abort complete call back is called only if no
3478   *         Abort still ongoing for Rx DMA Handle.
3479   * @param  hdma DMA handle.
3480   * @retval None
3481   */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3482 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3483 {
3484   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3485 
3486   huart->hdmatx->XferAbortCallback = NULL;
3487 
3488   /* Check if an Abort process is still ongoing */
3489   if (huart->hdmarx != NULL)
3490   {
3491     if (huart->hdmarx->XferAbortCallback != NULL)
3492     {
3493       return;
3494     }
3495   }
3496 
3497   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3498   huart->TxXferCount = 0U;
3499   huart->RxXferCount = 0U;
3500 
3501   /* Reset errorCode */
3502   huart->ErrorCode = HAL_UART_ERROR_NONE;
3503 
3504   /* Clear the Error flags in the ICR register */
3505   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3506 
3507   /* Flush the whole TX FIFO (if needed) */
3508   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3509   {
3510     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3511   }
3512 
3513   /* Restore huart->gState and huart->RxState to Ready */
3514   huart->gState  = HAL_UART_STATE_READY;
3515   huart->RxState = HAL_UART_STATE_READY;
3516 
3517   /* Call user Abort complete callback */
3518 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3519   /* Call registered Abort complete callback */
3520   huart->AbortCpltCallback(huart);
3521 #else
3522   /* Call legacy weak Abort complete callback */
3523   HAL_UART_AbortCpltCallback(huart);
3524 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3525 }
3526 
3527 
3528 /**
3529   * @brief  DMA UART Rx communication abort callback, when initiated by user
3530   *         (To be called at end of DMA Rx Abort procedure following user abort request).
3531   * @note   When this callback is executed, User Abort complete call back is called only if no
3532   *         Abort still ongoing for Tx DMA Handle.
3533   * @param  hdma DMA handle.
3534   * @retval None
3535   */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3536 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3537 {
3538   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3539 
3540   huart->hdmarx->XferAbortCallback = NULL;
3541 
3542   /* Check if an Abort process is still ongoing */
3543   if (huart->hdmatx != NULL)
3544   {
3545     if (huart->hdmatx->XferAbortCallback != NULL)
3546     {
3547       return;
3548     }
3549   }
3550 
3551   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3552   huart->TxXferCount = 0U;
3553   huart->RxXferCount = 0U;
3554 
3555   /* Reset errorCode */
3556   huart->ErrorCode = HAL_UART_ERROR_NONE;
3557 
3558   /* Clear the Error flags in the ICR register */
3559   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3560 
3561   /* Discard the received data */
3562   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3563 
3564   /* Restore huart->gState and huart->RxState to Ready */
3565   huart->gState  = HAL_UART_STATE_READY;
3566   huart->RxState = HAL_UART_STATE_READY;
3567 
3568   /* Call user Abort complete callback */
3569 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3570   /* Call registered Abort complete callback */
3571   huart->AbortCpltCallback(huart);
3572 #else
3573   /* Call legacy weak Abort complete callback */
3574   HAL_UART_AbortCpltCallback(huart);
3575 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3576 }
3577 
3578 
3579 /**
3580   * @brief  DMA UART Tx communication abort callback, when initiated by user by a call to
3581   *         HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3582   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3583   *         and leads to user Tx Abort Complete callback execution).
3584   * @param  hdma DMA handle.
3585   * @retval None
3586   */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3587 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3588 {
3589   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3590 
3591   huart->TxXferCount = 0U;
3592 
3593   /* Flush the whole TX FIFO (if needed) */
3594   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3595   {
3596     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3597   }
3598 
3599   /* Restore huart->gState to Ready */
3600   huart->gState = HAL_UART_STATE_READY;
3601 
3602   /* Call user Abort complete callback */
3603 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3604   /* Call registered Abort Transmit Complete Callback */
3605   huart->AbortTransmitCpltCallback(huart);
3606 #else
3607   /* Call legacy weak Abort Transmit Complete Callback */
3608   HAL_UART_AbortTransmitCpltCallback(huart);
3609 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3610 }
3611 
3612 /**
3613   * @brief  DMA UART Rx communication abort callback, when initiated by user by a call to
3614   *         HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3615   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3616   *         and leads to user Rx Abort Complete callback execution).
3617   * @param  hdma DMA handle.
3618   * @retval None
3619   */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3620 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3621 {
3622   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3623 
3624   huart->RxXferCount = 0U;
3625 
3626   /* Clear the Error flags in the ICR register */
3627   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3628 
3629   /* Discard the received data */
3630   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3631 
3632   /* Restore huart->RxState to Ready */
3633   huart->RxState = HAL_UART_STATE_READY;
3634 
3635   /* Call user Abort complete callback */
3636 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3637   /* Call registered Abort Receive Complete Callback */
3638   huart->AbortReceiveCpltCallback(huart);
3639 #else
3640   /* Call legacy weak Abort Receive Complete Callback */
3641   HAL_UART_AbortReceiveCpltCallback(huart);
3642 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3643 }
3644 
3645 /**
3646   * @brief TX interrrupt handler for 7 or 8 bits data word length .
3647   * @note   Function is called under interruption only, once
3648   *         interruptions have been enabled by HAL_UART_Transmit_IT().
3649   * @param huart UART handle.
3650   * @retval None
3651   */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)3652 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
3653 {
3654   /* Check that a Tx process is ongoing */
3655   if (huart->gState == HAL_UART_STATE_BUSY_TX)
3656   {
3657     if (huart->TxXferCount == 0U)
3658     {
3659       /* Disable the UART Transmit Data Register Empty Interrupt */
3660       CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3661 
3662       /* Enable the UART Transmit Complete Interrupt */
3663       SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3664     }
3665     else
3666     {
3667       huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
3668       huart->pTxBuffPtr++;
3669       huart->TxXferCount--;
3670     }
3671   }
3672 }
3673 
3674 /**
3675   * @brief TX interrrupt handler for 9 bits data word length.
3676   * @note   Function is called under interruption only, once
3677   *         interruptions have been enabled by HAL_UART_Transmit_IT().
3678   * @param huart UART handle.
3679   * @retval None
3680   */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)3681 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
3682 {
3683   uint16_t *tmp;
3684 
3685   /* Check that a Tx process is ongoing */
3686   if (huart->gState == HAL_UART_STATE_BUSY_TX)
3687   {
3688     if (huart->TxXferCount == 0U)
3689     {
3690       /* Disable the UART Transmit Data Register Empty Interrupt */
3691       CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3692 
3693       /* Enable the UART Transmit Complete Interrupt */
3694       SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3695     }
3696     else
3697     {
3698       tmp = (uint16_t *) huart->pTxBuffPtr;
3699       huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
3700       huart->pTxBuffPtr += 2U;
3701       huart->TxXferCount--;
3702     }
3703   }
3704 }
3705 
3706 /**
3707   * @brief TX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
3708   * @note   Function is called under interruption only, once
3709   *         interruptions have been enabled by HAL_UART_Transmit_IT().
3710   * @param huart UART handle.
3711   * @retval None
3712   */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)3713 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3714 {
3715   uint16_t  nb_tx_data;
3716 
3717   /* Check that a Tx process is ongoing */
3718   if (huart->gState == HAL_UART_STATE_BUSY_TX)
3719   {
3720     for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3721     {
3722       if (huart->TxXferCount == 0U)
3723       {
3724         /* Disable the TX FIFO threshold interrupt */
3725         CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3726 
3727         /* Enable the UART Transmit Complete Interrupt */
3728         SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3729 
3730         break; /* force exit loop */
3731       }
3732       else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
3733       {
3734         huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
3735         huart->pTxBuffPtr++;
3736         huart->TxXferCount--;
3737       }
3738       else
3739       {
3740         /* Nothing to do */
3741       }
3742     }
3743   }
3744 }
3745 
3746 /**
3747   * @brief TX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
3748   * @note   Function is called under interruption only, once
3749   *         interruptions have been enabled by HAL_UART_Transmit_IT().
3750   * @param huart UART handle.
3751   * @retval None
3752   */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)3753 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
3754 {
3755   uint16_t *tmp;
3756   uint16_t  nb_tx_data;
3757 
3758   /* Check that a Tx process is ongoing */
3759   if (huart->gState == HAL_UART_STATE_BUSY_TX)
3760   {
3761     for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3762     {
3763       if (huart->TxXferCount == 0U)
3764       {
3765         /* Disable the TX FIFO threshold interrupt */
3766         CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3767 
3768         /* Enable the UART Transmit Complete Interrupt */
3769         SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3770 
3771         break; /* force exit loop */
3772       }
3773       else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
3774       {
3775         tmp = (uint16_t *) huart->pTxBuffPtr;
3776         huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
3777         huart->pTxBuffPtr += 2U;
3778         huart->TxXferCount--;
3779       }
3780       else
3781       {
3782         /* Nothing to do */
3783       }
3784     }
3785   }
3786 }
3787 
3788 /**
3789   * @brief  Wrap up transmission in non-blocking mode.
3790   * @param  huart pointer to a UART_HandleTypeDef structure that contains
3791   *                the configuration information for the specified UART module.
3792   * @retval None
3793   */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)3794 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
3795 {
3796   /* Disable the UART Transmit Complete Interrupt */
3797   CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3798 
3799   /* Tx process is ended, restore huart->gState to Ready */
3800   huart->gState = HAL_UART_STATE_READY;
3801 
3802   /* Cleat TxISR function pointer */
3803   huart->TxISR = NULL;
3804 
3805 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3806   /*Call registered Tx complete callback*/
3807   huart->TxCpltCallback(huart);
3808 #else
3809   /*Call legacy weak Tx complete callback*/
3810   HAL_UART_TxCpltCallback(huart);
3811 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3812 }
3813 
3814 /**
3815   * @brief RX interrrupt handler for 7 or 8 bits data word length .
3816   * @param huart UART handle.
3817   * @retval None
3818   */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)3819 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
3820 {
3821   uint16_t uhMask = huart->Mask;
3822   uint16_t  uhdata;
3823 
3824   /* Check that a Rx process is ongoing */
3825   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3826   {
3827     uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3828     *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
3829     huart->pRxBuffPtr++;
3830     huart->RxXferCount--;
3831 
3832     if (huart->RxXferCount == 0U)
3833     {
3834       /* Disable the UART Parity Error Interrupt and RXNE interrupts */
3835       CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3836 
3837       /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3838       CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3839 
3840       /* Rx process is completed, restore huart->RxState to Ready */
3841       huart->RxState = HAL_UART_STATE_READY;
3842 
3843       /* Clear RxISR function pointer */
3844       huart->RxISR = NULL;
3845 
3846 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3847       /*Call registered Rx complete callback*/
3848       huart->RxCpltCallback(huart);
3849 #else
3850       /*Call legacy weak Rx complete callback*/
3851       HAL_UART_RxCpltCallback(huart);
3852 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3853     }
3854   }
3855   else
3856   {
3857     /* Clear RXNE interrupt flag */
3858     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3859   }
3860 }
3861 
3862 /**
3863   * @brief RX interrrupt handler for 9 bits data word length .
3864   * @note   Function is called under interruption only, once
3865   *         interruptions have been enabled by HAL_UART_Receive_IT()
3866   * @param huart UART handle.
3867   * @retval None
3868   */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)3869 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
3870 {
3871   uint16_t *tmp;
3872   uint16_t uhMask = huart->Mask;
3873   uint16_t  uhdata;
3874 
3875   /* Check that a Rx process is ongoing */
3876   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3877   {
3878     uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3879     tmp = (uint16_t *) huart->pRxBuffPtr ;
3880     *tmp = (uint16_t)(uhdata & uhMask);
3881     huart->pRxBuffPtr += 2U;
3882     huart->RxXferCount--;
3883 
3884     if (huart->RxXferCount == 0U)
3885     {
3886       /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
3887       CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3888 
3889       /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3890       CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3891 
3892       /* Rx process is completed, restore huart->RxState to Ready */
3893       huart->RxState = HAL_UART_STATE_READY;
3894 
3895       /* Clear RxISR function pointer */
3896       huart->RxISR = NULL;
3897 
3898 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3899       /*Call registered Rx complete callback*/
3900       huart->RxCpltCallback(huart);
3901 #else
3902       /*Call legacy weak Rx complete callback*/
3903       HAL_UART_RxCpltCallback(huart);
3904 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3905     }
3906   }
3907   else
3908   {
3909     /* Clear RXNE interrupt flag */
3910     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3911   }
3912 }
3913 
3914 /**
3915   * @brief RX interrrupt handler for 7 or 8  bits data word length and FIFO mode is enabled.
3916   * @note   Function is called under interruption only, once
3917   *         interruptions have been enabled by HAL_UART_Receive_IT()
3918   * @param huart UART handle.
3919   * @retval None
3920   */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)3921 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3922 {
3923   uint16_t  uhMask = huart->Mask;
3924   uint16_t  uhdata;
3925   uint16_t   nb_rx_data;
3926   uint16_t  rxdatacount;
3927 
3928   /* Check that a Rx process is ongoing */
3929   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3930   {
3931     for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3932     {
3933       uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3934       *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
3935       huart->pRxBuffPtr++;
3936       huart->RxXferCount--;
3937 
3938       if (huart->RxXferCount == 0U)
3939       {
3940         /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
3941         CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3942 
3943         /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3944         CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3945 
3946         /* Rx process is completed, restore huart->RxState to Ready */
3947         huart->RxState = HAL_UART_STATE_READY;
3948 
3949         /* Clear RxISR function pointer */
3950         huart->RxISR = NULL;
3951 
3952 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3953         /*Call registered Rx complete callback*/
3954         huart->RxCpltCallback(huart);
3955 #else
3956         /*Call legacy weak Rx complete callback*/
3957         HAL_UART_RxCpltCallback(huart);
3958 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3959       }
3960     }
3961 
3962     /* When remaining number of bytes to receive is less than the RX FIFO
3963     threshold, next incoming frames are processed as if FIFO mode was
3964     disabled (i.e. one interrupt per received frame).
3965     */
3966     rxdatacount = huart->RxXferCount;
3967     if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
3968     {
3969       /* Disable the UART RXFT interrupt*/
3970       CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3971 
3972       /* Update the RxISR function pointer */
3973       huart->RxISR = UART_RxISR_8BIT;
3974 
3975       /* Enable the UART Data Register Not Empty interrupt */
3976       SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3977     }
3978   }
3979   else
3980   {
3981     /* Clear RXNE interrupt flag */
3982     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3983   }
3984 }
3985 
3986 /**
3987   * @brief RX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
3988   * @note   Function is called under interruption only, once
3989   *         interruptions have been enabled by HAL_UART_Receive_IT()
3990   * @param huart UART handle.
3991   * @retval None
3992   */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)3993 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
3994 {
3995   uint16_t *tmp;
3996   uint16_t  uhMask = huart->Mask;
3997   uint16_t  uhdata;
3998   uint16_t   nb_rx_data;
3999   uint16_t  rxdatacount;
4000 
4001   /* Check that a Rx process is ongoing */
4002   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4003   {
4004     for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
4005     {
4006       uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4007       tmp = (uint16_t *) huart->pRxBuffPtr ;
4008       *tmp = (uint16_t)(uhdata & uhMask);
4009       huart->pRxBuffPtr += 2U;
4010       huart->RxXferCount--;
4011 
4012       if (huart->RxXferCount == 0U)
4013       {
4014         /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4015         CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4016 
4017         /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
4018         CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4019 
4020         /* Rx process is completed, restore huart->RxState to Ready */
4021         huart->RxState = HAL_UART_STATE_READY;
4022 
4023         /* Clear RxISR function pointer */
4024         huart->RxISR = NULL;
4025 
4026 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4027         /*Call registered Rx complete callback*/
4028         huart->RxCpltCallback(huart);
4029 #else
4030         /*Call legacy weak Rx complete callback*/
4031         HAL_UART_RxCpltCallback(huart);
4032 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4033       }
4034     }
4035 
4036     /* When remaining number of bytes to receive is less than the RX FIFO
4037     threshold, next incoming frames are processed as if FIFO mode was
4038     disabled (i.e. one interrupt per received frame).
4039     */
4040     rxdatacount = huart->RxXferCount;
4041     if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4042     {
4043       /* Disable the UART RXFT interrupt*/
4044       CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4045 
4046       /* Update the RxISR function pointer */
4047       huart->RxISR = UART_RxISR_16BIT;
4048 
4049       /* Enable the UART Data Register Not Empty interrupt */
4050       SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4051     }
4052   }
4053   else
4054   {
4055     /* Clear RXNE interrupt flag */
4056     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4057   }
4058 }
4059 
4060 /**
4061   * @}
4062   */
4063 
4064 #endif /* HAL_UART_MODULE_ENABLED */
4065 /**
4066   * @}
4067   */
4068 
4069 /**
4070   * @}
4071   */
4072 
4073 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
4074