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