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