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