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