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