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