tdse-tp0_02-hw_sw_test

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