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