Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_irda.c
0004   * @author  MCD Application Team
0005   * @brief   IRDA HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the IrDA (Infrared Data Association) Peripheral
0008   *          (IRDA)
0009   *           + Initialization and de-initialization functions
0010   *           + IO operation functions
0011   *           + Peripheral State and Errors functions
0012   *           + Peripheral Control functions
0013   *
0014   ******************************************************************************
0015   * @attention
0016   *
0017   * Copyright (c) 2017 STMicroelectronics.
0018   * All rights reserved.
0019   *
0020   * This software is licensed under terms that can be found in the LICENSE file
0021   * in the root directory of this software component.
0022   * If no LICENSE file comes with this software, it is provided AS-IS.
0023   *
0024   ******************************************************************************
0025   @verbatim
0026   ==============================================================================
0027                         ##### How to use this driver #####
0028   ==============================================================================
0029   [..]
0030     The IRDA HAL driver can be used as follows:
0031 
0032     (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda).
0033     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API
0034         in setting the associated USART or UART in IRDA mode:
0035         (++) Enable the USARTx/UARTx interface clock.
0036         (++) USARTx/UARTx pins configuration:
0037             (+++) Enable the clock for the USARTx/UARTx GPIOs.
0038             (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input).
0039         (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
0040              and HAL_IRDA_Receive_IT() APIs):
0041             (+++) Configure the USARTx/UARTx interrupt priority.
0042             (+++) Enable the NVIC USARTx/UARTx IRQ handle.
0043             (+++) The specific IRDA interrupts (Transmission complete interrupt,
0044                   RXNE interrupt and Error Interrupts) will be managed using the macros
0045                   __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
0046 
0047         (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
0048              and HAL_IRDA_Receive_DMA() APIs):
0049             (+++) Declare a DMA handle structure for the Tx/Rx channel.
0050             (+++) Enable the DMAx interface clock.
0051             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
0052             (+++) Configure the DMA Tx/Rx channel.
0053             (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
0054             (+++) Configure the priority and enable the NVIC for the transfer
0055                   complete interrupt on the DMA Tx/Rx channel.
0056 
0057     (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
0058         the normal or low power mode and the clock prescaler in the hirda handle Init structure.
0059 
0060     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
0061         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
0062              by calling the customized HAL_IRDA_MspInit() API.
0063 
0064          -@@- The specific IRDA interrupts (Transmission complete interrupt,
0065              RXNE interrupt and Error Interrupts) will be managed using the macros
0066              __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
0067 
0068     (#) Three operation modes are available within this driver :
0069 
0070      *** Polling mode IO operation ***
0071      =================================
0072      [..]
0073        (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
0074        (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
0075 
0076      *** Interrupt mode IO operation ***
0077      ===================================
0078      [..]
0079        (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT()
0080        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
0081             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
0082        (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT()
0083        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
0084             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
0085        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
0086             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
0087 
0088      *** DMA mode IO operation ***
0089      ==============================
0090      [..]
0091        (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
0092        (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can
0093             add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback()
0094        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
0095             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
0096        (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA()
0097        (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can
0098             add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback()
0099        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
0100             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
0101        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
0102             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
0103 
0104      *** IRDA HAL driver macros list ***
0105      ====================================
0106      [..]
0107        Below the list of most used macros in IRDA HAL driver.
0108 
0109        (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
0110        (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
0111        (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
0112        (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
0113        (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
0114        (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
0115        (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled
0116 
0117      [..]
0118        (@) You can refer to the IRDA HAL driver header file for more useful macros
0119 
0120     ##### Callback registration #####
0121     ==================================
0122 
0123     [..]
0124     The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1
0125     allows the user to configure dynamically the driver callbacks.
0126 
0127     [..]
0128     Use Function HAL_IRDA_RegisterCallback() to register a user callback.
0129     Function HAL_IRDA_RegisterCallback() allows to register following callbacks:
0130     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
0131     (+) TxCpltCallback            : Tx Complete Callback.
0132     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
0133     (+) RxCpltCallback            : Rx Complete Callback.
0134     (+) ErrorCallback             : Error Callback.
0135     (+) AbortCpltCallback         : Abort Complete Callback.
0136     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
0137     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
0138     (+) MspInitCallback           : IRDA MspInit.
0139     (+) MspDeInitCallback         : IRDA MspDeInit.
0140     This function takes as parameters the HAL peripheral handle, the Callback ID
0141     and a pointer to the user callback function.
0142 
0143     [..]
0144     Use function HAL_IRDA_UnRegisterCallback() to reset a callback to the default
0145     weak function.
0146     HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle,
0147     and the Callback ID.
0148     This function allows to reset following callbacks:
0149     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
0150     (+) TxCpltCallback            : Tx Complete Callback.
0151     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
0152     (+) RxCpltCallback            : Rx Complete Callback.
0153     (+) ErrorCallback             : Error Callback.
0154     (+) AbortCpltCallback         : Abort Complete Callback.
0155     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
0156     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
0157     (+) MspInitCallback           : IRDA MspInit.
0158     (+) MspDeInitCallback         : IRDA MspDeInit.
0159 
0160     [..]
0161     By default, after the HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET
0162     all callbacks are set to the corresponding weak functions:
0163     examples HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxHalfCpltCallback().
0164     Exception done for MspInit and MspDeInit functions that are respectively
0165     reset to the legacy weak functions in the HAL_IRDA_Init()
0166     and HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand).
0167     If not, MspInit or MspDeInit are not null, the HAL_IRDA_Init() and HAL_IRDA_DeInit()
0168     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
0169 
0170     [..]
0171     Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only.
0172     Exception done MspInit/MspDeInit that can be registered/unregistered
0173     in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user)
0174     MspInit/DeInit callbacks can be used during the Init/DeInit.
0175     In that case first register the MspInit/MspDeInit user callbacks
0176     using HAL_IRDA_RegisterCallback() before calling HAL_IRDA_DeInit()
0177     or HAL_IRDA_Init() function.
0178 
0179     [..]
0180     When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or
0181     not defined, the callback registration feature is not available
0182     and weak callbacks are used.
0183 
0184   @endverbatim
0185   ******************************************************************************
0186   */
0187 
0188 /* Includes ------------------------------------------------------------------*/
0189 #include "stm32h7xx_hal.h"
0190 
0191 /** @addtogroup STM32H7xx_HAL_Driver
0192   * @{
0193   */
0194 
0195 /** @defgroup IRDA IRDA
0196   * @ingroup RTEMSBSPsARMSTM32H7
0197   * @brief HAL IRDA module driver
0198   * @{
0199   */
0200 
0201 #ifdef HAL_IRDA_MODULE_ENABLED
0202 
0203 /* Private typedef -----------------------------------------------------------*/
0204 /* Private define ------------------------------------------------------------*/
0205 /** @defgroup IRDA_Private_Constants IRDA Private Constants
0206   * @ingroup RTEMSBSPsARMSTM32H7
0207   * @{
0208   */
0209 #define IRDA_TEACK_REACK_TIMEOUT            1000U                                   /*!< IRDA TX or RX enable acknowledge time-out value  */
0210 
0211 #define IRDA_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
0212                                      | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))  /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */
0213 
0214 #define USART_BRR_MIN    0x10U        /*!< USART BRR minimum authorized value */
0215 
0216 #define USART_BRR_MAX    0x0000FFFFU  /*!< USART BRR maximum authorized value */
0217 /**
0218   * @}
0219   */
0220 
0221 /* Private macros ------------------------------------------------------------*/
0222 /** @defgroup IRDA_Private_Macros IRDA Private Macros
0223   * @ingroup RTEMSBSPsARMSTM32H7
0224   * @{
0225   */
0226 /** @brief  BRR division operation to set BRR register in 16-bit oversampling mode.
0227   * @param  __PCLK__ IRDA clock source.
0228   * @param  __BAUD__ Baud rate set by the user.
0229   * @param  __PRESCALER__ IRDA clock prescaler value.
0230   * @retval Division result
0231   */
0232 #define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__, __PRESCALER__)  ((((__PCLK__)/IRDAPrescTable[(__PRESCALER__)])\
0233                                                                   + ((__BAUD__)/2U)) / (__BAUD__))
0234 /**
0235   * @}
0236   */
0237 
0238 /* Private variables ---------------------------------------------------------*/
0239 /* Private function prototypes -----------------------------------------------*/
0240 /** @addtogroup IRDA_Private_Functions
0241   * @{
0242   */
0243 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
0244 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda);
0245 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
0246 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
0247 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
0248 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
0249                                                      uint32_t Tickstart, uint32_t Timeout);
0250 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
0251 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
0252 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
0253 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
0254 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
0255 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
0256 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
0257 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
0258 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
0259 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
0260 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
0261 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
0262 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
0263 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
0264 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
0265 /**
0266   * @}
0267   */
0268 
0269 /* Exported functions --------------------------------------------------------*/
0270 
0271 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions
0272   * @ingroup RTEMSBSPsARMSTM32H7
0273   * @{
0274   */
0275 
0276 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
0277   * @ingroup RTEMSBSPsARMSTM32H7
0278   *  @brief    Initialization and Configuration functions
0279   *
0280 @verbatim
0281   ==============================================================================
0282               ##### Initialization and Configuration functions #####
0283   ==============================================================================
0284   [..]
0285   This subsection provides a set of functions allowing to initialize the USARTx
0286   in asynchronous IRDA mode.
0287   (+) For the asynchronous mode only these parameters can be configured:
0288       (++) Baud Rate
0289       (++) Word Length
0290       (++) Parity: If the parity is enabled, then the MSB bit of the data written
0291            in the data register is transmitted but is changed by the parity bit.
0292       (++) Power mode
0293       (++) Prescaler setting
0294       (++) Receiver/transmitter modes
0295 
0296   [..]
0297   The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
0298   (details for the procedures are available in reference manual).
0299 
0300 @endverbatim
0301 
0302   Depending on the frame length defined by the M1 and M0 bits (7-bit,
0303   8-bit or 9-bit), the possible IRDA frame formats are listed in the
0304   following table.
0305 
0306     Table 1. IRDA frame format.
0307     +-----------------------------------------------------------------------+
0308     |  M1 bit |  M0 bit |  PCE bit  |             IRDA frame                |
0309     |---------|---------|-----------|---------------------------------------|
0310     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
0311     |---------|---------|-----------|---------------------------------------|
0312     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
0313     |---------|---------|-----------|---------------------------------------|
0314     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
0315     |---------|---------|-----------|---------------------------------------|
0316     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
0317     |---------|---------|-----------|---------------------------------------|
0318     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
0319     |---------|---------|-----------|---------------------------------------|
0320     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
0321     +-----------------------------------------------------------------------+
0322 
0323   * @{
0324   */
0325 
0326 /**
0327   * @brief Initialize the IRDA mode according to the specified
0328   *        parameters in the IRDA_InitTypeDef and initialize the associated handle.
0329   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
0330   *               the configuration information for the specified IRDA module.
0331   * @retval HAL status
0332   */
0333 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
0334 {
0335   /* Check the IRDA handle allocation */
0336   if (hirda == NULL)
0337   {
0338     return HAL_ERROR;
0339   }
0340 
0341   /* Check the USART/UART associated to the IRDA handle */
0342   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
0343 
0344   if (hirda->gState == HAL_IRDA_STATE_RESET)
0345   {
0346     /* Allocate lock resource and initialize it */
0347     hirda->Lock = HAL_UNLOCKED;
0348 
0349 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
0350     IRDA_InitCallbacksToDefault(hirda);
0351 
0352     if (hirda->MspInitCallback == NULL)
0353     {
0354       hirda->MspInitCallback = HAL_IRDA_MspInit;
0355     }
0356 
0357     /* Init the low level hardware */
0358     hirda->MspInitCallback(hirda);
0359 #else
0360     /* Init the low level hardware : GPIO, CLOCK */
0361     HAL_IRDA_MspInit(hirda);
0362 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
0363   }
0364 
0365   hirda->gState = HAL_IRDA_STATE_BUSY;
0366 
0367   /* Disable the Peripheral to update the configuration registers */
0368   __HAL_IRDA_DISABLE(hirda);
0369 
0370   /* Set the IRDA Communication parameters */
0371   if (IRDA_SetConfig(hirda) == HAL_ERROR)
0372   {
0373     return HAL_ERROR;
0374   }
0375 
0376   /* In IRDA mode, the following bits must be kept cleared:
0377   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
0378   - SCEN and HDSEL bits in the USART_CR3 register.*/
0379   CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
0380   CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
0381 
0382   /* set the UART/USART in IRDA mode */
0383   hirda->Instance->CR3 |= USART_CR3_IREN;
0384 
0385   /* Enable the Peripheral */
0386   __HAL_IRDA_ENABLE(hirda);
0387 
0388   /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */
0389   return (IRDA_CheckIdleState(hirda));
0390 }
0391 
0392 /**
0393   * @brief DeInitialize the IRDA peripheral.
0394   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
0395   *               the configuration information for the specified IRDA module.
0396   * @retval HAL status
0397   */
0398 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
0399 {
0400   /* Check the IRDA handle allocation */
0401   if (hirda == NULL)
0402   {
0403     return HAL_ERROR;
0404   }
0405 
0406   /* Check the USART/UART associated to the IRDA handle */
0407   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
0408 
0409   hirda->gState = HAL_IRDA_STATE_BUSY;
0410 
0411   /* DeInit the low level hardware */
0412 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
0413   if (hirda->MspDeInitCallback == NULL)
0414   {
0415     hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
0416   }
0417   /* DeInit the low level hardware */
0418   hirda->MspDeInitCallback(hirda);
0419 #else
0420   HAL_IRDA_MspDeInit(hirda);
0421 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
0422   /* Disable the Peripheral */
0423   __HAL_IRDA_DISABLE(hirda);
0424 
0425   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
0426   hirda->gState    = HAL_IRDA_STATE_RESET;
0427   hirda->RxState   = HAL_IRDA_STATE_RESET;
0428 
0429   /* Process Unlock */
0430   __HAL_UNLOCK(hirda);
0431 
0432   return HAL_OK;
0433 }
0434 
0435 /**
0436   * @brief Initialize the IRDA MSP.
0437   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
0438   *               the configuration information for the specified IRDA module.
0439   * @retval None
0440   */
0441 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
0442 {
0443   /* Prevent unused argument(s) compilation warning */
0444   UNUSED(hirda);
0445 
0446   /* NOTE: This function should not be modified, when the callback is needed,
0447            the HAL_IRDA_MspInit can be implemented in the user file
0448    */
0449 }
0450 
0451 /**
0452   * @brief DeInitialize the IRDA MSP.
0453   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
0454   *               the configuration information for the specified IRDA module.
0455   * @retval None
0456   */
0457 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
0458 {
0459   /* Prevent unused argument(s) compilation warning */
0460   UNUSED(hirda);
0461 
0462   /* NOTE: This function should not be modified, when the callback is needed,
0463            the HAL_IRDA_MspDeInit can be implemented in the user file
0464    */
0465 }
0466 
0467 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
0468 /**
0469   * @brief  Register a User IRDA Callback
0470   *         To be used to override the weak predefined callback
0471   * @note   The HAL_IRDA_RegisterCallback() may be called before HAL_IRDA_Init() in HAL_IRDA_STATE_RESET
0472   *         to register callbacks for HAL_IRDA_MSPINIT_CB_ID and HAL_IRDA_MSPDEINIT_CB_ID
0473   * @param  hirda irda handle
0474   * @param  CallbackID ID of the callback to be registered
0475   *         This parameter can be one of the following values:
0476   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
0477   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
0478   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
0479   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
0480   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
0481   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
0482   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
0483   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
0484   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
0485   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
0486   * @param  pCallback pointer to the Callback function
0487   * @retval HAL status
0488   */
0489 HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID,
0490                                             pIRDA_CallbackTypeDef pCallback)
0491 {
0492   HAL_StatusTypeDef status = HAL_OK;
0493 
0494   if (pCallback == NULL)
0495   {
0496     /* Update the error code */
0497     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0498 
0499     return HAL_ERROR;
0500   }
0501 
0502   if (hirda->gState == HAL_IRDA_STATE_READY)
0503   {
0504     switch (CallbackID)
0505     {
0506       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
0507         hirda->TxHalfCpltCallback = pCallback;
0508         break;
0509 
0510       case HAL_IRDA_TX_COMPLETE_CB_ID :
0511         hirda->TxCpltCallback = pCallback;
0512         break;
0513 
0514       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
0515         hirda->RxHalfCpltCallback = pCallback;
0516         break;
0517 
0518       case HAL_IRDA_RX_COMPLETE_CB_ID :
0519         hirda->RxCpltCallback = pCallback;
0520         break;
0521 
0522       case HAL_IRDA_ERROR_CB_ID :
0523         hirda->ErrorCallback = pCallback;
0524         break;
0525 
0526       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
0527         hirda->AbortCpltCallback = pCallback;
0528         break;
0529 
0530       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
0531         hirda->AbortTransmitCpltCallback = pCallback;
0532         break;
0533 
0534       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
0535         hirda->AbortReceiveCpltCallback = pCallback;
0536         break;
0537 
0538       case HAL_IRDA_MSPINIT_CB_ID :
0539         hirda->MspInitCallback = pCallback;
0540         break;
0541 
0542       case HAL_IRDA_MSPDEINIT_CB_ID :
0543         hirda->MspDeInitCallback = pCallback;
0544         break;
0545 
0546       default :
0547         /* Update the error code */
0548         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0549 
0550         /* Return error status */
0551         status =  HAL_ERROR;
0552         break;
0553     }
0554   }
0555   else if (hirda->gState == HAL_IRDA_STATE_RESET)
0556   {
0557     switch (CallbackID)
0558     {
0559       case HAL_IRDA_MSPINIT_CB_ID :
0560         hirda->MspInitCallback = pCallback;
0561         break;
0562 
0563       case HAL_IRDA_MSPDEINIT_CB_ID :
0564         hirda->MspDeInitCallback = pCallback;
0565         break;
0566 
0567       default :
0568         /* Update the error code */
0569         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0570 
0571         /* Return error status */
0572         status =  HAL_ERROR;
0573         break;
0574     }
0575   }
0576   else
0577   {
0578     /* Update the error code */
0579     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0580 
0581     /* Return error status */
0582     status =  HAL_ERROR;
0583   }
0584 
0585   return status;
0586 }
0587 
0588 /**
0589   * @brief  Unregister an IRDA callback
0590   *         IRDA callback is redirected to the weak predefined callback
0591   * @note   The HAL_IRDA_UnRegisterCallback() may be called before HAL_IRDA_Init() in HAL_IRDA_STATE_RESET
0592   *         to un-register callbacks for HAL_IRDA_MSPINIT_CB_ID and HAL_IRDA_MSPDEINIT_CB_ID
0593   * @param  hirda irda handle
0594   * @param  CallbackID ID of the callback to be unregistered
0595   *         This parameter can be one of the following values:
0596   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
0597   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
0598   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
0599   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
0600   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
0601   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
0602   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
0603   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
0604   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
0605   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
0606   * @retval HAL status
0607   */
0608 HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID)
0609 {
0610   HAL_StatusTypeDef status = HAL_OK;
0611 
0612   if (HAL_IRDA_STATE_READY == hirda->gState)
0613   {
0614     switch (CallbackID)
0615     {
0616       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
0617         hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback    */
0618         break;
0619 
0620       case HAL_IRDA_TX_COMPLETE_CB_ID :
0621         hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback;                       /* Legacy weak TxCpltCallback         */
0622         break;
0623 
0624       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
0625         hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback     */
0626         break;
0627 
0628       case HAL_IRDA_RX_COMPLETE_CB_ID :
0629         hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback;                       /* Legacy weak RxCpltCallback         */
0630         break;
0631 
0632       case HAL_IRDA_ERROR_CB_ID :
0633         hirda->ErrorCallback = HAL_IRDA_ErrorCallback;                         /* Legacy weak ErrorCallback          */
0634         break;
0635 
0636       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
0637         hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback      */
0638         break;
0639 
0640       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
0641         hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak
0642                                                                                   AbortTransmitCpltCallback          */
0643         break;
0644 
0645       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
0646         hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback;   /* Legacy weak
0647                                                                                   AbortReceiveCpltCallback           */
0648         break;
0649 
0650       case HAL_IRDA_MSPINIT_CB_ID :
0651         hirda->MspInitCallback = HAL_IRDA_MspInit;                             /* Legacy weak MspInitCallback        */
0652         break;
0653 
0654       case HAL_IRDA_MSPDEINIT_CB_ID :
0655         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;                         /* Legacy weak MspDeInitCallback      */
0656         break;
0657 
0658       default :
0659         /* Update the error code */
0660         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0661 
0662         /* Return error status */
0663         status =  HAL_ERROR;
0664         break;
0665     }
0666   }
0667   else if (HAL_IRDA_STATE_RESET == hirda->gState)
0668   {
0669     switch (CallbackID)
0670     {
0671       case HAL_IRDA_MSPINIT_CB_ID :
0672         hirda->MspInitCallback = HAL_IRDA_MspInit;
0673         break;
0674 
0675       case HAL_IRDA_MSPDEINIT_CB_ID :
0676         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
0677         break;
0678 
0679       default :
0680         /* Update the error code */
0681         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0682 
0683         /* Return error status */
0684         status =  HAL_ERROR;
0685         break;
0686     }
0687   }
0688   else
0689   {
0690     /* Update the error code */
0691     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
0692 
0693     /* Return error status */
0694     status =  HAL_ERROR;
0695   }
0696 
0697   return status;
0698 }
0699 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
0700 
0701 /**
0702   * @}
0703   */
0704 
0705 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
0706   * @ingroup RTEMSBSPsARMSTM32H7
0707   *  @brief   IRDA Transmit and Receive functions
0708   *
0709 @verbatim
0710  ===============================================================================
0711                          ##### IO operation functions #####
0712  ===============================================================================
0713   [..]
0714     This subsection provides a set of functions allowing to manage the IRDA data transfers.
0715 
0716   [..]
0717     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
0718     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
0719     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
0720     While receiving data, transmission should be avoided as the data to be transmitted
0721     could be corrupted.
0722 
0723   [..]
0724     (#) There are two modes of transfer:
0725         (++) Blocking mode: the communication is performed in polling mode.
0726              The HAL status of all data processing is returned by the same function
0727              after finishing transfer.
0728         (++) Non-Blocking mode: the communication is performed using Interrupts
0729              or DMA, these API's return the HAL status.
0730              The end of the data processing will be indicated through the
0731              dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
0732              using DMA mode.
0733              The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
0734              will be executed respectively at the end of the Transmit or Receive process
0735              The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
0736 
0737     (#) Blocking mode APIs are :
0738         (++) HAL_IRDA_Transmit()
0739         (++) HAL_IRDA_Receive()
0740 
0741     (#) Non Blocking mode APIs with Interrupt are :
0742         (++) HAL_IRDA_Transmit_IT()
0743         (++) HAL_IRDA_Receive_IT()
0744         (++) HAL_IRDA_IRQHandler()
0745 
0746     (#) Non Blocking mode functions with DMA are :
0747         (++) HAL_IRDA_Transmit_DMA()
0748         (++) HAL_IRDA_Receive_DMA()
0749         (++) HAL_IRDA_DMAPause()
0750         (++) HAL_IRDA_DMAResume()
0751         (++) HAL_IRDA_DMAStop()
0752 
0753     (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
0754         (++) HAL_IRDA_TxHalfCpltCallback()
0755         (++) HAL_IRDA_TxCpltCallback()
0756         (++) HAL_IRDA_RxHalfCpltCallback()
0757         (++) HAL_IRDA_RxCpltCallback()
0758         (++) HAL_IRDA_ErrorCallback()
0759 
0760     (#) Non-Blocking mode transfers could be aborted using Abort API's :
0761         (++) HAL_IRDA_Abort()
0762         (++) HAL_IRDA_AbortTransmit()
0763         (++) HAL_IRDA_AbortReceive()
0764         (++) HAL_IRDA_Abort_IT()
0765         (++) HAL_IRDA_AbortTransmit_IT()
0766         (++) HAL_IRDA_AbortReceive_IT()
0767 
0768     (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
0769         (++) HAL_IRDA_AbortCpltCallback()
0770         (++) HAL_IRDA_AbortTransmitCpltCallback()
0771         (++) HAL_IRDA_AbortReceiveCpltCallback()
0772 
0773     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
0774         Errors are handled as follows :
0775         (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
0776              to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
0777              in Interrupt mode reception .
0778              Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
0779              to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed.
0780              Transfer is kept ongoing on IRDA side.
0781              If user wants to abort it, Abort services should be called by user.
0782         (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
0783              This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
0784              Error code is set to allow user to identify error type, and
0785              HAL_IRDA_ErrorCallback() user callback is executed.
0786 
0787 @endverbatim
0788   * @{
0789   */
0790 
0791 /**
0792   * @brief Send an amount of data in blocking mode.
0793   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
0794   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
0795   *        of u16 available through pData.
0796   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
0797   *               the configuration information for the specified IRDA module.
0798   * @param pData Pointer to data buffer (u8 or u16 data elements).
0799   * @param Size Amount of data elements (u8 or u16) to be sent.
0800   * @param Timeout Specify timeout value.
0801   * @retval HAL status
0802   */
0803 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
0804 {
0805   const uint8_t  *pdata8bits;
0806   const uint16_t *pdata16bits;
0807   uint32_t tickstart;
0808 
0809   /* Check that a Tx process is not already ongoing */
0810   if (hirda->gState == HAL_IRDA_STATE_READY)
0811   {
0812     if ((pData == NULL) || (Size == 0U))
0813     {
0814       return  HAL_ERROR;
0815     }
0816 
0817     /* Process Locked */
0818     __HAL_LOCK(hirda);
0819 
0820     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
0821     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
0822 
0823     /* Init tickstart for timeout management */
0824     tickstart = HAL_GetTick();
0825 
0826     hirda->TxXferSize = Size;
0827     hirda->TxXferCount = Size;
0828 
0829     /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
0830     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
0831     {
0832       pdata8bits  = NULL;
0833       pdata16bits = (const uint16_t *) pData; /* Derogation R.11.3 */
0834     }
0835     else
0836     {
0837       pdata8bits  = pData;
0838       pdata16bits = NULL;
0839     }
0840 
0841     while (hirda->TxXferCount > 0U)
0842     {
0843       hirda->TxXferCount--;
0844 
0845       if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
0846       {
0847         return HAL_TIMEOUT;
0848       }
0849       if (pdata8bits == NULL)
0850       {
0851         hirda->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
0852         pdata16bits++;
0853       }
0854       else
0855       {
0856         hirda->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
0857         pdata8bits++;
0858       }
0859     }
0860 
0861     if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
0862     {
0863       return HAL_TIMEOUT;
0864     }
0865 
0866     /* At end of Tx process, restore hirda->gState to Ready */
0867     hirda->gState = HAL_IRDA_STATE_READY;
0868 
0869     /* Process Unlocked */
0870     __HAL_UNLOCK(hirda);
0871 
0872     return HAL_OK;
0873   }
0874   else
0875   {
0876     return HAL_BUSY;
0877   }
0878 }
0879 
0880 /**
0881   * @brief Receive an amount of data in blocking mode.
0882   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
0883   *        the received data is handled as a set of u16. In this case, Size must reflect the number
0884   *        of u16 available through pData.
0885   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
0886   *                the configuration information for the specified IRDA module.
0887   * @param pData Pointer to data buffer (u8 or u16 data elements).
0888   * @param Size Amount of data elements (u8 or u16) to be received.
0889   * @param Timeout Specify timeout value.
0890   * @retval HAL status
0891   */
0892 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
0893 {
0894   uint8_t  *pdata8bits;
0895   uint16_t *pdata16bits;
0896   uint16_t uhMask;
0897   uint32_t tickstart;
0898 
0899   /* Check that a Rx process is not already ongoing */
0900   if (hirda->RxState == HAL_IRDA_STATE_READY)
0901   {
0902     if ((pData == NULL) || (Size == 0U))
0903     {
0904       return  HAL_ERROR;
0905     }
0906 
0907     /* Process Locked */
0908     __HAL_LOCK(hirda);
0909 
0910     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
0911     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
0912 
0913     /* Init tickstart for timeout management */
0914     tickstart = HAL_GetTick();
0915 
0916     hirda->RxXferSize = Size;
0917     hirda->RxXferCount = Size;
0918 
0919     /* Computation of the mask to apply to RDR register
0920        of the UART associated to the IRDA */
0921     IRDA_MASK_COMPUTATION(hirda);
0922     uhMask = hirda->Mask;
0923 
0924     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
0925     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
0926     {
0927       pdata8bits  = NULL;
0928       pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */
0929     }
0930     else
0931     {
0932       pdata8bits  = pData;
0933       pdata16bits = NULL;
0934     }
0935 
0936     /* Check data remaining to be received */
0937     while (hirda->RxXferCount > 0U)
0938     {
0939       hirda->RxXferCount--;
0940 
0941       if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
0942       {
0943         return HAL_TIMEOUT;
0944       }
0945       if (pdata8bits == NULL)
0946       {
0947         *pdata16bits = (uint16_t)(hirda->Instance->RDR & uhMask);
0948         pdata16bits++;
0949       }
0950       else
0951       {
0952         *pdata8bits = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
0953         pdata8bits++;
0954       }
0955     }
0956 
0957     /* At end of Rx process, restore hirda->RxState to Ready */
0958     hirda->RxState = HAL_IRDA_STATE_READY;
0959 
0960     /* Process Unlocked */
0961     __HAL_UNLOCK(hirda);
0962 
0963     return HAL_OK;
0964   }
0965   else
0966   {
0967     return HAL_BUSY;
0968   }
0969 }
0970 
0971 /**
0972   * @brief Send an amount of data in interrupt mode.
0973   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
0974   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
0975   *        of u16 available through pData.
0976   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
0977   *                the configuration information for the specified IRDA module.
0978   * @param pData Pointer to data buffer (u8 or u16 data elements).
0979   * @param Size Amount of data elements (u8 or u16) to be sent.
0980   * @retval HAL status
0981   */
0982 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
0983 {
0984   /* Check that a Tx process is not already ongoing */
0985   if (hirda->gState == HAL_IRDA_STATE_READY)
0986   {
0987     if ((pData == NULL) || (Size == 0U))
0988     {
0989       return HAL_ERROR;
0990     }
0991 
0992     /* Process Locked */
0993     __HAL_LOCK(hirda);
0994 
0995     hirda->pTxBuffPtr = pData;
0996     hirda->TxXferSize = Size;
0997     hirda->TxXferCount = Size;
0998 
0999     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1000     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1001 
1002     /* Process Unlocked */
1003     __HAL_UNLOCK(hirda);
1004 
1005     /* Enable the IRDA Transmit Data Register Empty Interrupt */
1006     SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1007 
1008     return HAL_OK;
1009   }
1010   else
1011   {
1012     return HAL_BUSY;
1013   }
1014 }
1015 
1016 /**
1017   * @brief Receive an amount of data in interrupt mode.
1018   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1019   *        the received data is handled as a set of u16. In this case, Size must reflect the number
1020   *        of u16 available through pData.
1021   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1022   *                the configuration information for the specified IRDA module.
1023   * @param pData Pointer to data buffer (u8 or u16 data elements).
1024   * @param Size Amount of data elements (u8 or u16) to be received.
1025   * @retval HAL status
1026   */
1027 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1028 {
1029   /* Check that a Rx process is not already ongoing */
1030   if (hirda->RxState == HAL_IRDA_STATE_READY)
1031   {
1032     if ((pData == NULL) || (Size == 0U))
1033     {
1034       return HAL_ERROR;
1035     }
1036 
1037     /* Process Locked */
1038     __HAL_LOCK(hirda);
1039 
1040     hirda->pRxBuffPtr = pData;
1041     hirda->RxXferSize = Size;
1042     hirda->RxXferCount = Size;
1043 
1044     /* Computation of the mask to apply to the RDR register
1045        of the UART associated to the IRDA */
1046     IRDA_MASK_COMPUTATION(hirda);
1047 
1048     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1049     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1050 
1051     /* Process Unlocked */
1052     __HAL_UNLOCK(hirda);
1053 
1054     if (hirda->Init.Parity != IRDA_PARITY_NONE)
1055     {
1056       /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
1057       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1058     }
1059     else
1060     {
1061       /* Enable the IRDA Data Register not empty Interrupts */
1062       SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1063     }
1064 
1065     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1066     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1067 
1068     return HAL_OK;
1069   }
1070   else
1071   {
1072     return HAL_BUSY;
1073   }
1074 }
1075 
1076 /**
1077   * @brief Send an amount of data in DMA mode.
1078   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1079   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
1080   *        of u16 available through pData.
1081   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1082   *               the configuration information for the specified IRDA module.
1083   * @param pData pointer to data buffer (u8 or u16 data elements).
1084   * @param Size Amount of data elements (u8 or u16) to be sent.
1085   * @retval HAL status
1086   */
1087 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
1088 {
1089   /* Check that a Tx process is not already ongoing */
1090   if (hirda->gState == HAL_IRDA_STATE_READY)
1091   {
1092     if ((pData == NULL) || (Size == 0U))
1093     {
1094       return HAL_ERROR;
1095     }
1096 
1097     /* Process Locked */
1098     __HAL_LOCK(hirda);
1099 
1100     hirda->pTxBuffPtr = pData;
1101     hirda->TxXferSize = Size;
1102     hirda->TxXferCount = Size;
1103 
1104     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1105     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1106 
1107     /* Set the IRDA DMA transfer complete callback */
1108     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
1109 
1110     /* Set the IRDA DMA half transfer complete callback */
1111     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
1112 
1113     /* Set the DMA error callback */
1114     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
1115 
1116     /* Set the DMA abort callback */
1117     hirda->hdmatx->XferAbortCallback = NULL;
1118 
1119     /* Enable the IRDA transmit DMA channel */
1120     if (HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, Size) == HAL_OK)
1121     {
1122       /* Clear the TC flag in the ICR register */
1123       __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
1124 
1125       /* Process Unlocked */
1126       __HAL_UNLOCK(hirda);
1127 
1128       /* Enable the DMA transfer for transmit request by setting the DMAT bit
1129          in the USART CR3 register */
1130       SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1131 
1132       return HAL_OK;
1133     }
1134     else
1135     {
1136       /* Set error code to DMA */
1137       hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1138 
1139       /* Process Unlocked */
1140       __HAL_UNLOCK(hirda);
1141 
1142       /* Restore hirda->gState to ready */
1143       hirda->gState = HAL_IRDA_STATE_READY;
1144 
1145       return HAL_ERROR;
1146     }
1147   }
1148   else
1149   {
1150     return HAL_BUSY;
1151   }
1152 }
1153 
1154 /**
1155   * @brief Receive an amount of data in DMA mode.
1156   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1157   *        the received data is handled as a set of u16. In this case, Size must reflect the number
1158   *        of u16 available through pData.
1159   * @note   When the IRDA parity is enabled (PCE = 1), the received data contains
1160   *         the parity bit (MSB position).
1161   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1162   *               the configuration information for the specified IRDA module.
1163   * @param pData Pointer to data buffer (u8 or u16 data elements).
1164   * @param Size Amount of data elements (u8 or u16) to be received.
1165   * @retval HAL status
1166   */
1167 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1168 {
1169   /* Check that a Rx process is not already ongoing */
1170   if (hirda->RxState == HAL_IRDA_STATE_READY)
1171   {
1172     if ((pData == NULL) || (Size == 0U))
1173     {
1174       return HAL_ERROR;
1175     }
1176 
1177     /* Process Locked */
1178     __HAL_LOCK(hirda);
1179 
1180     hirda->pRxBuffPtr = pData;
1181     hirda->RxXferSize = Size;
1182 
1183     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1184     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1185 
1186     /* Set the IRDA DMA transfer complete callback */
1187     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
1188 
1189     /* Set the IRDA DMA half transfer complete callback */
1190     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
1191 
1192     /* Set the DMA error callback */
1193     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
1194 
1195     /* Set the DMA abort callback */
1196     hirda->hdmarx->XferAbortCallback = NULL;
1197 
1198     /* Enable the DMA channel */
1199     if (HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, Size) == HAL_OK)
1200     {
1201       /* Process Unlocked */
1202       __HAL_UNLOCK(hirda);
1203 
1204       if (hirda->Init.Parity != IRDA_PARITY_NONE)
1205       {
1206         /* Enable the UART Parity Error Interrupt */
1207         SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1208       }
1209 
1210       /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1211       SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1212 
1213       /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1214          in the USART CR3 register */
1215       SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1216 
1217       return HAL_OK;
1218     }
1219     else
1220     {
1221       /* Set error code to DMA */
1222       hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1223 
1224       /* Process Unlocked */
1225       __HAL_UNLOCK(hirda);
1226 
1227       /* Restore hirda->RxState to ready */
1228       hirda->RxState = HAL_IRDA_STATE_READY;
1229 
1230       return HAL_ERROR;
1231     }
1232   }
1233   else
1234   {
1235     return HAL_BUSY;
1236   }
1237 }
1238 
1239 
1240 /**
1241   * @brief Pause the DMA Transfer.
1242   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1243   *                the configuration information for the specified IRDA module.
1244   * @retval HAL status
1245   */
1246 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
1247 {
1248   /* Process Locked */
1249   __HAL_LOCK(hirda);
1250 
1251   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1252   {
1253     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1254     {
1255       /* Disable the IRDA DMA Tx request */
1256       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1257     }
1258   }
1259   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1260   {
1261     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1262     {
1263       /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1264       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1265       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1266 
1267       /* Disable the IRDA DMA Rx request */
1268       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1269     }
1270   }
1271 
1272   /* Process Unlocked */
1273   __HAL_UNLOCK(hirda);
1274 
1275   return HAL_OK;
1276 }
1277 
1278 /**
1279   * @brief Resume the DMA Transfer.
1280   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1281   *                the configuration information for the specified UART module.
1282   * @retval HAL status
1283   */
1284 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
1285 {
1286   /* Process Locked */
1287   __HAL_LOCK(hirda);
1288 
1289   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1290   {
1291     /* Enable the IRDA DMA Tx request */
1292     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1293   }
1294   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1295   {
1296     /* Clear the Overrun flag before resuming the Rx transfer*/
1297     __HAL_IRDA_CLEAR_OREFLAG(hirda);
1298 
1299     /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1300     if (hirda->Init.Parity != IRDA_PARITY_NONE)
1301     {
1302       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1303     }
1304     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1305 
1306     /* Enable the IRDA DMA Rx request */
1307     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1308   }
1309 
1310   /* Process Unlocked */
1311   __HAL_UNLOCK(hirda);
1312 
1313   return HAL_OK;
1314 }
1315 
1316 /**
1317   * @brief Stop the DMA Transfer.
1318   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1319   *                the configuration information for the specified UART module.
1320   * @retval HAL status
1321   */
1322 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
1323 {
1324   /* The Lock is not implemented on this API to allow the user application
1325      to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
1326      HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback:
1327      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1328      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1329      the stream and the corresponding call back is executed. */
1330 
1331   /* Stop IRDA DMA Tx request if ongoing */
1332   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1333   {
1334     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1335     {
1336       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1337 
1338       /* Abort the IRDA DMA Tx channel */
1339       if (hirda->hdmatx != NULL)
1340       {
1341         if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1342         {
1343           if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1344           {
1345             /* Set error code to DMA */
1346             hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1347 
1348             return HAL_TIMEOUT;
1349           }
1350         }
1351       }
1352 
1353       IRDA_EndTxTransfer(hirda);
1354     }
1355   }
1356 
1357   /* Stop IRDA DMA Rx request if ongoing */
1358   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1359   {
1360     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1361     {
1362       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1363 
1364       /* Abort the IRDA DMA Rx channel */
1365       if (hirda->hdmarx != NULL)
1366       {
1367         if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1368         {
1369           if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1370           {
1371             /* Set error code to DMA */
1372             hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1373 
1374             return HAL_TIMEOUT;
1375           }
1376         }
1377       }
1378 
1379       IRDA_EndRxTransfer(hirda);
1380     }
1381   }
1382 
1383   return HAL_OK;
1384 }
1385 
1386 /**
1387   * @brief  Abort ongoing transfers (blocking mode).
1388   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1389   *               the configuration information for the specified UART module.
1390   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1391   *         This procedure performs following operations :
1392   *           - Disable IRDA Interrupts (Tx and Rx)
1393   *           - Disable the DMA transfer in the peripheral register (if enabled)
1394   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1395   *           - Set handle State to READY
1396   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1397   * @retval HAL status
1398   */
1399 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
1400 {
1401   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1402   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
1403                                    USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1404   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1405 
1406   /* Disable the IRDA DMA Tx request if enabled */
1407   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1408   {
1409     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1410 
1411     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1412     if (hirda->hdmatx != NULL)
1413     {
1414       /* Set the IRDA DMA Abort callback to Null.
1415          No call back execution at end of DMA abort procedure */
1416       hirda->hdmatx->XferAbortCallback = NULL;
1417 
1418       if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1419       {
1420         if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1421         {
1422           /* Set error code to DMA */
1423           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1424 
1425           return HAL_TIMEOUT;
1426         }
1427       }
1428     }
1429   }
1430 
1431   /* Disable the IRDA DMA Rx request if enabled */
1432   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1433   {
1434     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1435 
1436     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1437     if (hirda->hdmarx != NULL)
1438     {
1439       /* Set the IRDA DMA Abort callback to Null.
1440          No call back execution at end of DMA abort procedure */
1441       hirda->hdmarx->XferAbortCallback = NULL;
1442 
1443       if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1444       {
1445         if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1446         {
1447           /* Set error code to DMA */
1448           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1449 
1450           return HAL_TIMEOUT;
1451         }
1452       }
1453     }
1454   }
1455 
1456   /* Reset Tx and Rx transfer counters */
1457   hirda->TxXferCount = 0U;
1458   hirda->RxXferCount = 0U;
1459 
1460   /* Clear the Error flags in the ICR register */
1461   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1462 
1463   /* Restore hirda->gState and hirda->RxState to Ready */
1464   hirda->gState  = HAL_IRDA_STATE_READY;
1465   hirda->RxState = HAL_IRDA_STATE_READY;
1466 
1467   /* Reset Handle ErrorCode to No Error */
1468   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1469 
1470   return HAL_OK;
1471 }
1472 
1473 /**
1474   * @brief  Abort ongoing Transmit transfer (blocking mode).
1475   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1476   *               the configuration information for the specified UART module.
1477   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1478   *         This procedure performs following operations :
1479   *           - Disable IRDA Interrupts (Tx)
1480   *           - Disable the DMA transfer in the peripheral register (if enabled)
1481   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1482   *           - Set handle State to READY
1483   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1484   * @retval HAL status
1485   */
1486 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
1487 {
1488   /* Disable TXEIE and TCIE interrupts */
1489   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1490 
1491   /* Disable the IRDA DMA Tx request if enabled */
1492   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1493   {
1494     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1495 
1496     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1497     if (hirda->hdmatx != NULL)
1498     {
1499       /* Set the IRDA DMA Abort callback to Null.
1500          No call back execution at end of DMA abort procedure */
1501       hirda->hdmatx->XferAbortCallback = NULL;
1502 
1503       if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1504       {
1505         if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1506         {
1507           /* Set error code to DMA */
1508           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1509 
1510           return HAL_TIMEOUT;
1511         }
1512       }
1513     }
1514   }
1515 
1516   /* Reset Tx transfer counter */
1517   hirda->TxXferCount = 0U;
1518 
1519   /* Restore hirda->gState to Ready */
1520   hirda->gState = HAL_IRDA_STATE_READY;
1521 
1522   return HAL_OK;
1523 }
1524 
1525 /**
1526   * @brief  Abort ongoing Receive transfer (blocking mode).
1527   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1528   *               the configuration information for the specified UART module.
1529   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1530   *         This procedure performs following operations :
1531   *           - Disable IRDA Interrupts (Rx)
1532   *           - Disable the DMA transfer in the peripheral register (if enabled)
1533   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1534   *           - Set handle State to READY
1535   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1536   * @retval HAL status
1537   */
1538 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
1539 {
1540   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1541   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
1542   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1543 
1544   /* Disable the IRDA DMA Rx request if enabled */
1545   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1546   {
1547     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1548 
1549     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1550     if (hirda->hdmarx != NULL)
1551     {
1552       /* Set the IRDA DMA Abort callback to Null.
1553          No call back execution at end of DMA abort procedure */
1554       hirda->hdmarx->XferAbortCallback = NULL;
1555 
1556       if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1557       {
1558         if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1559         {
1560           /* Set error code to DMA */
1561           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1562 
1563           return HAL_TIMEOUT;
1564         }
1565       }
1566     }
1567   }
1568 
1569   /* Reset Rx transfer counter */
1570   hirda->RxXferCount = 0U;
1571 
1572   /* Clear the Error flags in the ICR register */
1573   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1574 
1575   /* Restore hirda->RxState to Ready */
1576   hirda->RxState = HAL_IRDA_STATE_READY;
1577 
1578   return HAL_OK;
1579 }
1580 
1581 /**
1582   * @brief  Abort ongoing transfers (Interrupt mode).
1583   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1584   *               the configuration information for the specified UART module.
1585   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1586   *         This procedure performs following operations :
1587   *           - Disable IRDA Interrupts (Tx and Rx)
1588   *           - Disable the DMA transfer in the peripheral register (if enabled)
1589   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1590   *           - Set handle State to READY
1591   *           - At abort completion, call user abort complete callback
1592   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1593   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1594   * @retval HAL status
1595   */
1596 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
1597 {
1598   uint32_t abortcplt = 1U;
1599 
1600   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1601   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
1602                                    USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1603   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1604 
1605   /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
1606      before any call to DMA Abort functions */
1607   /* DMA Tx Handle is valid */
1608   if (hirda->hdmatx != NULL)
1609   {
1610     /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
1611        Otherwise, set it to NULL */
1612     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1613     {
1614       hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
1615     }
1616     else
1617     {
1618       hirda->hdmatx->XferAbortCallback = NULL;
1619     }
1620   }
1621   /* DMA Rx Handle is valid */
1622   if (hirda->hdmarx != NULL)
1623   {
1624     /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
1625        Otherwise, set it to NULL */
1626     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1627     {
1628       hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
1629     }
1630     else
1631     {
1632       hirda->hdmarx->XferAbortCallback = NULL;
1633     }
1634   }
1635 
1636   /* Disable the IRDA DMA Tx request if enabled */
1637   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1638   {
1639     /* Disable DMA Tx at UART level */
1640     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1641 
1642     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1643     if (hirda->hdmatx != NULL)
1644     {
1645       /* IRDA Tx DMA Abort callback has already been initialised :
1646          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1647 
1648       /* Abort DMA TX */
1649       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1650       {
1651         hirda->hdmatx->XferAbortCallback = NULL;
1652       }
1653       else
1654       {
1655         abortcplt = 0U;
1656       }
1657     }
1658   }
1659 
1660   /* Disable the IRDA DMA Rx request if enabled */
1661   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1662   {
1663     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1664 
1665     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1666     if (hirda->hdmarx != NULL)
1667     {
1668       /* IRDA Rx DMA Abort callback has already been initialised :
1669          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1670 
1671       /* Abort DMA RX */
1672       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1673       {
1674         hirda->hdmarx->XferAbortCallback = NULL;
1675         abortcplt = 1U;
1676       }
1677       else
1678       {
1679         abortcplt = 0U;
1680       }
1681     }
1682   }
1683 
1684   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1685   if (abortcplt == 1U)
1686   {
1687     /* Reset Tx and Rx transfer counters */
1688     hirda->TxXferCount = 0U;
1689     hirda->RxXferCount = 0U;
1690 
1691     /* Reset errorCode */
1692     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1693 
1694     /* Clear the Error flags in the ICR register */
1695     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1696 
1697     /* Restore hirda->gState and hirda->RxState to Ready */
1698     hirda->gState  = HAL_IRDA_STATE_READY;
1699     hirda->RxState = HAL_IRDA_STATE_READY;
1700 
1701     /* As no DMA to be aborted, call directly user Abort complete callback */
1702 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1703     /* Call registered Abort complete callback */
1704     hirda->AbortCpltCallback(hirda);
1705 #else
1706     /* Call legacy weak Abort complete callback */
1707     HAL_IRDA_AbortCpltCallback(hirda);
1708 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1709   }
1710 
1711   return HAL_OK;
1712 }
1713 
1714 /**
1715   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
1716   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1717   *               the configuration information for the specified UART module.
1718   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1719   *         This procedure performs following operations :
1720   *           - Disable IRDA Interrupts (Tx)
1721   *           - Disable the DMA transfer in the peripheral register (if enabled)
1722   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1723   *           - Set handle State to READY
1724   *           - At abort completion, call user abort complete callback
1725   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1726   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1727   * @retval HAL status
1728   */
1729 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
1730 {
1731   /* Disable TXEIE and TCIE interrupts */
1732   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1733 
1734   /* Disable the IRDA DMA Tx request if enabled */
1735   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1736   {
1737     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1738 
1739     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1740     if (hirda->hdmatx != NULL)
1741     {
1742       /* Set the IRDA DMA Abort callback :
1743          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1744       hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
1745 
1746       /* Abort DMA TX */
1747       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1748       {
1749         /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
1750         hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
1751       }
1752     }
1753     else
1754     {
1755       /* Reset Tx transfer counter */
1756       hirda->TxXferCount = 0U;
1757 
1758       /* Restore hirda->gState to Ready */
1759       hirda->gState = HAL_IRDA_STATE_READY;
1760 
1761       /* As no DMA to be aborted, call directly user Abort complete callback */
1762 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1763       /* Call registered Abort Transmit Complete Callback */
1764       hirda->AbortTransmitCpltCallback(hirda);
1765 #else
1766       /* Call legacy weak Abort Transmit Complete Callback */
1767       HAL_IRDA_AbortTransmitCpltCallback(hirda);
1768 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1769     }
1770   }
1771   else
1772   {
1773     /* Reset Tx transfer counter */
1774     hirda->TxXferCount = 0U;
1775 
1776     /* Restore hirda->gState to Ready */
1777     hirda->gState = HAL_IRDA_STATE_READY;
1778 
1779     /* As no DMA to be aborted, call directly user Abort complete callback */
1780 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1781     /* Call registered Abort Transmit Complete Callback */
1782     hirda->AbortTransmitCpltCallback(hirda);
1783 #else
1784     /* Call legacy weak Abort Transmit Complete Callback */
1785     HAL_IRDA_AbortTransmitCpltCallback(hirda);
1786 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1787   }
1788 
1789   return HAL_OK;
1790 }
1791 
1792 /**
1793   * @brief  Abort ongoing Receive transfer (Interrupt mode).
1794   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1795   *               the configuration information for the specified UART module.
1796   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1797   *         This procedure performs following operations :
1798   *           - Disable IRDA Interrupts (Rx)
1799   *           - Disable the DMA transfer in the peripheral register (if enabled)
1800   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1801   *           - Set handle State to READY
1802   *           - At abort completion, call user abort complete callback
1803   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1804   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1805   * @retval HAL status
1806   */
1807 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
1808 {
1809   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1810   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
1811   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1812 
1813   /* Disable the IRDA DMA Rx request if enabled */
1814   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1815   {
1816     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1817 
1818     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1819     if (hirda->hdmarx != NULL)
1820     {
1821       /* Set the IRDA DMA Abort callback :
1822          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1823       hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
1824 
1825       /* Abort DMA RX */
1826       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1827       {
1828         /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1829         hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1830       }
1831     }
1832     else
1833     {
1834       /* Reset Rx transfer counter */
1835       hirda->RxXferCount = 0U;
1836 
1837       /* Clear the Error flags in the ICR register */
1838       __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1839 
1840       /* Restore hirda->RxState to Ready */
1841       hirda->RxState = HAL_IRDA_STATE_READY;
1842 
1843       /* As no DMA to be aborted, call directly user Abort complete callback */
1844 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1845       /* Call registered Abort Receive Complete Callback */
1846       hirda->AbortReceiveCpltCallback(hirda);
1847 #else
1848       /* Call legacy weak Abort Receive Complete Callback */
1849       HAL_IRDA_AbortReceiveCpltCallback(hirda);
1850 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1851     }
1852   }
1853   else
1854   {
1855     /* Reset Rx transfer counter */
1856     hirda->RxXferCount = 0U;
1857 
1858     /* Clear the Error flags in the ICR register */
1859     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1860 
1861     /* Restore hirda->RxState to Ready */
1862     hirda->RxState = HAL_IRDA_STATE_READY;
1863 
1864     /* As no DMA to be aborted, call directly user Abort complete callback */
1865 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1866     /* Call registered Abort Receive Complete Callback */
1867     hirda->AbortReceiveCpltCallback(hirda);
1868 #else
1869     /* Call legacy weak Abort Receive Complete Callback */
1870     HAL_IRDA_AbortReceiveCpltCallback(hirda);
1871 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1872   }
1873 
1874   return HAL_OK;
1875 }
1876 
1877 /**
1878   * @brief Handle IRDA interrupt request.
1879   * @param hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1880   *               the configuration information for the specified IRDA module.
1881   * @retval None
1882   */
1883 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
1884 {
1885   uint32_t isrflags   = READ_REG(hirda->Instance->ISR);
1886   uint32_t cr1its     = READ_REG(hirda->Instance->CR1);
1887   uint32_t cr3its;
1888   uint32_t errorflags;
1889   uint32_t errorcode;
1890 
1891   /* If no error occurs */
1892   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
1893   if (errorflags == 0U)
1894   {
1895     /* IRDA in mode Receiver ---------------------------------------------------*/
1896     if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
1897     {
1898       IRDA_Receive_IT(hirda);
1899       return;
1900     }
1901   }
1902 
1903   /* If some errors occur */
1904   cr3its = READ_REG(hirda->Instance->CR3);
1905   if ((errorflags != 0U)
1906       && (((cr3its & USART_CR3_EIE) != 0U)
1907           || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
1908   {
1909     /* IRDA parity error interrupt occurred -------------------------------------*/
1910     if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
1911     {
1912       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
1913 
1914       hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
1915     }
1916 
1917     /* IRDA frame error interrupt occurred --------------------------------------*/
1918     if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
1919     {
1920       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
1921 
1922       hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
1923     }
1924 
1925     /* IRDA noise error interrupt occurred --------------------------------------*/
1926     if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
1927     {
1928       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
1929 
1930       hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
1931     }
1932 
1933     /* IRDA Over-Run interrupt occurred -----------------------------------------*/
1934     if (((isrflags & USART_ISR_ORE) != 0U) &&
1935         (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U)))
1936     {
1937       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
1938 
1939       hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
1940     }
1941 
1942     /* Call IRDA Error Call back function if need be --------------------------*/
1943     if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
1944     {
1945       /* IRDA in mode Receiver ---------------------------------------------------*/
1946       if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
1947       {
1948         IRDA_Receive_IT(hirda);
1949       }
1950 
1951       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1952          consider error as blocking */
1953       errorcode = hirda->ErrorCode;
1954       if ((HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) ||
1955           ((errorcode & HAL_IRDA_ERROR_ORE) != 0U))
1956       {
1957         /* Blocking error : transfer is aborted
1958            Set the IRDA state ready to be able to start again the process,
1959            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1960         IRDA_EndRxTransfer(hirda);
1961 
1962         /* Disable the IRDA DMA Rx request if enabled */
1963         if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1964         {
1965           CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1966 
1967           /* Abort the IRDA DMA Rx channel */
1968           if (hirda->hdmarx != NULL)
1969           {
1970             /* Set the IRDA DMA Abort callback :
1971                will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
1972             hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
1973 
1974             /* Abort DMA RX */
1975             if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1976             {
1977               /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1978               hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1979             }
1980           }
1981           else
1982           {
1983 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1984             /* Call registered user error callback */
1985             hirda->ErrorCallback(hirda);
1986 #else
1987             /* Call legacy weak user error callback */
1988             HAL_IRDA_ErrorCallback(hirda);
1989 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1990           }
1991         }
1992         else
1993         {
1994 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1995           /* Call registered user error callback */
1996           hirda->ErrorCallback(hirda);
1997 #else
1998           /* Call legacy weak user error callback */
1999           HAL_IRDA_ErrorCallback(hirda);
2000 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2001         }
2002       }
2003       else
2004       {
2005         /* Non Blocking error : transfer could go on.
2006            Error is notified to user through user error callback */
2007 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2008         /* Call registered user error callback */
2009         hirda->ErrorCallback(hirda);
2010 #else
2011         /* Call legacy weak user error callback */
2012         HAL_IRDA_ErrorCallback(hirda);
2013 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2014         hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2015       }
2016     }
2017     return;
2018 
2019   } /* End if some error occurs */
2020 
2021   /* IRDA in mode Transmitter ------------------------------------------------*/
2022   if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) && ((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U))
2023   {
2024     IRDA_Transmit_IT(hirda);
2025     return;
2026   }
2027 
2028   /* IRDA in mode Transmitter (transmission end) -----------------------------*/
2029   if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2030   {
2031     IRDA_EndTransmit_IT(hirda);
2032     return;
2033   }
2034 
2035 }
2036 
2037 /**
2038   * @brief  Tx Transfer completed callback.
2039   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2040   *               the configuration information for the specified IRDA module.
2041   * @retval None
2042   */
2043 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
2044 {
2045   /* Prevent unused argument(s) compilation warning */
2046   UNUSED(hirda);
2047 
2048   /* NOTE : This function should not be modified, when the callback is needed,
2049             the HAL_IRDA_TxCpltCallback can be implemented in the user file.
2050    */
2051 }
2052 
2053 /**
2054   * @brief  Tx Half Transfer completed callback.
2055   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2056   *               the configuration information for the specified USART module.
2057   * @retval None
2058   */
2059 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2060 {
2061   /* Prevent unused argument(s) compilation warning */
2062   UNUSED(hirda);
2063 
2064   /* NOTE : This function should not be modified, when the callback is needed,
2065             the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
2066    */
2067 }
2068 
2069 /**
2070   * @brief  Rx Transfer completed callback.
2071   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2072   *               the configuration information for the specified IRDA module.
2073   * @retval None
2074   */
2075 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
2076 {
2077   /* Prevent unused argument(s) compilation warning */
2078   UNUSED(hirda);
2079 
2080   /* NOTE : This function should not be modified, when the callback is needed,
2081             the HAL_IRDA_RxCpltCallback can be implemented in the user file.
2082    */
2083 }
2084 
2085 /**
2086   * @brief  Rx Half Transfer complete callback.
2087   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2088   *               the configuration information for the specified IRDA module.
2089   * @retval None
2090   */
2091 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2092 {
2093   /* Prevent unused argument(s) compilation warning */
2094   UNUSED(hirda);
2095 
2096   /* NOTE : This function should not be modified, when the callback is needed,
2097             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
2098    */
2099 }
2100 
2101 /**
2102   * @brief  IRDA error callback.
2103   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2104   *               the configuration information for the specified IRDA module.
2105   * @retval None
2106   */
2107 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
2108 {
2109   /* Prevent unused argument(s) compilation warning */
2110   UNUSED(hirda);
2111 
2112   /* NOTE : This function should not be modified, when the callback is needed,
2113             the HAL_IRDA_ErrorCallback can be implemented in the user file.
2114    */
2115 }
2116 
2117 /**
2118   * @brief  IRDA Abort Complete callback.
2119   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2120   *               the configuration information for the specified IRDA module.
2121   * @retval None
2122   */
2123 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
2124 {
2125   /* Prevent unused argument(s) compilation warning */
2126   UNUSED(hirda);
2127 
2128   /* NOTE : This function should not be modified, when the callback is needed,
2129             the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
2130    */
2131 }
2132 
2133 /**
2134   * @brief  IRDA Abort Complete callback.
2135   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2136   *               the configuration information for the specified IRDA module.
2137   * @retval None
2138   */
2139 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
2140 {
2141   /* Prevent unused argument(s) compilation warning */
2142   UNUSED(hirda);
2143 
2144   /* NOTE : This function should not be modified, when the callback is needed,
2145             the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
2146    */
2147 }
2148 
2149 /**
2150   * @brief  IRDA Abort Receive Complete callback.
2151   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2152   *               the configuration information for the specified IRDA module.
2153   * @retval None
2154   */
2155 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
2156 {
2157   /* Prevent unused argument(s) compilation warning */
2158   UNUSED(hirda);
2159 
2160   /* NOTE : This function should not be modified, when the callback is needed,
2161             the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
2162    */
2163 }
2164 
2165 /**
2166   * @}
2167   */
2168 
2169 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
2170   * @ingroup RTEMSBSPsARMSTM32H7
2171   *  @brief   IRDA State and Errors functions
2172   *
2173 @verbatim
2174   ==============================================================================
2175             ##### Peripheral State and Error functions #####
2176   ==============================================================================
2177   [..]
2178     This subsection provides a set of functions allowing to return the State of IrDA
2179     communication process and also return Peripheral Errors occurred during communication process
2180      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
2181          of the IRDA peripheral handle.
2182      (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
2183          communication.
2184 
2185 @endverbatim
2186   * @{
2187   */
2188 
2189 /**
2190   * @brief Return the IRDA handle state.
2191   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2192   *                the configuration information for the specified IRDA module.
2193   * @retval HAL state
2194   */
2195 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(const IRDA_HandleTypeDef *hirda)
2196 {
2197   /* Return IRDA handle state */
2198   uint32_t temp1;
2199   uint32_t temp2;
2200   temp1 = (uint32_t)hirda->gState;
2201   temp2 = (uint32_t)hirda->RxState;
2202 
2203   return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
2204 }
2205 
2206 /**
2207   * @brief Return the IRDA handle error code.
2208   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2209   *               the configuration information for the specified IRDA module.
2210   * @retval IRDA Error Code
2211   */
2212 uint32_t HAL_IRDA_GetError(const IRDA_HandleTypeDef *hirda)
2213 {
2214   return hirda->ErrorCode;
2215 }
2216 
2217 /**
2218   * @}
2219   */
2220 
2221 /**
2222   * @}
2223   */
2224 
2225 /** @defgroup IRDA_Private_Functions IRDA Private Functions
2226   * @ingroup RTEMSBSPsARMSTM32H7
2227   * @{
2228   */
2229 
2230 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2231 /**
2232   * @brief  Initialize the callbacks to their default values.
2233   * @param  hirda IRDA handle.
2234   * @retval none
2235   */
2236 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
2237 {
2238   /* Init the IRDA Callback settings */
2239   hirda->TxHalfCpltCallback        = HAL_IRDA_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2240   hirda->TxCpltCallback            = HAL_IRDA_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2241   hirda->RxHalfCpltCallback        = HAL_IRDA_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2242   hirda->RxCpltCallback            = HAL_IRDA_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2243   hirda->ErrorCallback             = HAL_IRDA_ErrorCallback;             /* Legacy weak ErrorCallback             */
2244   hirda->AbortCpltCallback         = HAL_IRDA_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2245   hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2246   hirda->AbortReceiveCpltCallback  = HAL_IRDA_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
2247 
2248 }
2249 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2250 
2251 /**
2252   * @brief Configure the IRDA peripheral.
2253   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2254   *               the configuration information for the specified IRDA module.
2255   * @retval HAL status
2256   */
2257 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
2258 {
2259   uint32_t tmpreg;
2260   IRDA_ClockSourceTypeDef clocksource;
2261   HAL_StatusTypeDef ret = HAL_OK;
2262   static const uint16_t IRDAPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
2263   PLL2_ClocksTypeDef pll2_clocks;
2264   PLL3_ClocksTypeDef pll3_clocks;
2265   uint32_t pclk;
2266 
2267   /* Check the communication parameters */
2268   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2269   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2270   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2271   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
2272   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
2273   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
2274   assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler));
2275 
2276   /*-------------------------- USART CR1 Configuration -----------------------*/
2277   /* Configure the IRDA Word Length, Parity and transfer Mode:
2278      Set the M bits according to hirda->Init.WordLength value
2279      Set PCE and PS bits according to hirda->Init.Parity value
2280      Set TE and RE bits according to hirda->Init.Mode value */
2281   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
2282 
2283   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
2284 
2285   /*-------------------------- USART CR3 Configuration -----------------------*/
2286   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
2287 
2288   /*--------------------- USART clock PRESC Configuration ----------------*/
2289   /* Configure
2290   * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */
2291   MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler);
2292 
2293   /*-------------------------- USART GTPR Configuration ----------------------*/
2294   MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler);
2295 
2296   /*-------------------------- USART BRR Configuration -----------------------*/
2297   IRDA_GETCLOCKSOURCE(hirda, clocksource);
2298   tmpreg =   0U;
2299   switch (clocksource)
2300   {
2301     case IRDA_CLOCKSOURCE_D2PCLK1:
2302       pclk = HAL_RCC_GetPCLK1Freq();
2303       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2304       break;
2305     case IRDA_CLOCKSOURCE_D2PCLK2:
2306       pclk = HAL_RCC_GetPCLK2Freq();
2307       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2308       break;
2309     case IRDA_CLOCKSOURCE_PLL2Q:
2310       HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2311       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll2_clocks.PLL2_Q_Frequency,
2312                                               hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2313       break;
2314     case IRDA_CLOCKSOURCE_PLL3Q:
2315       HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2316       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll3_clocks.PLL3_Q_Frequency, hirda->Init.BaudRate,
2317                                               hirda->Init.ClockPrescaler));
2318       break;
2319     case IRDA_CLOCKSOURCE_CSI:
2320       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(CSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2321       break;
2322     case IRDA_CLOCKSOURCE_HSI:
2323       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2324       break;
2325     case IRDA_CLOCKSOURCE_LSE:
2326       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2327       break;
2328     default:
2329       ret = HAL_ERROR;
2330       break;
2331   }
2332 
2333   /* USARTDIV must be greater than or equal to 0d16 */
2334   if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX))
2335   {
2336     hirda->Instance->BRR = (uint16_t)tmpreg;
2337   }
2338   else
2339   {
2340     ret = HAL_ERROR;
2341   }
2342 
2343   return ret;
2344 }
2345 
2346 /**
2347   * @brief Check the IRDA Idle State.
2348   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2349   *               the configuration information for the specified IRDA module.
2350   * @retval HAL status
2351   */
2352 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
2353 {
2354   uint32_t tickstart;
2355 
2356   /* Initialize the IRDA ErrorCode */
2357   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2358 
2359   /* Init tickstart for timeout management */
2360   tickstart = HAL_GetTick();
2361 
2362   /* Check if the Transmitter is enabled */
2363   if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2364   {
2365     /* Wait until TEACK flag is set */
2366     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2367     {
2368       /* Timeout occurred */
2369       return HAL_TIMEOUT;
2370     }
2371   }
2372   /* Check if the Receiver is enabled */
2373   if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2374   {
2375     /* Wait until REACK flag is set */
2376     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2377     {
2378       /* Timeout occurred */
2379       return HAL_TIMEOUT;
2380     }
2381   }
2382 
2383   /* Initialize the IRDA state*/
2384   hirda->gState  = HAL_IRDA_STATE_READY;
2385   hirda->RxState = HAL_IRDA_STATE_READY;
2386 
2387   /* Process Unlocked */
2388   __HAL_UNLOCK(hirda);
2389 
2390   return HAL_OK;
2391 }
2392 
2393 /**
2394   * @brief  Handle IRDA Communication Timeout. It waits
2395   *         until a flag is no longer in the specified status.
2396   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2397   *               the configuration information for the specified IRDA module.
2398   * @param  Flag Specifies the IRDA flag to check.
2399   * @param  Status The actual Flag status (SET or RESET)
2400   * @param  Tickstart Tick start value
2401   * @param  Timeout Timeout duration
2402   * @retval HAL status
2403   */
2404 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
2405                                                      uint32_t Tickstart, uint32_t Timeout)
2406 {
2407   /* Wait until flag is set */
2408   while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
2409   {
2410     /* Check for the Timeout */
2411     if (Timeout != HAL_MAX_DELAY)
2412     {
2413       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2414       {
2415         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
2416            interrupts for the interrupt process */
2417         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
2418         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2419 
2420         hirda->gState  = HAL_IRDA_STATE_READY;
2421         hirda->RxState = HAL_IRDA_STATE_READY;
2422 
2423         /* Process Unlocked */
2424         __HAL_UNLOCK(hirda);
2425         return HAL_TIMEOUT;
2426       }
2427     }
2428   }
2429   return HAL_OK;
2430 }
2431 
2432 
2433 /**
2434   * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
2435   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2436   *               the configuration information for the specified IRDA module.
2437   * @retval None
2438   */
2439 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
2440 {
2441   /* Disable TXEIE and TCIE interrupts */
2442   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
2443 
2444   /* At end of Tx process, restore hirda->gState to Ready */
2445   hirda->gState = HAL_IRDA_STATE_READY;
2446 }
2447 
2448 /**
2449   * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
2450   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2451   *               the configuration information for the specified IRDA module.
2452   * @retval None
2453   */
2454 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
2455 {
2456   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2457   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2458   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2459 
2460   /* At end of Rx process, restore hirda->RxState to Ready */
2461   hirda->RxState = HAL_IRDA_STATE_READY;
2462 }
2463 
2464 
2465 /**
2466   * @brief  DMA IRDA transmit process complete callback.
2467   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2468   *              the configuration information for the specified DMA module.
2469   * @retval None
2470   */
2471 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2472 {
2473   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2474 
2475   /* DMA Normal mode */
2476   if (hdma->Init.Mode != DMA_CIRCULAR)
2477   {
2478     hirda->TxXferCount = 0U;
2479 
2480     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2481        in the IRDA CR3 register */
2482     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
2483 
2484     /* Enable the IRDA Transmit Complete Interrupt */
2485     SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2486   }
2487   /* DMA Circular mode */
2488   else
2489   {
2490 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2491     /* Call registered Tx complete callback */
2492     hirda->TxCpltCallback(hirda);
2493 #else
2494     /* Call legacy weak Tx complete callback */
2495     HAL_IRDA_TxCpltCallback(hirda);
2496 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2497   }
2498 
2499 }
2500 
2501 /**
2502   * @brief  DMA IRDA transmit process half complete callback.
2503   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2504   *              the configuration information for the specified DMA module.
2505   * @retval None
2506   */
2507 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
2508 {
2509   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2510 
2511 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2512   /* Call registered Tx Half complete callback */
2513   hirda->TxHalfCpltCallback(hirda);
2514 #else
2515   /* Call legacy weak Tx complete callback */
2516   HAL_IRDA_TxHalfCpltCallback(hirda);
2517 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2518 }
2519 
2520 /**
2521   * @brief  DMA IRDA receive process complete callback.
2522   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2523   *               the configuration information for the specified DMA module.
2524   * @retval None
2525   */
2526 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2527 {
2528   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2529 
2530   /* DMA Normal mode */
2531   if (hdma->Init.Mode != DMA_CIRCULAR)
2532   {
2533     hirda->RxXferCount = 0U;
2534 
2535     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2536     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2537     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2538 
2539     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2540        in the IRDA CR3 register */
2541     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2542 
2543     /* At end of Rx process, restore hirda->RxState to Ready */
2544     hirda->RxState = HAL_IRDA_STATE_READY;
2545   }
2546 
2547 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2548   /* Call registered Rx complete callback */
2549   hirda->RxCpltCallback(hirda);
2550 #else
2551   /* Call legacy weak Rx complete callback */
2552   HAL_IRDA_RxCpltCallback(hirda);
2553 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2554 }
2555 
2556 /**
2557   * @brief DMA IRDA receive process half complete callback.
2558   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2559   *              the configuration information for the specified DMA module.
2560   * @retval None
2561   */
2562 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
2563 {
2564   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2565 
2566 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2567   /*Call registered Rx Half complete callback*/
2568   hirda->RxHalfCpltCallback(hirda);
2569 #else
2570   /* Call legacy weak Rx Half complete callback */
2571   HAL_IRDA_RxHalfCpltCallback(hirda);
2572 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2573 }
2574 
2575 /**
2576   * @brief DMA IRDA communication error callback.
2577   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2578   *              the configuration information for the specified DMA module.
2579   * @retval None
2580   */
2581 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
2582 {
2583   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2584 
2585   /* Stop IRDA DMA Tx request if ongoing */
2586   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2587   {
2588     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
2589     {
2590       hirda->TxXferCount = 0U;
2591       IRDA_EndTxTransfer(hirda);
2592     }
2593   }
2594 
2595   /* Stop IRDA DMA Rx request if ongoing */
2596   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2597   {
2598     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2599     {
2600       hirda->RxXferCount = 0U;
2601       IRDA_EndRxTransfer(hirda);
2602     }
2603   }
2604 
2605   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
2606 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2607   /* Call registered user error callback */
2608   hirda->ErrorCallback(hirda);
2609 #else
2610   /* Call legacy weak user error callback */
2611   HAL_IRDA_ErrorCallback(hirda);
2612 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2613 }
2614 
2615 /**
2616   * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
2617   *         (To be called at end of DMA Abort procedure following error occurrence).
2618   * @param  hdma DMA handle.
2619   * @retval None
2620   */
2621 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2622 {
2623   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2624   hirda->RxXferCount = 0U;
2625   hirda->TxXferCount = 0U;
2626 
2627 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2628   /* Call registered user error callback */
2629   hirda->ErrorCallback(hirda);
2630 #else
2631   /* Call legacy weak user error callback */
2632   HAL_IRDA_ErrorCallback(hirda);
2633 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2634 }
2635 
2636 /**
2637   * @brief  DMA IRDA Tx communication abort callback, when initiated by user
2638   *         (To be called at end of DMA Tx Abort procedure following user abort request).
2639   * @note   When this callback is executed, User Abort complete call back is called only if no
2640   *         Abort still ongoing for Rx DMA Handle.
2641   * @param  hdma DMA handle.
2642   * @retval None
2643   */
2644 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2645 {
2646   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2647 
2648   hirda->hdmatx->XferAbortCallback = NULL;
2649 
2650   /* Check if an Abort process is still ongoing */
2651   if (hirda->hdmarx != NULL)
2652   {
2653     if (hirda->hdmarx->XferAbortCallback != NULL)
2654     {
2655       return;
2656     }
2657   }
2658 
2659   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2660   hirda->TxXferCount = 0U;
2661   hirda->RxXferCount = 0U;
2662 
2663   /* Reset errorCode */
2664   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2665 
2666   /* Clear the Error flags in the ICR register */
2667   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2668 
2669   /* Restore hirda->gState and hirda->RxState to Ready */
2670   hirda->gState  = HAL_IRDA_STATE_READY;
2671   hirda->RxState = HAL_IRDA_STATE_READY;
2672 
2673   /* Call user Abort complete callback */
2674 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2675   /* Call registered Abort complete callback */
2676   hirda->AbortCpltCallback(hirda);
2677 #else
2678   /* Call legacy weak Abort complete callback */
2679   HAL_IRDA_AbortCpltCallback(hirda);
2680 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2681 }
2682 
2683 
2684 /**
2685   * @brief  DMA IRDA Rx communication abort callback, when initiated by user
2686   *         (To be called at end of DMA Rx Abort procedure following user abort request).
2687   * @note   When this callback is executed, User Abort complete call back is called only if no
2688   *         Abort still ongoing for Tx DMA Handle.
2689   * @param  hdma DMA handle.
2690   * @retval None
2691   */
2692 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2693 {
2694   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2695 
2696   hirda->hdmarx->XferAbortCallback = NULL;
2697 
2698   /* Check if an Abort process is still ongoing */
2699   if (hirda->hdmatx != NULL)
2700   {
2701     if (hirda->hdmatx->XferAbortCallback != NULL)
2702     {
2703       return;
2704     }
2705   }
2706 
2707   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2708   hirda->TxXferCount = 0U;
2709   hirda->RxXferCount = 0U;
2710 
2711   /* Reset errorCode */
2712   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2713 
2714   /* Clear the Error flags in the ICR register */
2715   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2716 
2717   /* Restore hirda->gState and hirda->RxState to Ready */
2718   hirda->gState  = HAL_IRDA_STATE_READY;
2719   hirda->RxState = HAL_IRDA_STATE_READY;
2720 
2721   /* Call user Abort complete callback */
2722 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2723   /* Call registered Abort complete callback */
2724   hirda->AbortCpltCallback(hirda);
2725 #else
2726   /* Call legacy weak Abort complete callback */
2727   HAL_IRDA_AbortCpltCallback(hirda);
2728 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2729 }
2730 
2731 
2732 /**
2733   * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
2734   *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
2735   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2736   *         and leads to user Tx Abort Complete callback execution).
2737   * @param  hdma DMA handle.
2738   * @retval None
2739   */
2740 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2741 {
2742   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2743 
2744   hirda->TxXferCount = 0U;
2745 
2746   /* Restore hirda->gState to Ready */
2747   hirda->gState = HAL_IRDA_STATE_READY;
2748 
2749   /* Call user Abort complete callback */
2750 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2751   /* Call registered Abort Transmit Complete Callback */
2752   hirda->AbortTransmitCpltCallback(hirda);
2753 #else
2754   /* Call legacy weak Abort Transmit Complete Callback */
2755   HAL_IRDA_AbortTransmitCpltCallback(hirda);
2756 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2757 }
2758 
2759 /**
2760   * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
2761   *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
2762   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2763   *         and leads to user Rx Abort Complete callback execution).
2764   * @param  hdma DMA handle.
2765   * @retval None
2766   */
2767 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2768 {
2769   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2770 
2771   hirda->RxXferCount = 0U;
2772 
2773   /* Clear the Error flags in the ICR register */
2774   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2775 
2776   /* Restore hirda->RxState to Ready */
2777   hirda->RxState = HAL_IRDA_STATE_READY;
2778 
2779   /* Call user Abort complete callback */
2780 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2781   /* Call registered Abort Receive Complete Callback */
2782   hirda->AbortReceiveCpltCallback(hirda);
2783 #else
2784   /* Call legacy weak Abort Receive Complete Callback */
2785   HAL_IRDA_AbortReceiveCpltCallback(hirda);
2786 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2787 }
2788 
2789 /**
2790   * @brief  Send an amount of data in interrupt mode.
2791   * @note   Function is called under interruption only, once
2792   *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
2793   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2794   *               the configuration information for the specified IRDA module.
2795   * @retval None
2796   */
2797 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
2798 {
2799   const uint16_t *tmp;
2800 
2801   /* Check that a Tx process is ongoing */
2802   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2803   {
2804     if (hirda->TxXferCount == 0U)
2805     {
2806       /* Disable the IRDA Transmit Data Register Empty Interrupt */
2807       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
2808 
2809       /* Enable the IRDA Transmit Complete Interrupt */
2810       SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2811     }
2812     else
2813     {
2814       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2815       {
2816         tmp = (const uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */
2817         hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
2818         hirda->pTxBuffPtr += 2U;
2819       }
2820       else
2821       {
2822         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU);
2823         hirda->pTxBuffPtr++;
2824       }
2825       hirda->TxXferCount--;
2826     }
2827   }
2828 }
2829 
2830 /**
2831   * @brief  Wrap up transmission in non-blocking mode.
2832   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2833   *               the configuration information for the specified IRDA module.
2834   * @retval None
2835   */
2836 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
2837 {
2838   /* Disable the IRDA Transmit Complete Interrupt */
2839   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2840 
2841   /* Tx process is ended, restore hirda->gState to Ready */
2842   hirda->gState = HAL_IRDA_STATE_READY;
2843 
2844 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2845   /* Call registered Tx complete callback */
2846   hirda->TxCpltCallback(hirda);
2847 #else
2848   /* Call legacy weak Tx complete callback */
2849   HAL_IRDA_TxCpltCallback(hirda);
2850 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2851 }
2852 
2853 /**
2854   * @brief  Receive an amount of data in interrupt mode.
2855   * @note   Function is called under interruption only, once
2856   *         interruptions have been enabled by HAL_IRDA_Receive_IT()
2857   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2858   *               the configuration information for the specified IRDA module.
2859   * @retval None
2860   */
2861 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
2862 {
2863   uint16_t *tmp;
2864   uint16_t  uhMask = hirda->Mask;
2865   uint16_t  uhdata;
2866 
2867   /* Check that a Rx process is ongoing */
2868   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2869   {
2870     uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
2871     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2872     {
2873       tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */
2874       *tmp = (uint16_t)(uhdata & uhMask);
2875       hirda->pRxBuffPtr  += 2U;
2876     }
2877     else
2878     {
2879       *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
2880       hirda->pRxBuffPtr++;
2881     }
2882 
2883     hirda->RxXferCount--;
2884     if (hirda->RxXferCount == 0U)
2885     {
2886       /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */
2887       CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2888 
2889       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2890       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2891 
2892       /* Rx process is completed, restore hirda->RxState to Ready */
2893       hirda->RxState = HAL_IRDA_STATE_READY;
2894 
2895 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2896       /* Call registered Rx complete callback */
2897       hirda->RxCpltCallback(hirda);
2898 #else
2899       /* Call legacy weak Rx complete callback */
2900       HAL_IRDA_RxCpltCallback(hirda);
2901 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2902     }
2903   }
2904   else
2905   {
2906     /* Clear RXNE interrupt flag */
2907     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
2908   }
2909 }
2910 
2911 /**
2912   * @}
2913   */
2914 
2915 #endif /* HAL_IRDA_MODULE_ENABLED */
2916 /**
2917   * @}
2918   */
2919 
2920 /**
2921   * @}
2922   */
2923 
2924