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