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