STM32L443xx HAL User Manual
stm32l4xx_hal_irda.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_irda.c
00004   * @author  MCD Application Team
00005   * @brief   IRDA HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the IrDA (Infrared Data Association) Peripheral
00008   *          (IRDA)
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State and Errors functions
00012   *           + Peripheral Control functions
00013   *
00014   ******************************************************************************
00015   * @attention
00016   *
00017   * Copyright (c) 2017 STMicroelectronics.
00018   * All rights reserved.
00019   *
00020   * This software is licensed under terms that can be found in the LICENSE file
00021   * in the root directory of this software component.
00022   * If no LICENSE file comes with this software, it is provided AS-IS.
00023   *
00024   ******************************************************************************
00025   @verbatim
00026   ==============================================================================
00027                         ##### How to use this driver #####
00028   ==============================================================================
00029   [..]
00030     The IRDA HAL driver can be used as follows:
00031 
00032     (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda).
00033     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API
00034         in setting the associated USART or UART in IRDA mode:
00035         (++) Enable the USARTx/UARTx interface clock.
00036         (++) USARTx/UARTx pins configuration:
00037             (+++) Enable the clock for the USARTx/UARTx GPIOs.
00038             (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input).
00039         (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
00040              and HAL_IRDA_Receive_IT() APIs):
00041             (+++) Configure the USARTx/UARTx interrupt priority.
00042             (+++) Enable the NVIC USARTx/UARTx IRQ handle.
00043             (+++) The specific IRDA interrupts (Transmission complete interrupt,
00044                   RXNE interrupt and Error Interrupts) will be managed using the macros
00045                   __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
00046 
00047         (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
00048              and HAL_IRDA_Receive_DMA() APIs):
00049             (+++) Declare a DMA handle structure for the Tx/Rx channel.
00050             (+++) Enable the DMAx interface clock.
00051             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
00052             (+++) Configure the DMA Tx/Rx channel.
00053             (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
00054             (+++) Configure the priority and enable the NVIC for the transfer
00055                   complete interrupt on the DMA Tx/Rx channel.
00056 
00057     (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
00058         the normal or low power mode and the clock prescaler in the hirda handle Init structure.
00059 
00060     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
00061         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00062              by calling the customized HAL_IRDA_MspInit() API.
00063 
00064          -@@- The specific IRDA interrupts (Transmission complete interrupt,
00065              RXNE interrupt and Error Interrupts) will be managed using the macros
00066              __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
00067 
00068     (#) Three operation modes are available within this driver :
00069 
00070      *** Polling mode IO operation ***
00071      =================================
00072      [..]
00073        (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
00074        (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
00075 
00076      *** Interrupt mode IO operation ***
00077      ===================================
00078      [..]
00079        (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT()
00080        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
00081             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
00082        (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT()
00083        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
00084             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
00085        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
00086             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
00087 
00088      *** DMA mode IO operation ***
00089      ==============================
00090      [..]
00091        (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
00092        (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can
00093             add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback()
00094        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
00095             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
00096        (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA()
00097        (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can
00098             add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback()
00099        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
00100             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
00101        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
00102             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
00103 
00104      *** IRDA HAL driver macros list ***
00105      ====================================
00106      [..]
00107        Below the list of most used macros in IRDA HAL driver.
00108 
00109        (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
00110        (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
00111        (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
00112        (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
00113        (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
00114        (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
00115        (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled
00116 
00117      [..]
00118        (@) You can refer to the IRDA HAL driver header file for more useful macros
00119 
00120     ##### Callback registration #####
00121     ==================================
00122 
00123     [..]
00124     The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1
00125     allows the user to configure dynamically the driver callbacks.
00126 
00127     [..]
00128     Use Function HAL_IRDA_RegisterCallback() to register a user callback.
00129     Function HAL_IRDA_RegisterCallback() allows to register following callbacks:
00130     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
00131     (+) TxCpltCallback            : Tx Complete Callback.
00132     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
00133     (+) RxCpltCallback            : Rx Complete Callback.
00134     (+) ErrorCallback             : Error Callback.
00135     (+) AbortCpltCallback         : Abort Complete Callback.
00136     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
00137     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
00138     (+) MspInitCallback           : IRDA MspInit.
00139     (+) MspDeInitCallback         : IRDA MspDeInit.
00140     This function takes as parameters the HAL peripheral handle, the Callback ID
00141     and a pointer to the user callback function.
00142 
00143     [..]
00144     Use function HAL_IRDA_UnRegisterCallback() to reset a callback to the default
00145     weak (surcharged) function.
00146     HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle,
00147     and the Callback ID.
00148     This function allows to reset following callbacks:
00149     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
00150     (+) TxCpltCallback            : Tx Complete Callback.
00151     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
00152     (+) RxCpltCallback            : Rx Complete Callback.
00153     (+) ErrorCallback             : Error Callback.
00154     (+) AbortCpltCallback         : Abort Complete Callback.
00155     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
00156     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
00157     (+) MspInitCallback           : IRDA MspInit.
00158     (+) MspDeInitCallback         : IRDA MspDeInit.
00159 
00160     [..]
00161     By default, after the HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET
00162     all callbacks are set to the corresponding weak (surcharged) functions:
00163     examples HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxHalfCpltCallback().
00164     Exception done for MspInit and MspDeInit functions that are respectively
00165     reset to the legacy weak (surcharged) functions in the HAL_IRDA_Init()
00166     and HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand).
00167     If not, MspInit or MspDeInit are not null, the HAL_IRDA_Init() and HAL_IRDA_DeInit()
00168     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
00169 
00170     [..]
00171     Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only.
00172     Exception done MspInit/MspDeInit that can be registered/unregistered
00173     in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user)
00174     MspInit/DeInit callbacks can be used during the Init/DeInit.
00175     In that case first register the MspInit/MspDeInit user callbacks
00176     using HAL_IRDA_RegisterCallback() before calling HAL_IRDA_DeInit()
00177     or HAL_IRDA_Init() function.
00178 
00179     [..]
00180     When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or
00181     not defined, the callback registration feature is not available
00182     and weak (surcharged) callbacks are used.
00183 
00184   @endverbatim
00185   ******************************************************************************
00186   */
00187 
00188 /* Includes ------------------------------------------------------------------*/
00189 #include "stm32l4xx_hal.h"
00190 
00191 /** @addtogroup STM32L4xx_HAL_Driver
00192   * @{
00193   */
00194 
00195 /** @defgroup IRDA IRDA
00196   * @brief HAL IRDA module driver
00197   * @{
00198   */
00199 
00200 #ifdef HAL_IRDA_MODULE_ENABLED
00201 
00202 /* Private typedef -----------------------------------------------------------*/
00203 /* Private define ------------------------------------------------------------*/
00204 /** @defgroup IRDA_Private_Constants IRDA Private Constants
00205   * @{
00206   */
00207 #define IRDA_TEACK_REACK_TIMEOUT            1000U                                   /*!< IRDA TX or RX enable acknowledge time-out value  */
00208 
00209 #define IRDA_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
00210                                      | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))  /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */
00211 
00212 #define USART_BRR_MIN    0x10U        /*!< USART BRR minimum authorized value */
00213 
00214 #define USART_BRR_MAX    0x0000FFFFU  /*!< USART BRR maximum authorized value */
00215 /**
00216   * @}
00217   */
00218 
00219 /* Private macros ------------------------------------------------------------*/
00220 /** @defgroup IRDA_Private_Macros IRDA Private Macros
00221   * @{
00222   */
00223 #if defined(USART_PRESC_PRESCALER)
00224 /** @brief  BRR division operation to set BRR register in 16-bit oversampling mode.
00225   * @param  __PCLK__ IRDA clock source.
00226   * @param  __BAUD__ Baud rate set by the user.
00227   * @param  __PRESCALER__ IRDA clock prescaler value.
00228   * @retval Division result
00229   */
00230 #define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__, __PRESCALER__)  ((((__PCLK__)/IRDAPrescTable[(__PRESCALER__)])\
00231                                                                   + ((__BAUD__)/2U)) / (__BAUD__))
00232 #else
00233 /** @brief  BRR division operation to set BRR register in 16-bit oversampling mode.
00234   * @param  __PCLK__ IRDA clock source.
00235   * @param  __BAUD__ Baud rate set by the user.
00236   * @retval Division result
00237   */
00238 #define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__)  (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__))
00239 #endif /* USART_PRESC_PRESCALER */
00240 /**
00241   * @}
00242   */
00243 
00244 /* Private variables ---------------------------------------------------------*/
00245 /* Private function prototypes -----------------------------------------------*/
00246 /** @addtogroup IRDA_Private_Functions
00247   * @{
00248   */
00249 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
00250 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda);
00251 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
00252 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
00253 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
00254 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
00255                                                      uint32_t Tickstart, uint32_t Timeout);
00256 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
00257 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
00258 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00259 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
00260 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00261 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
00262 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
00263 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
00264 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
00265 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
00266 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
00267 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
00268 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
00269 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
00270 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
00271 /**
00272   * @}
00273   */
00274 
00275 /* Exported functions --------------------------------------------------------*/
00276 
00277 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions
00278   * @{
00279   */
00280 
00281 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
00282   *  @brief    Initialization and Configuration functions
00283   *
00284 @verbatim
00285   ==============================================================================
00286               ##### Initialization and Configuration functions #####
00287   ==============================================================================
00288   [..]
00289   This subsection provides a set of functions allowing to initialize the USARTx
00290   in asynchronous IRDA mode.
00291   (+) For the asynchronous mode only these parameters can be configured:
00292       (++) Baud Rate
00293       (++) Word Length
00294       (++) Parity: If the parity is enabled, then the MSB bit of the data written
00295            in the data register is transmitted but is changed by the parity bit.
00296       (++) Power mode
00297       (++) Prescaler setting
00298       (++) Receiver/transmitter modes
00299 
00300   [..]
00301   The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
00302   (details for the procedures are available in reference manual).
00303 
00304 @endverbatim
00305 
00306   Depending on the frame length defined by the M1 and M0 bits (7-bit,
00307   8-bit or 9-bit), the possible IRDA frame formats are listed in the
00308   following table.
00309 
00310     Table 1. IRDA frame format.
00311     +-----------------------------------------------------------------------+
00312     |  M1 bit |  M0 bit |  PCE bit  |             IRDA frame                |
00313     |---------|---------|-----------|---------------------------------------|
00314     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
00315     |---------|---------|-----------|---------------------------------------|
00316     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
00317     |---------|---------|-----------|---------------------------------------|
00318     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
00319     |---------|---------|-----------|---------------------------------------|
00320     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
00321     |---------|---------|-----------|---------------------------------------|
00322     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
00323     |---------|---------|-----------|---------------------------------------|
00324     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
00325     +-----------------------------------------------------------------------+
00326 
00327   * @{
00328   */
00329 
00330 /**
00331   * @brief Initialize the IRDA mode according to the specified
00332   *        parameters in the IRDA_InitTypeDef and initialize the associated handle.
00333   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
00334   *               the configuration information for the specified IRDA module.
00335   * @retval HAL status
00336   */
00337 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
00338 {
00339   /* Check the IRDA handle allocation */
00340   if (hirda == NULL)
00341   {
00342     return HAL_ERROR;
00343   }
00344 
00345   /* Check the USART/UART associated to the IRDA handle */
00346   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00347 
00348   if (hirda->gState == HAL_IRDA_STATE_RESET)
00349   {
00350     /* Allocate lock resource and initialize it */
00351     hirda->Lock = HAL_UNLOCKED;
00352 
00353 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
00354     IRDA_InitCallbacksToDefault(hirda);
00355 
00356     if (hirda->MspInitCallback == NULL)
00357     {
00358       hirda->MspInitCallback = HAL_IRDA_MspInit;
00359     }
00360 
00361     /* Init the low level hardware */
00362     hirda->MspInitCallback(hirda);
00363 #else
00364     /* Init the low level hardware : GPIO, CLOCK */
00365     HAL_IRDA_MspInit(hirda);
00366 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
00367   }
00368 
00369   hirda->gState = HAL_IRDA_STATE_BUSY;
00370 
00371   /* Disable the Peripheral to update the configuration registers */
00372   __HAL_IRDA_DISABLE(hirda);
00373 
00374   /* Set the IRDA Communication parameters */
00375   if (IRDA_SetConfig(hirda) == HAL_ERROR)
00376   {
00377     return HAL_ERROR;
00378   }
00379 
00380   /* In IRDA mode, the following bits must be kept cleared:
00381   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
00382   - SCEN and HDSEL bits in the USART_CR3 register.*/
00383   CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
00384   CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
00385 
00386   /* set the UART/USART in IRDA mode */
00387   hirda->Instance->CR3 |= USART_CR3_IREN;
00388 
00389   /* Enable the Peripheral */
00390   __HAL_IRDA_ENABLE(hirda);
00391 
00392   /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */
00393   return (IRDA_CheckIdleState(hirda));
00394 }
00395 
00396 /**
00397   * @brief DeInitialize the IRDA peripheral.
00398   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
00399   *               the configuration information for the specified IRDA module.
00400   * @retval HAL status
00401   */
00402 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
00403 {
00404   /* Check the IRDA handle allocation */
00405   if (hirda == NULL)
00406   {
00407     return HAL_ERROR;
00408   }
00409 
00410   /* Check the USART/UART associated to the IRDA handle */
00411   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00412 
00413   hirda->gState = HAL_IRDA_STATE_BUSY;
00414 
00415   /* DeInit the low level hardware */
00416 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
00417   if (hirda->MspDeInitCallback == NULL)
00418   {
00419     hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
00420   }
00421   /* DeInit the low level hardware */
00422   hirda->MspDeInitCallback(hirda);
00423 #else
00424   HAL_IRDA_MspDeInit(hirda);
00425 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
00426   /* Disable the Peripheral */
00427   __HAL_IRDA_DISABLE(hirda);
00428 
00429   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00430   hirda->gState    = HAL_IRDA_STATE_RESET;
00431   hirda->RxState   = HAL_IRDA_STATE_RESET;
00432 
00433   /* Process Unlock */
00434   __HAL_UNLOCK(hirda);
00435 
00436   return HAL_OK;
00437 }
00438 
00439 /**
00440   * @brief Initialize the IRDA MSP.
00441   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
00442   *               the configuration information for the specified IRDA module.
00443   * @retval None
00444   */
00445 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
00446 {
00447   /* Prevent unused argument(s) compilation warning */
00448   UNUSED(hirda);
00449 
00450   /* NOTE: This function should not be modified, when the callback is needed,
00451            the HAL_IRDA_MspInit can be implemented in the user file
00452    */
00453 }
00454 
00455 /**
00456   * @brief DeInitialize the IRDA MSP.
00457   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
00458   *               the configuration information for the specified IRDA module.
00459   * @retval None
00460   */
00461 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
00462 {
00463   /* Prevent unused argument(s) compilation warning */
00464   UNUSED(hirda);
00465 
00466   /* NOTE: This function should not be modified, when the callback is needed,
00467            the HAL_IRDA_MspDeInit can be implemented in the user file
00468    */
00469 }
00470 
00471 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
00472 /**
00473   * @brief  Register a User IRDA Callback
00474   *         To be used instead of the weak predefined callback
00475   * @param  hirda irda handle
00476   * @param  CallbackID ID of the callback to be registered
00477   *         This parameter can be one of the following values:
00478   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
00479   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
00480   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
00481   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
00482   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
00483   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
00484   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
00485   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
00486   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
00487   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
00488   * @param  pCallback pointer to the Callback function
00489   * @retval HAL status
00490   */
00491 HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID,
00492                                             pIRDA_CallbackTypeDef pCallback)
00493 {
00494   HAL_StatusTypeDef status = HAL_OK;
00495 
00496   if (pCallback == NULL)
00497   {
00498     /* Update the error code */
00499     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00500 
00501     return HAL_ERROR;
00502   }
00503   /* Process locked */
00504   __HAL_LOCK(hirda);
00505 
00506   if (hirda->gState == HAL_IRDA_STATE_READY)
00507   {
00508     switch (CallbackID)
00509     {
00510       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
00511         hirda->TxHalfCpltCallback = pCallback;
00512         break;
00513 
00514       case HAL_IRDA_TX_COMPLETE_CB_ID :
00515         hirda->TxCpltCallback = pCallback;
00516         break;
00517 
00518       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
00519         hirda->RxHalfCpltCallback = pCallback;
00520         break;
00521 
00522       case HAL_IRDA_RX_COMPLETE_CB_ID :
00523         hirda->RxCpltCallback = pCallback;
00524         break;
00525 
00526       case HAL_IRDA_ERROR_CB_ID :
00527         hirda->ErrorCallback = pCallback;
00528         break;
00529 
00530       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
00531         hirda->AbortCpltCallback = pCallback;
00532         break;
00533 
00534       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
00535         hirda->AbortTransmitCpltCallback = pCallback;
00536         break;
00537 
00538       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
00539         hirda->AbortReceiveCpltCallback = pCallback;
00540         break;
00541 
00542       case HAL_IRDA_MSPINIT_CB_ID :
00543         hirda->MspInitCallback = pCallback;
00544         break;
00545 
00546       case HAL_IRDA_MSPDEINIT_CB_ID :
00547         hirda->MspDeInitCallback = pCallback;
00548         break;
00549 
00550       default :
00551         /* Update the error code */
00552         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00553 
00554         /* Return error status */
00555         status =  HAL_ERROR;
00556         break;
00557     }
00558   }
00559   else if (hirda->gState == HAL_IRDA_STATE_RESET)
00560   {
00561     switch (CallbackID)
00562     {
00563       case HAL_IRDA_MSPINIT_CB_ID :
00564         hirda->MspInitCallback = pCallback;
00565         break;
00566 
00567       case HAL_IRDA_MSPDEINIT_CB_ID :
00568         hirda->MspDeInitCallback = pCallback;
00569         break;
00570 
00571       default :
00572         /* Update the error code */
00573         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00574 
00575         /* Return error status */
00576         status =  HAL_ERROR;
00577         break;
00578     }
00579   }
00580   else
00581   {
00582     /* Update the error code */
00583     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00584 
00585     /* Return error status */
00586     status =  HAL_ERROR;
00587   }
00588 
00589   /* Release Lock */
00590   __HAL_UNLOCK(hirda);
00591 
00592   return status;
00593 }
00594 
00595 /**
00596   * @brief  Unregister an IRDA callback
00597   *         IRDA callback is redirected to the weak predefined callback
00598   * @param  hirda irda handle
00599   * @param  CallbackID ID of the callback to be unregistered
00600   *         This parameter can be one of the following values:
00601   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
00602   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
00603   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
00604   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
00605   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
00606   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
00607   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
00608   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
00609   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
00610   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
00611   * @retval HAL status
00612   */
00613 HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID)
00614 {
00615   HAL_StatusTypeDef status = HAL_OK;
00616 
00617   /* Process locked */
00618   __HAL_LOCK(hirda);
00619 
00620   if (HAL_IRDA_STATE_READY == hirda->gState)
00621   {
00622     switch (CallbackID)
00623     {
00624       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
00625         hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback    */
00626         break;
00627 
00628       case HAL_IRDA_TX_COMPLETE_CB_ID :
00629         hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback;                       /* Legacy weak TxCpltCallback         */
00630         break;
00631 
00632       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
00633         hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback     */
00634         break;
00635 
00636       case HAL_IRDA_RX_COMPLETE_CB_ID :
00637         hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback;                       /* Legacy weak RxCpltCallback         */
00638         break;
00639 
00640       case HAL_IRDA_ERROR_CB_ID :
00641         hirda->ErrorCallback = HAL_IRDA_ErrorCallback;                         /* Legacy weak ErrorCallback          */
00642         break;
00643 
00644       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
00645         hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback      */
00646         break;
00647 
00648       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
00649         hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak
00650                                                                                   AbortTransmitCpltCallback          */
00651         break;
00652 
00653       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
00654         hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback;   /* Legacy weak
00655                                                                                   AbortReceiveCpltCallback           */
00656         break;
00657 
00658       case HAL_IRDA_MSPINIT_CB_ID :
00659         hirda->MspInitCallback = HAL_IRDA_MspInit;                             /* Legacy weak MspInitCallback        */
00660         break;
00661 
00662       case HAL_IRDA_MSPDEINIT_CB_ID :
00663         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;                         /* Legacy weak MspDeInitCallback      */
00664         break;
00665 
00666       default :
00667         /* Update the error code */
00668         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00669 
00670         /* Return error status */
00671         status =  HAL_ERROR;
00672         break;
00673     }
00674   }
00675   else if (HAL_IRDA_STATE_RESET == hirda->gState)
00676   {
00677     switch (CallbackID)
00678     {
00679       case HAL_IRDA_MSPINIT_CB_ID :
00680         hirda->MspInitCallback = HAL_IRDA_MspInit;
00681         break;
00682 
00683       case HAL_IRDA_MSPDEINIT_CB_ID :
00684         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
00685         break;
00686 
00687       default :
00688         /* Update the error code */
00689         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00690 
00691         /* Return error status */
00692         status =  HAL_ERROR;
00693         break;
00694     }
00695   }
00696   else
00697   {
00698     /* Update the error code */
00699     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
00700 
00701     /* Return error status */
00702     status =  HAL_ERROR;
00703   }
00704 
00705   /* Release Lock */
00706   __HAL_UNLOCK(hirda);
00707 
00708   return status;
00709 }
00710 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
00711 
00712 /**
00713   * @}
00714   */
00715 
00716 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
00717   *  @brief   IRDA Transmit and Receive functions
00718   *
00719 @verbatim
00720  ===============================================================================
00721                          ##### IO operation functions #####
00722  ===============================================================================
00723   [..]
00724     This subsection provides a set of functions allowing to manage the IRDA data transfers.
00725 
00726   [..]
00727     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
00728     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
00729     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
00730     While receiving data, transmission should be avoided as the data to be transmitted
00731     could be corrupted.
00732 
00733   [..]
00734     (#) There are two modes of transfer:
00735         (++) Blocking mode: the communication is performed in polling mode.
00736              The HAL status of all data processing is returned by the same function
00737              after finishing transfer.
00738         (++) Non-Blocking mode: the communication is performed using Interrupts
00739              or DMA, these API's return the HAL status.
00740              The end of the data processing will be indicated through the
00741              dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
00742              using DMA mode.
00743              The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
00744              will be executed respectively at the end of the Transmit or Receive process
00745              The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
00746 
00747     (#) Blocking mode APIs are :
00748         (++) HAL_IRDA_Transmit()
00749         (++) HAL_IRDA_Receive()
00750 
00751     (#) Non Blocking mode APIs with Interrupt are :
00752         (++) HAL_IRDA_Transmit_IT()
00753         (++) HAL_IRDA_Receive_IT()
00754         (++) HAL_IRDA_IRQHandler()
00755 
00756     (#) Non Blocking mode functions with DMA are :
00757         (++) HAL_IRDA_Transmit_DMA()
00758         (++) HAL_IRDA_Receive_DMA()
00759         (++) HAL_IRDA_DMAPause()
00760         (++) HAL_IRDA_DMAResume()
00761         (++) HAL_IRDA_DMAStop()
00762 
00763     (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
00764         (++) HAL_IRDA_TxHalfCpltCallback()
00765         (++) HAL_IRDA_TxCpltCallback()
00766         (++) HAL_IRDA_RxHalfCpltCallback()
00767         (++) HAL_IRDA_RxCpltCallback()
00768         (++) HAL_IRDA_ErrorCallback()
00769 
00770     (#) Non-Blocking mode transfers could be aborted using Abort API's :
00771         (++) HAL_IRDA_Abort()
00772         (++) HAL_IRDA_AbortTransmit()
00773         (++) HAL_IRDA_AbortReceive()
00774         (++) HAL_IRDA_Abort_IT()
00775         (++) HAL_IRDA_AbortTransmit_IT()
00776         (++) HAL_IRDA_AbortReceive_IT()
00777 
00778     (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
00779         (++) HAL_IRDA_AbortCpltCallback()
00780         (++) HAL_IRDA_AbortTransmitCpltCallback()
00781         (++) HAL_IRDA_AbortReceiveCpltCallback()
00782 
00783     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
00784         Errors are handled as follows :
00785         (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
00786              to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
00787              in Interrupt mode reception .
00788              Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
00789              to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed.
00790              Transfer is kept ongoing on IRDA side.
00791              If user wants to abort it, Abort services should be called by user.
00792         (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
00793              This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
00794              Error code is set to allow user to identify error type, and
00795              HAL_IRDA_ErrorCallback() user callback is executed.
00796 
00797 @endverbatim
00798   * @{
00799   */
00800 
00801 /**
00802   * @brief Send an amount of data in blocking mode.
00803   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
00804   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
00805   *        of u16 available through pData.
00806   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
00807   *               the configuration information for the specified IRDA module.
00808   * @param pData Pointer to data buffer (u8 or u16 data elements).
00809   * @param Size Amount of data elements (u8 or u16) to be sent.
00810   * @param Timeout Specify timeout value.
00811   * @retval HAL status
00812   */
00813 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
00814 {
00815   const uint8_t  *pdata8bits;
00816   const uint16_t *pdata16bits;
00817   uint32_t tickstart;
00818 
00819   /* Check that a Tx process is not already ongoing */
00820   if (hirda->gState == HAL_IRDA_STATE_READY)
00821   {
00822     if ((pData == NULL) || (Size == 0U))
00823     {
00824       return  HAL_ERROR;
00825     }
00826 
00827     /* Process Locked */
00828     __HAL_LOCK(hirda);
00829 
00830     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00831     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00832 
00833     /* Init tickstart for timeout management */
00834     tickstart = HAL_GetTick();
00835 
00836     hirda->TxXferSize = Size;
00837     hirda->TxXferCount = Size;
00838 
00839     /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
00840     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00841     {
00842       pdata8bits  = NULL;
00843       pdata16bits = (const uint16_t *) pData; /* Derogation R.11.3 */
00844     }
00845     else
00846     {
00847       pdata8bits  = pData;
00848       pdata16bits = NULL;
00849     }
00850 
00851     while (hirda->TxXferCount > 0U)
00852     {
00853       hirda->TxXferCount--;
00854 
00855       if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
00856       {
00857         return HAL_TIMEOUT;
00858       }
00859       if (pdata8bits == NULL)
00860       {
00861         hirda->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
00862         pdata16bits++;
00863       }
00864       else
00865       {
00866         hirda->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
00867         pdata8bits++;
00868       }
00869     }
00870 
00871     if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00872     {
00873       return HAL_TIMEOUT;
00874     }
00875 
00876     /* At end of Tx process, restore hirda->gState to Ready */
00877     hirda->gState = HAL_IRDA_STATE_READY;
00878 
00879     /* Process Unlocked */
00880     __HAL_UNLOCK(hirda);
00881 
00882     return HAL_OK;
00883   }
00884   else
00885   {
00886     return HAL_BUSY;
00887   }
00888 }
00889 
00890 /**
00891   * @brief Receive an amount of data in blocking mode.
00892   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
00893   *        the received data is handled as a set of u16. In this case, Size must reflect the number
00894   *        of u16 available through pData.
00895   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
00896   *                the configuration information for the specified IRDA module.
00897   * @param pData Pointer to data buffer (u8 or u16 data elements).
00898   * @param Size Amount of data elements (u8 or u16) to be received.
00899   * @param Timeout Specify timeout value.
00900   * @retval HAL status
00901   */
00902 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00903 {
00904   uint8_t  *pdata8bits;
00905   uint16_t *pdata16bits;
00906   uint16_t uhMask;
00907   uint32_t tickstart;
00908 
00909   /* Check that a Rx process is not already ongoing */
00910   if (hirda->RxState == HAL_IRDA_STATE_READY)
00911   {
00912     if ((pData == NULL) || (Size == 0U))
00913     {
00914       return  HAL_ERROR;
00915     }
00916 
00917     /* Process Locked */
00918     __HAL_LOCK(hirda);
00919 
00920     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00921     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00922 
00923     /* Init tickstart for timeout management */
00924     tickstart = HAL_GetTick();
00925 
00926     hirda->RxXferSize = Size;
00927     hirda->RxXferCount = Size;
00928 
00929     /* Computation of the mask to apply to RDR register
00930        of the UART associated to the IRDA */
00931     IRDA_MASK_COMPUTATION(hirda);
00932     uhMask = hirda->Mask;
00933 
00934     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
00935     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00936     {
00937       pdata8bits  = NULL;
00938       pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */
00939     }
00940     else
00941     {
00942       pdata8bits  = pData;
00943       pdata16bits = NULL;
00944     }
00945 
00946     /* Check data remaining to be received */
00947     while (hirda->RxXferCount > 0U)
00948     {
00949       hirda->RxXferCount--;
00950 
00951       if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00952       {
00953         return HAL_TIMEOUT;
00954       }
00955       if (pdata8bits == NULL)
00956       {
00957         *pdata16bits = (uint16_t)(hirda->Instance->RDR & uhMask);
00958         pdata16bits++;
00959       }
00960       else
00961       {
00962         *pdata8bits = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
00963         pdata8bits++;
00964       }
00965     }
00966 
00967     /* At end of Rx process, restore hirda->RxState to Ready */
00968     hirda->RxState = HAL_IRDA_STATE_READY;
00969 
00970     /* Process Unlocked */
00971     __HAL_UNLOCK(hirda);
00972 
00973     return HAL_OK;
00974   }
00975   else
00976   {
00977     return HAL_BUSY;
00978   }
00979 }
00980 
00981 /**
00982   * @brief Send an amount of data in interrupt mode.
00983   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
00984   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
00985   *        of u16 available through pData.
00986   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
00987   *                the configuration information for the specified IRDA module.
00988   * @param pData Pointer to data buffer (u8 or u16 data elements).
00989   * @param Size Amount of data elements (u8 or u16) to be sent.
00990   * @retval HAL status
00991   */
00992 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
00993 {
00994   /* Check that a Tx process is not already ongoing */
00995   if (hirda->gState == HAL_IRDA_STATE_READY)
00996   {
00997     if ((pData == NULL) || (Size == 0U))
00998     {
00999       return HAL_ERROR;
01000     }
01001 
01002     /* Process Locked */
01003     __HAL_LOCK(hirda);
01004 
01005     hirda->pTxBuffPtr = pData;
01006     hirda->TxXferSize = Size;
01007     hirda->TxXferCount = Size;
01008 
01009     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01010     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
01011 
01012     /* Process Unlocked */
01013     __HAL_UNLOCK(hirda);
01014 
01015     /* Enable the IRDA Transmit Data Register Empty Interrupt */
01016 #if defined(USART_CR1_FIFOEN)
01017     SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
01018 #else
01019     SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
01020 #endif /* USART_CR1_FIFOEN */
01021 
01022     return HAL_OK;
01023   }
01024   else
01025   {
01026     return HAL_BUSY;
01027   }
01028 }
01029 
01030 /**
01031   * @brief Receive an amount of data in interrupt mode.
01032   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
01033   *        the received data is handled as a set of u16. In this case, Size must reflect the number
01034   *        of u16 available through pData.
01035   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01036   *                the configuration information for the specified IRDA module.
01037   * @param pData Pointer to data buffer (u8 or u16 data elements).
01038   * @param Size Amount of data elements (u8 or u16) to be received.
01039   * @retval HAL status
01040   */
01041 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
01042 {
01043   /* Check that a Rx process is not already ongoing */
01044   if (hirda->RxState == HAL_IRDA_STATE_READY)
01045   {
01046     if ((pData == NULL) || (Size == 0U))
01047     {
01048       return HAL_ERROR;
01049     }
01050 
01051     /* Process Locked */
01052     __HAL_LOCK(hirda);
01053 
01054     hirda->pRxBuffPtr = pData;
01055     hirda->RxXferSize = Size;
01056     hirda->RxXferCount = Size;
01057 
01058     /* Computation of the mask to apply to the RDR register
01059        of the UART associated to the IRDA */
01060     IRDA_MASK_COMPUTATION(hirda);
01061 
01062     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01063     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
01064 
01065     /* Process Unlocked */
01066     __HAL_UNLOCK(hirda);
01067 
01068 #if defined(USART_CR1_FIFOEN)
01069     if (hirda->Init.Parity != IRDA_PARITY_NONE)
01070     {
01071       /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
01072       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
01073     }
01074     else
01075     {
01076       /* Enable the IRDA Data Register not empty Interrupts */
01077       SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
01078     }
01079 #else
01080     if (hirda->Init.Parity != IRDA_PARITY_NONE)
01081     { 
01082       /* Enable the IRDA Parity Error and Data Register not empty Interrupts */  
01083       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
01084     }
01085     else
01086     {
01087      /* Enable the IRDA Data Register not empty Interrupts */ 
01088      SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE); 
01089     }
01090 #endif /* USART_CR1_FIFOEN */
01091 
01092     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
01093     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01094 
01095     return HAL_OK;
01096   }
01097   else
01098   {
01099     return HAL_BUSY;
01100   }
01101 }
01102 
01103 /**
01104   * @brief Send an amount of data in DMA mode.
01105   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
01106   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
01107   *        of u16 available through pData.
01108   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
01109   *               the configuration information for the specified IRDA module.
01110   * @param pData pointer to data buffer (u8 or u16 data elements).
01111   * @param Size Amount of data elements (u8 or u16) to be sent.
01112   * @retval HAL status
01113   */
01114 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
01115 {
01116   /* Check that a Tx process is not already ongoing */
01117   if (hirda->gState == HAL_IRDA_STATE_READY)
01118   {
01119     if ((pData == NULL) || (Size == 0U))
01120     {
01121       return HAL_ERROR;
01122     }
01123 
01124     /* Process Locked */
01125     __HAL_LOCK(hirda);
01126 
01127     hirda->pTxBuffPtr = pData;
01128     hirda->TxXferSize = Size;
01129     hirda->TxXferCount = Size;
01130 
01131     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01132     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
01133 
01134     /* Set the IRDA DMA transfer complete callback */
01135     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
01136 
01137     /* Set the IRDA DMA half transfer complete callback */
01138     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
01139 
01140     /* Set the DMA error callback */
01141     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
01142 
01143     /* Set the DMA abort callback */
01144     hirda->hdmatx->XferAbortCallback = NULL;
01145 
01146     /* Enable the IRDA transmit DMA channel */
01147     if (HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, Size) == HAL_OK)
01148     {
01149       /* Clear the TC flag in the ICR register */
01150       __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
01151 
01152       /* Process Unlocked */
01153       __HAL_UNLOCK(hirda);
01154 
01155       /* Enable the DMA transfer for transmit request by setting the DMAT bit
01156          in the USART CR3 register */
01157       SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01158 
01159       return HAL_OK;
01160     }
01161     else
01162     {
01163       /* Set error code to DMA */
01164       hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01165 
01166       /* Process Unlocked */
01167       __HAL_UNLOCK(hirda);
01168 
01169       /* Restore hirda->gState to ready */
01170       hirda->gState = HAL_IRDA_STATE_READY;
01171 
01172       return HAL_ERROR;
01173     }
01174   }
01175   else
01176   {
01177     return HAL_BUSY;
01178   }
01179 }
01180 
01181 /**
01182   * @brief Receive an amount of data in DMA mode.
01183   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
01184   *        the received data is handled as a set of u16. In this case, Size must reflect the number
01185   *        of u16 available through pData.
01186   * @note   When the IRDA parity is enabled (PCE = 1), the received data contains
01187   *         the parity bit (MSB position).
01188   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
01189   *               the configuration information for the specified IRDA module.
01190   * @param pData Pointer to data buffer (u8 or u16 data elements).
01191   * @param Size Amount of data elements (u8 or u16) to be received.
01192   * @retval HAL status
01193   */
01194 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
01195 {
01196   /* Check that a Rx process is not already ongoing */
01197   if (hirda->RxState == HAL_IRDA_STATE_READY)
01198   {
01199     if ((pData == NULL) || (Size == 0U))
01200     {
01201       return HAL_ERROR;
01202     }
01203 
01204     /* Process Locked */
01205     __HAL_LOCK(hirda);
01206 
01207     hirda->pRxBuffPtr = pData;
01208     hirda->RxXferSize = Size;
01209 
01210     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01211     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
01212 
01213     /* Set the IRDA DMA transfer complete callback */
01214     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
01215 
01216     /* Set the IRDA DMA half transfer complete callback */
01217     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
01218 
01219     /* Set the DMA error callback */
01220     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
01221 
01222     /* Set the DMA abort callback */
01223     hirda->hdmarx->XferAbortCallback = NULL;
01224 
01225     /* Enable the DMA channel */
01226     if (HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, Size) == HAL_OK)
01227     {
01228       /* Process Unlocked */
01229       __HAL_UNLOCK(hirda);
01230 
01231       if (hirda->Init.Parity != IRDA_PARITY_NONE)
01232       {
01233         /* Enable the UART Parity Error Interrupt */
01234         SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
01235       }
01236 
01237       /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
01238       SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01239 
01240       /* Enable the DMA transfer for the receiver request by setting the DMAR bit
01241          in the USART CR3 register */
01242       SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01243 
01244       return HAL_OK;
01245     }
01246     else
01247     {
01248       /* Set error code to DMA */
01249       hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01250 
01251       /* Process Unlocked */
01252       __HAL_UNLOCK(hirda);
01253 
01254       /* Restore hirda->RxState to ready */
01255       hirda->RxState = HAL_IRDA_STATE_READY;
01256 
01257       return HAL_ERROR;
01258     }
01259   }
01260   else
01261   {
01262     return HAL_BUSY;
01263   }
01264 }
01265 
01266 
01267 /**
01268   * @brief Pause the DMA Transfer.
01269   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01270   *                the configuration information for the specified IRDA module.
01271   * @retval HAL status
01272   */
01273 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
01274 {
01275   /* Process Locked */
01276   __HAL_LOCK(hirda);
01277 
01278   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
01279   {
01280     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01281     {
01282       /* Disable the IRDA DMA Tx request */
01283       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01284     }
01285   }
01286   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
01287   {
01288     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01289     {
01290       /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
01291       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
01292       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01293 
01294       /* Disable the IRDA DMA Rx request */
01295       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01296     }
01297   }
01298 
01299   /* Process Unlocked */
01300   __HAL_UNLOCK(hirda);
01301 
01302   return HAL_OK;
01303 }
01304 
01305 /**
01306   * @brief Resume the DMA Transfer.
01307   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01308   *                the configuration information for the specified UART module.
01309   * @retval HAL status
01310   */
01311 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
01312 {
01313   /* Process Locked */
01314   __HAL_LOCK(hirda);
01315 
01316   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
01317   {
01318     /* Enable the IRDA DMA Tx request */
01319     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01320   }
01321   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
01322   {
01323     /* Clear the Overrun flag before resuming the Rx transfer*/
01324     __HAL_IRDA_CLEAR_OREFLAG(hirda);
01325 
01326     /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
01327     if (hirda->Init.Parity != IRDA_PARITY_NONE)
01328     {    
01329       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
01330     }
01331     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01332 
01333     /* Enable the IRDA DMA Rx request */
01334     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01335   }
01336 
01337   /* Process Unlocked */
01338   __HAL_UNLOCK(hirda);
01339 
01340   return HAL_OK;
01341 }
01342 
01343 /**
01344   * @brief Stop the DMA Transfer.
01345   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01346   *                the configuration information for the specified UART module.
01347   * @retval HAL status
01348   */
01349 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
01350 {
01351   /* The Lock is not implemented on this API to allow the user application
01352      to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
01353      HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback:
01354      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
01355      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
01356      the stream and the corresponding call back is executed. */
01357 
01358   /* Stop IRDA DMA Tx request if ongoing */
01359   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
01360   {
01361     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01362     {
01363       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01364 
01365       /* Abort the IRDA DMA Tx channel */
01366       if (hirda->hdmatx != NULL)
01367       {
01368         if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
01369         {
01370           if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
01371           {
01372             /* Set error code to DMA */
01373             hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01374 
01375             return HAL_TIMEOUT;
01376           }
01377         }
01378       }
01379 
01380       IRDA_EndTxTransfer(hirda);
01381     }
01382   }
01383 
01384   /* Stop IRDA DMA Rx request if ongoing */
01385   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
01386   {
01387     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01388     {
01389       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01390 
01391       /* Abort the IRDA DMA Rx channel */
01392       if (hirda->hdmarx != NULL)
01393       {
01394         if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
01395         {
01396           if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
01397           {
01398             /* Set error code to DMA */
01399             hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01400 
01401             return HAL_TIMEOUT;
01402           }
01403         }
01404       }
01405 
01406       IRDA_EndRxTransfer(hirda);
01407     }
01408   }
01409 
01410   return HAL_OK;
01411 }
01412 
01413 /**
01414   * @brief  Abort ongoing transfers (blocking mode).
01415   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01416   *               the configuration information for the specified UART module.
01417   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
01418   *         This procedure performs following operations :
01419   *           - Disable IRDA Interrupts (Tx and Rx)
01420   *           - Disable the DMA transfer in the peripheral register (if enabled)
01421   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
01422   *           - Set handle State to READY
01423   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
01424   * @retval HAL status
01425   */
01426 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
01427 {
01428   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01429 #if defined(USART_CR1_FIFOEN)
01430   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
01431                                    USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
01432 #else
01433   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
01434 #endif /* USART_CR1_FIFOEN */
01435   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01436 
01437   /* Disable the IRDA DMA Tx request if enabled */
01438   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01439   {
01440     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01441 
01442     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
01443     if (hirda->hdmatx != NULL)
01444     {
01445       /* Set the IRDA DMA Abort callback to Null.
01446          No call back execution at end of DMA abort procedure */
01447       hirda->hdmatx->XferAbortCallback = NULL;
01448 
01449       if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
01450       {
01451         if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
01452         {
01453           /* Set error code to DMA */
01454           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01455 
01456           return HAL_TIMEOUT;
01457         }
01458       }
01459     }
01460   }
01461 
01462   /* Disable the IRDA DMA Rx request if enabled */
01463   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01464   {
01465     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01466 
01467     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
01468     if (hirda->hdmarx != NULL)
01469     {
01470       /* Set the IRDA DMA Abort callback to Null.
01471          No call back execution at end of DMA abort procedure */
01472       hirda->hdmarx->XferAbortCallback = NULL;
01473 
01474       if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
01475       {
01476         if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
01477         {
01478           /* Set error code to DMA */
01479           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01480 
01481           return HAL_TIMEOUT;
01482         }
01483       }
01484     }
01485   }
01486 
01487   /* Reset Tx and Rx transfer counters */
01488   hirda->TxXferCount = 0U;
01489   hirda->RxXferCount = 0U;
01490 
01491   /* Clear the Error flags in the ICR register */
01492   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
01493 
01494   /* Restore hirda->gState and hirda->RxState to Ready */
01495   hirda->gState  = HAL_IRDA_STATE_READY;
01496   hirda->RxState = HAL_IRDA_STATE_READY;
01497 
01498   /* Reset Handle ErrorCode to No Error */
01499   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01500 
01501   return HAL_OK;
01502 }
01503 
01504 /**
01505   * @brief  Abort ongoing Transmit transfer (blocking mode).
01506   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01507   *               the configuration information for the specified UART module.
01508   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
01509   *         This procedure performs following operations :
01510   *           - Disable IRDA Interrupts (Tx)
01511   *           - Disable the DMA transfer in the peripheral register (if enabled)
01512   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
01513   *           - Set handle State to READY
01514   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
01515   * @retval HAL status
01516   */
01517 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
01518 {
01519   /* Disable TXEIE and TCIE interrupts */
01520 #if defined(USART_CR1_FIFOEN)
01521   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
01522 #else
01523   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
01524 #endif /* USART_CR1_FIFOEN */
01525 
01526   /* Disable the IRDA DMA Tx request if enabled */
01527   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01528   {
01529     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01530 
01531     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
01532     if (hirda->hdmatx != NULL)
01533     {
01534       /* Set the IRDA DMA Abort callback to Null.
01535          No call back execution at end of DMA abort procedure */
01536       hirda->hdmatx->XferAbortCallback = NULL;
01537 
01538       if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
01539       {
01540         if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
01541         {
01542           /* Set error code to DMA */
01543           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01544 
01545           return HAL_TIMEOUT;
01546         }
01547       }
01548     }
01549   }
01550 
01551   /* Reset Tx transfer counter */
01552   hirda->TxXferCount = 0U;
01553 
01554   /* Restore hirda->gState to Ready */
01555   hirda->gState = HAL_IRDA_STATE_READY;
01556 
01557   return HAL_OK;
01558 }
01559 
01560 /**
01561   * @brief  Abort ongoing Receive transfer (blocking mode).
01562   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01563   *               the configuration information for the specified UART module.
01564   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
01565   *         This procedure performs following operations :
01566   *           - Disable IRDA Interrupts (Rx)
01567   *           - Disable the DMA transfer in the peripheral register (if enabled)
01568   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
01569   *           - Set handle State to READY
01570   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
01571   * @retval HAL status
01572   */
01573 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
01574 {
01575   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01576 #if defined(USART_CR1_FIFOEN)
01577   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
01578 #else
01579   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01580 #endif /* USART_CR1_FIFOEN */
01581   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01582 
01583   /* Disable the IRDA DMA Rx request if enabled */
01584   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01585   {
01586     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01587 
01588     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
01589     if (hirda->hdmarx != NULL)
01590     {
01591       /* Set the IRDA DMA Abort callback to Null.
01592          No call back execution at end of DMA abort procedure */
01593       hirda->hdmarx->XferAbortCallback = NULL;
01594 
01595       if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
01596       {
01597         if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
01598         {
01599           /* Set error code to DMA */
01600           hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
01601 
01602           return HAL_TIMEOUT;
01603         }
01604       }
01605     }
01606   }
01607 
01608   /* Reset Rx transfer counter */
01609   hirda->RxXferCount = 0U;
01610 
01611   /* Clear the Error flags in the ICR register */
01612   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
01613 
01614   /* Restore hirda->RxState to Ready */
01615   hirda->RxState = HAL_IRDA_STATE_READY;
01616 
01617   return HAL_OK;
01618 }
01619 
01620 /**
01621   * @brief  Abort ongoing transfers (Interrupt mode).
01622   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01623   *               the configuration information for the specified UART module.
01624   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
01625   *         This procedure performs following operations :
01626   *           - Disable IRDA Interrupts (Tx and Rx)
01627   *           - Disable the DMA transfer in the peripheral register (if enabled)
01628   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01629   *           - Set handle State to READY
01630   *           - At abort completion, call user abort complete callback
01631   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01632   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01633   * @retval HAL status
01634   */
01635 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
01636 {
01637   uint32_t abortcplt = 1U;
01638 
01639   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01640 #if defined(USART_CR1_FIFOEN)
01641   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
01642                                    USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
01643 #else
01644   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
01645 #endif /* USART_CR1_FIFOEN */
01646   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01647 
01648   /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
01649      before any call to DMA Abort functions */
01650   /* DMA Tx Handle is valid */
01651   if (hirda->hdmatx != NULL)
01652   {
01653     /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
01654        Otherwise, set it to NULL */
01655     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01656     {
01657       hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
01658     }
01659     else
01660     {
01661       hirda->hdmatx->XferAbortCallback = NULL;
01662     }
01663   }
01664   /* DMA Rx Handle is valid */
01665   if (hirda->hdmarx != NULL)
01666   {
01667     /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
01668        Otherwise, set it to NULL */
01669     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01670     {
01671       hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
01672     }
01673     else
01674     {
01675       hirda->hdmarx->XferAbortCallback = NULL;
01676     }
01677   }
01678 
01679   /* Disable the IRDA DMA Tx request if enabled */
01680   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01681   {
01682     /* Disable DMA Tx at UART level */
01683     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01684 
01685     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
01686     if (hirda->hdmatx != NULL)
01687     {
01688       /* IRDA Tx DMA Abort callback has already been initialised :
01689          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01690 
01691       /* Abort DMA TX */
01692       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
01693       {
01694         hirda->hdmatx->XferAbortCallback = NULL;
01695       }
01696       else
01697       {
01698         abortcplt = 0U;
01699       }
01700     }
01701   }
01702 
01703   /* Disable the IRDA DMA Rx request if enabled */
01704   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01705   {
01706     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01707 
01708     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
01709     if (hirda->hdmarx != NULL)
01710     {
01711       /* IRDA Rx DMA Abort callback has already been initialised :
01712          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01713 
01714       /* Abort DMA RX */
01715       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
01716       {
01717         hirda->hdmarx->XferAbortCallback = NULL;
01718         abortcplt = 1U;
01719       }
01720       else
01721       {
01722         abortcplt = 0U;
01723       }
01724     }
01725   }
01726 
01727   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
01728   if (abortcplt == 1U)
01729   {
01730     /* Reset Tx and Rx transfer counters */
01731     hirda->TxXferCount = 0U;
01732     hirda->RxXferCount = 0U;
01733 
01734     /* Reset errorCode */
01735     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01736 
01737     /* Clear the Error flags in the ICR register */
01738     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
01739 
01740     /* Restore hirda->gState and hirda->RxState to Ready */
01741     hirda->gState  = HAL_IRDA_STATE_READY;
01742     hirda->RxState = HAL_IRDA_STATE_READY;
01743 
01744     /* As no DMA to be aborted, call directly user Abort complete callback */
01745 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
01746     /* Call registered Abort complete callback */
01747     hirda->AbortCpltCallback(hirda);
01748 #else
01749     /* Call legacy weak Abort complete callback */
01750     HAL_IRDA_AbortCpltCallback(hirda);
01751 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
01752   }
01753 
01754   return HAL_OK;
01755 }
01756 
01757 /**
01758   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
01759   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01760   *               the configuration information for the specified UART module.
01761   * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
01762   *         This procedure performs following operations :
01763   *           - Disable IRDA Interrupts (Tx)
01764   *           - Disable the DMA transfer in the peripheral register (if enabled)
01765   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01766   *           - Set handle State to READY
01767   *           - At abort completion, call user abort complete callback
01768   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01769   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01770   * @retval HAL status
01771   */
01772 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
01773 {
01774   /* Disable TXEIE and TCIE interrupts */
01775 #if defined(USART_CR1_FIFOEN)
01776   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
01777 #else
01778   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
01779 #endif /* USART_CR1_FIFOEN */
01780 
01781   /* Disable the IRDA DMA Tx request if enabled */
01782   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01783   {
01784     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01785 
01786     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
01787     if (hirda->hdmatx != NULL)
01788     {
01789       /* Set the IRDA DMA Abort callback :
01790          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01791       hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
01792 
01793       /* Abort DMA TX */
01794       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
01795       {
01796         /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
01797         hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
01798       }
01799     }
01800     else
01801     {
01802       /* Reset Tx transfer counter */
01803       hirda->TxXferCount = 0U;
01804 
01805       /* Restore hirda->gState to Ready */
01806       hirda->gState = HAL_IRDA_STATE_READY;
01807 
01808       /* As no DMA to be aborted, call directly user Abort complete callback */
01809 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
01810       /* Call registered Abort Transmit Complete Callback */
01811       hirda->AbortTransmitCpltCallback(hirda);
01812 #else
01813       /* Call legacy weak Abort Transmit Complete Callback */
01814       HAL_IRDA_AbortTransmitCpltCallback(hirda);
01815 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
01816     }
01817   }
01818   else
01819   {
01820     /* Reset Tx transfer counter */
01821     hirda->TxXferCount = 0U;
01822 
01823     /* Restore hirda->gState to Ready */
01824     hirda->gState = HAL_IRDA_STATE_READY;
01825 
01826     /* As no DMA to be aborted, call directly user Abort complete callback */
01827 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
01828     /* Call registered Abort Transmit Complete Callback */
01829     hirda->AbortTransmitCpltCallback(hirda);
01830 #else
01831     /* Call legacy weak Abort Transmit Complete Callback */
01832     HAL_IRDA_AbortTransmitCpltCallback(hirda);
01833 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
01834   }
01835 
01836   return HAL_OK;
01837 }
01838 
01839 /**
01840   * @brief  Abort ongoing Receive transfer (Interrupt mode).
01841   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01842   *               the configuration information for the specified UART module.
01843   * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
01844   *         This procedure performs following operations :
01845   *           - Disable IRDA Interrupts (Rx)
01846   *           - Disable the DMA transfer in the peripheral register (if enabled)
01847   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01848   *           - Set handle State to READY
01849   *           - At abort completion, call user abort complete callback
01850   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01851   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01852   * @retval HAL status
01853   */
01854 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
01855 {
01856   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01857 #if defined(USART_CR1_FIFOEN)
01858   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
01859 #else
01860   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01861 #endif /* USART_CR1_FIFOEN */
01862   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01863 
01864   /* Disable the IRDA DMA Rx request if enabled */
01865   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01866   {
01867     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01868 
01869     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
01870     if (hirda->hdmarx != NULL)
01871     {
01872       /* Set the IRDA DMA Abort callback :
01873          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01874       hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
01875 
01876       /* Abort DMA RX */
01877       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
01878       {
01879         /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
01880         hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
01881       }
01882     }
01883     else
01884     {
01885       /* Reset Rx transfer counter */
01886       hirda->RxXferCount = 0U;
01887 
01888       /* Clear the Error flags in the ICR register */
01889       __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
01890 
01891       /* Restore hirda->RxState to Ready */
01892       hirda->RxState = HAL_IRDA_STATE_READY;
01893 
01894       /* As no DMA to be aborted, call directly user Abort complete callback */
01895 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
01896       /* Call registered Abort Receive Complete Callback */
01897       hirda->AbortReceiveCpltCallback(hirda);
01898 #else
01899       /* Call legacy weak Abort Receive Complete Callback */
01900       HAL_IRDA_AbortReceiveCpltCallback(hirda);
01901 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
01902     }
01903   }
01904   else
01905   {
01906     /* Reset Rx transfer counter */
01907     hirda->RxXferCount = 0U;
01908 
01909     /* Clear the Error flags in the ICR register */
01910     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
01911 
01912     /* Restore hirda->RxState to Ready */
01913     hirda->RxState = HAL_IRDA_STATE_READY;
01914 
01915     /* As no DMA to be aborted, call directly user Abort complete callback */
01916 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
01917     /* Call registered Abort Receive Complete Callback */
01918     hirda->AbortReceiveCpltCallback(hirda);
01919 #else
01920     /* Call legacy weak Abort Receive Complete Callback */
01921     HAL_IRDA_AbortReceiveCpltCallback(hirda);
01922 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
01923   }
01924 
01925   return HAL_OK;
01926 }
01927 
01928 /**
01929   * @brief Handle IRDA interrupt request.
01930   * @param hirda  Pointer to a IRDA_HandleTypeDef structure that contains
01931   *               the configuration information for the specified IRDA module.
01932   * @retval None
01933   */
01934 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
01935 {
01936   uint32_t isrflags   = READ_REG(hirda->Instance->ISR);
01937   uint32_t cr1its     = READ_REG(hirda->Instance->CR1);
01938   uint32_t cr3its;
01939   uint32_t errorflags;
01940   uint32_t errorcode;
01941 
01942   /* If no error occurs */
01943   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
01944   if (errorflags == 0U)
01945   {
01946     /* IRDA in mode Receiver ---------------------------------------------------*/
01947 #if defined(USART_CR1_FIFOEN)
01948     if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
01949 #else
01950     if (((isrflags & USART_ISR_RXNE) != 0U) && ((cr1its & USART_CR1_RXNEIE) != 0U))
01951 #endif /* USART_CR1_FIFOEN */
01952     {
01953       IRDA_Receive_IT(hirda);
01954       return;
01955     }
01956   }
01957 
01958   /* If some errors occur */
01959   cr3its = READ_REG(hirda->Instance->CR3);
01960   if ((errorflags != 0U)
01961       && (((cr3its & USART_CR3_EIE) != 0U)
01962 #if defined(USART_CR1_FIFOEN)
01963           || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
01964 #else
01965           || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != 0U)))
01966 #endif /* USART_CR1_FIFOEN */
01967   {
01968     /* IRDA parity error interrupt occurred -------------------------------------*/
01969     if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
01970     {
01971       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
01972 
01973       hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
01974     }
01975 
01976     /* IRDA frame error interrupt occurred --------------------------------------*/
01977     if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
01978     {
01979       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
01980 
01981       hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
01982     }
01983 
01984     /* IRDA noise error interrupt occurred --------------------------------------*/
01985     if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
01986     {
01987       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
01988 
01989       hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
01990     }
01991 
01992     /* IRDA Over-Run interrupt occurred -----------------------------------------*/
01993     if (((isrflags & USART_ISR_ORE) != 0U) &&
01994 #if defined(USART_CR1_FIFOEN)
01995         (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U)))
01996 #else
01997         (((cr1its & USART_CR1_RXNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U)))
01998 #endif /* USART_CR1_FIFOEN */
01999     {
02000       __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
02001 
02002       hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
02003     }
02004 
02005     /* Call IRDA Error Call back function if need be --------------------------*/
02006     if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
02007     {
02008       /* IRDA in mode Receiver ---------------------------------------------------*/
02009 #if defined(USART_CR1_FIFOEN)
02010       if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
02011 #else
02012       if (((isrflags & USART_ISR_RXNE) != 0U) && ((cr1its & USART_CR1_RXNEIE) != 0U))
02013 #endif /* USART_CR1_FIFOEN */
02014       {
02015         IRDA_Receive_IT(hirda);
02016       }
02017 
02018       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
02019          consider error as blocking */
02020       errorcode = hirda->ErrorCode;
02021       if ((HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) ||
02022           ((errorcode & HAL_IRDA_ERROR_ORE) != 0U))
02023       {
02024         /* Blocking error : transfer is aborted
02025            Set the IRDA state ready to be able to start again the process,
02026            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
02027         IRDA_EndRxTransfer(hirda);
02028 
02029         /* Disable the IRDA DMA Rx request if enabled */
02030         if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
02031         {
02032           CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
02033 
02034           /* Abort the IRDA DMA Rx channel */
02035           if (hirda->hdmarx != NULL)
02036           {
02037             /* Set the IRDA DMA Abort callback :
02038                will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
02039             hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
02040 
02041             /* Abort DMA RX */
02042             if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
02043             {
02044               /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
02045               hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
02046             }
02047           }
02048           else
02049           {
02050 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02051             /* Call registered user error callback */
02052             hirda->ErrorCallback(hirda);
02053 #else
02054             /* Call legacy weak user error callback */
02055             HAL_IRDA_ErrorCallback(hirda);
02056 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02057           }
02058         }
02059         else
02060         {
02061 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02062           /* Call registered user error callback */
02063           hirda->ErrorCallback(hirda);
02064 #else
02065           /* Call legacy weak user error callback */
02066           HAL_IRDA_ErrorCallback(hirda);
02067 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02068         }
02069       }
02070       else
02071       {
02072         /* Non Blocking error : transfer could go on.
02073            Error is notified to user through user error callback */
02074 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02075         /* Call registered user error callback */
02076         hirda->ErrorCallback(hirda);
02077 #else
02078         /* Call legacy weak user error callback */
02079         HAL_IRDA_ErrorCallback(hirda);
02080 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02081         hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
02082       }
02083     }
02084     return;
02085 
02086   } /* End if some error occurs */
02087 
02088   /* IRDA in mode Transmitter ------------------------------------------------*/
02089 #if defined(USART_CR1_FIFOEN)
02090   if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) && ((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U))
02091 #else
02092   if (((isrflags & USART_ISR_TXE) != 0U) && ((cr1its & USART_CR1_TXEIE) != 0U))
02093 #endif /* USART_CR1_FIFOEN */
02094   {
02095     IRDA_Transmit_IT(hirda);
02096     return;
02097   }
02098 
02099   /* IRDA in mode Transmitter (transmission end) -----------------------------*/
02100   if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
02101   {
02102     IRDA_EndTransmit_IT(hirda);
02103     return;
02104   }
02105 
02106 }
02107 
02108 /**
02109   * @brief  Tx Transfer completed callback.
02110   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02111   *               the configuration information for the specified IRDA module.
02112   * @retval None
02113   */
02114 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
02115 {
02116   /* Prevent unused argument(s) compilation warning */
02117   UNUSED(hirda);
02118 
02119   /* NOTE : This function should not be modified, when the callback is needed,
02120             the HAL_IRDA_TxCpltCallback can be implemented in the user file.
02121    */
02122 }
02123 
02124 /**
02125   * @brief  Tx Half Transfer completed callback.
02126   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02127   *               the configuration information for the specified USART module.
02128   * @retval None
02129   */
02130 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
02131 {
02132   /* Prevent unused argument(s) compilation warning */
02133   UNUSED(hirda);
02134 
02135   /* NOTE : This function should not be modified, when the callback is needed,
02136             the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
02137    */
02138 }
02139 
02140 /**
02141   * @brief  Rx Transfer completed callback.
02142   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02143   *               the configuration information for the specified IRDA module.
02144   * @retval None
02145   */
02146 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
02147 {
02148   /* Prevent unused argument(s) compilation warning */
02149   UNUSED(hirda);
02150 
02151   /* NOTE : This function should not be modified, when the callback is needed,
02152             the HAL_IRDA_RxCpltCallback can be implemented in the user file.
02153    */
02154 }
02155 
02156 /**
02157   * @brief  Rx Half Transfer complete callback.
02158   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02159   *               the configuration information for the specified IRDA module.
02160   * @retval None
02161   */
02162 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
02163 {
02164   /* Prevent unused argument(s) compilation warning */
02165   UNUSED(hirda);
02166 
02167   /* NOTE : This function should not be modified, when the callback is needed,
02168             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
02169    */
02170 }
02171 
02172 /**
02173   * @brief  IRDA error callback.
02174   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02175   *               the configuration information for the specified IRDA module.
02176   * @retval None
02177   */
02178 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
02179 {
02180   /* Prevent unused argument(s) compilation warning */
02181   UNUSED(hirda);
02182 
02183   /* NOTE : This function should not be modified, when the callback is needed,
02184             the HAL_IRDA_ErrorCallback can be implemented in the user file.
02185    */
02186 }
02187 
02188 /**
02189   * @brief  IRDA Abort Complete callback.
02190   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02191   *               the configuration information for the specified IRDA module.
02192   * @retval None
02193   */
02194 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
02195 {
02196   /* Prevent unused argument(s) compilation warning */
02197   UNUSED(hirda);
02198 
02199   /* NOTE : This function should not be modified, when the callback is needed,
02200             the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
02201    */
02202 }
02203 
02204 /**
02205   * @brief  IRDA Abort Complete callback.
02206   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02207   *               the configuration information for the specified IRDA module.
02208   * @retval None
02209   */
02210 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
02211 {
02212   /* Prevent unused argument(s) compilation warning */
02213   UNUSED(hirda);
02214 
02215   /* NOTE : This function should not be modified, when the callback is needed,
02216             the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
02217    */
02218 }
02219 
02220 /**
02221   * @brief  IRDA Abort Receive Complete callback.
02222   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02223   *               the configuration information for the specified IRDA module.
02224   * @retval None
02225   */
02226 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
02227 {
02228   /* Prevent unused argument(s) compilation warning */
02229   UNUSED(hirda);
02230 
02231   /* NOTE : This function should not be modified, when the callback is needed,
02232             the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
02233    */
02234 }
02235 
02236 /**
02237   * @}
02238   */
02239 
02240 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
02241   *  @brief   IRDA State and Errors functions
02242   *
02243 @verbatim
02244   ==============================================================================
02245             ##### Peripheral State and Error functions #####
02246   ==============================================================================
02247   [..]
02248     This subsection provides a set of functions allowing to return the State of IrDA
02249     communication process and also return Peripheral Errors occurred during communication process
02250      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
02251          of the IRDA peripheral handle.
02252      (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
02253          communication.
02254 
02255 @endverbatim
02256   * @{
02257   */
02258 
02259 /**
02260   * @brief Return the IRDA handle state.
02261   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
02262   *                the configuration information for the specified IRDA module.
02263   * @retval HAL state
02264   */
02265 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
02266 {
02267   /* Return IRDA handle state */
02268   uint32_t temp1;
02269   uint32_t temp2;
02270   temp1 = (uint32_t)hirda->gState;
02271   temp2 = (uint32_t)hirda->RxState;
02272 
02273   return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
02274 }
02275 
02276 /**
02277   * @brief Return the IRDA handle error code.
02278   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
02279   *               the configuration information for the specified IRDA module.
02280   * @retval IRDA Error Code
02281   */
02282 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
02283 {
02284   return hirda->ErrorCode;
02285 }
02286 
02287 /**
02288   * @}
02289   */
02290 
02291 /**
02292   * @}
02293   */
02294 
02295 /** @defgroup IRDA_Private_Functions IRDA Private Functions
02296   * @{
02297   */
02298 
02299 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02300 /**
02301   * @brief  Initialize the callbacks to their default values.
02302   * @param  hirda IRDA handle.
02303   * @retval none
02304   */
02305 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
02306 {
02307   /* Init the IRDA Callback settings */
02308   hirda->TxHalfCpltCallback        = HAL_IRDA_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
02309   hirda->TxCpltCallback            = HAL_IRDA_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
02310   hirda->RxHalfCpltCallback        = HAL_IRDA_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
02311   hirda->RxCpltCallback            = HAL_IRDA_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
02312   hirda->ErrorCallback             = HAL_IRDA_ErrorCallback;             /* Legacy weak ErrorCallback             */
02313   hirda->AbortCpltCallback         = HAL_IRDA_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
02314   hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
02315   hirda->AbortReceiveCpltCallback  = HAL_IRDA_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
02316 
02317 }
02318 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
02319 
02320 /**
02321   * @brief Configure the IRDA peripheral.
02322   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
02323   *               the configuration information for the specified IRDA module.
02324   * @retval HAL status
02325   */
02326 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
02327 {
02328   uint32_t tmpreg;
02329   IRDA_ClockSourceTypeDef clocksource;
02330   HAL_StatusTypeDef ret = HAL_OK;
02331 #if defined(USART_PRESC_PRESCALER)
02332   static const uint16_t IRDAPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
02333 #endif /* USART_PRESC_PRESCALER */
02334   uint32_t pclk;
02335 
02336   /* Check the communication parameters */
02337   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
02338   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
02339   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
02340   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
02341   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
02342   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
02343 #if defined(USART_PRESC_PRESCALER)
02344   assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler));
02345 #endif /* USART_PRESC_PRESCALER */
02346 
02347   /*-------------------------- USART CR1 Configuration -----------------------*/
02348   /* Configure the IRDA Word Length, Parity and transfer Mode:
02349      Set the M bits according to hirda->Init.WordLength value
02350      Set PCE and PS bits according to hirda->Init.Parity value
02351      Set TE and RE bits according to hirda->Init.Mode value */
02352   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
02353 
02354   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
02355 
02356   /*-------------------------- USART CR3 Configuration -----------------------*/
02357   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
02358 
02359 #if defined(USART_PRESC_PRESCALER)
02360   /*--------------------- USART clock PRESC Configuration ----------------*/
02361   /* Configure
02362   * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */
02363   MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler);
02364 #endif /* USART_PRESC_PRESCALER */
02365 
02366   /*-------------------------- USART GTPR Configuration ----------------------*/
02367   MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler);
02368 
02369   /*-------------------------- USART BRR Configuration -----------------------*/
02370   IRDA_GETCLOCKSOURCE(hirda, clocksource);
02371   tmpreg =   0U;
02372   switch (clocksource)
02373   {
02374     case IRDA_CLOCKSOURCE_PCLK1:
02375       pclk = HAL_RCC_GetPCLK1Freq();
02376 #if defined(USART_PRESC_PRESCALER)
02377       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
02378 #else
02379       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate));
02380 #endif /* USART_PRESC_PRESCALER */
02381       break;
02382     case IRDA_CLOCKSOURCE_PCLK2:
02383       pclk = HAL_RCC_GetPCLK2Freq();
02384 #if defined(USART_PRESC_PRESCALER)
02385       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
02386 #else
02387       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate));
02388 #endif /* USART_PRESC_PRESCALER */
02389       break;
02390     case IRDA_CLOCKSOURCE_HSI:
02391 #if defined(USART_PRESC_PRESCALER)
02392       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
02393 #else
02394       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate));
02395 #endif /* USART_PRESC_PRESCALER */
02396       break;
02397     case IRDA_CLOCKSOURCE_SYSCLK:
02398       pclk = HAL_RCC_GetSysClockFreq();
02399 #if defined(USART_PRESC_PRESCALER)
02400       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
02401 #else
02402       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate));
02403 #endif /* USART_PRESC_PRESCALER */
02404       break;
02405     case IRDA_CLOCKSOURCE_LSE:
02406 #if defined(USART_PRESC_PRESCALER)
02407       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
02408 #else
02409       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate));
02410 #endif /* USART_PRESC_PRESCALER */
02411       break;
02412     default:
02413       ret = HAL_ERROR;
02414       break;
02415   }
02416 
02417   /* USARTDIV must be greater than or equal to 0d16 */
02418   if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX))
02419   {
02420     hirda->Instance->BRR = (uint16_t)tmpreg;
02421   }
02422   else
02423   {
02424     ret = HAL_ERROR;
02425   }
02426 
02427   return ret;
02428 }
02429 
02430 /**
02431   * @brief Check the IRDA Idle State.
02432   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
02433   *               the configuration information for the specified IRDA module.
02434   * @retval HAL status
02435   */
02436 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
02437 {
02438   uint32_t tickstart;
02439 
02440   /* Initialize the IRDA ErrorCode */
02441   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
02442 
02443   /* Init tickstart for timeout management */
02444   tickstart = HAL_GetTick();
02445 
02446   /* Check if the Transmitter is enabled */
02447   if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
02448   {
02449     /* Wait until TEACK flag is set */
02450     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
02451     {
02452       /* Timeout occurred */
02453       return HAL_TIMEOUT;
02454     }
02455   }
02456   /* Check if the Receiver is enabled */
02457   if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
02458   {
02459     /* Wait until REACK flag is set */
02460     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
02461     {
02462       /* Timeout occurred */
02463       return HAL_TIMEOUT;
02464     }
02465   }
02466 
02467   /* Initialize the IRDA state*/
02468   hirda->gState  = HAL_IRDA_STATE_READY;
02469   hirda->RxState = HAL_IRDA_STATE_READY;
02470 
02471   /* Process Unlocked */
02472   __HAL_UNLOCK(hirda);
02473 
02474   return HAL_OK;
02475 }
02476 
02477 /**
02478   * @brief  Handle IRDA Communication Timeout. It waits
02479   *         until a flag is no longer in the specified status.
02480   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02481   *               the configuration information for the specified IRDA module.
02482   * @param  Flag Specifies the IRDA flag to check.
02483   * @param  Status The actual Flag status (SET or RESET)
02484   * @param  Tickstart Tick start value
02485   * @param  Timeout Timeout duration
02486   * @retval HAL status
02487   */
02488 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
02489                                                      uint32_t Tickstart, uint32_t Timeout)
02490 {
02491   /* Wait until flag is set */
02492   while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
02493   {
02494     /* Check for the Timeout */
02495     if (Timeout != HAL_MAX_DELAY)
02496     {
02497       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
02498       {
02499         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
02500            interrupts for the interrupt process */
02501 #if defined(USART_CR1_FIFOEN)
02502         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
02503 #else
02504         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
02505 #endif /* USART_CR1_FIFOEN */
02506         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
02507 
02508         hirda->gState  = HAL_IRDA_STATE_READY;
02509         hirda->RxState = HAL_IRDA_STATE_READY;
02510 
02511         /* Process Unlocked */
02512         __HAL_UNLOCK(hirda);
02513         return HAL_TIMEOUT;
02514       }
02515     }
02516   }
02517   return HAL_OK;
02518 }
02519 
02520 
02521 /**
02522   * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
02523   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02524   *               the configuration information for the specified IRDA module.
02525   * @retval None
02526   */
02527 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
02528 {
02529   /* Disable TXEIE and TCIE interrupts */
02530 #if defined(USART_CR1_FIFOEN)
02531   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
02532 #else
02533   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
02534 #endif /* USART_CR1_FIFOEN */
02535 
02536   /* At end of Tx process, restore hirda->gState to Ready */
02537   hirda->gState = HAL_IRDA_STATE_READY;
02538 }
02539 
02540 
02541 /**
02542   * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
02543   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02544   *               the configuration information for the specified IRDA module.
02545   * @retval None
02546   */
02547 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
02548 {
02549   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
02550 #if defined(USART_CR1_FIFOEN)
02551   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
02552 #else
02553   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
02554 #endif /* USART_CR1_FIFOEN */
02555   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
02556 
02557   /* At end of Rx process, restore hirda->RxState to Ready */
02558   hirda->RxState = HAL_IRDA_STATE_READY;
02559 }
02560 
02561 
02562 /**
02563   * @brief  DMA IRDA transmit process complete callback.
02564   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
02565   *              the configuration information for the specified DMA module.
02566   * @retval None
02567   */
02568 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
02569 {
02570   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02571 
02572   /* DMA Normal mode */
02573   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
02574   {
02575     hirda->TxXferCount = 0U;
02576 
02577     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
02578        in the IRDA CR3 register */
02579     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
02580 
02581     /* Enable the IRDA Transmit Complete Interrupt */
02582     SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
02583   }
02584   /* DMA Circular mode */
02585   else
02586   {
02587 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02588     /* Call registered Tx complete callback */
02589     hirda->TxCpltCallback(hirda);
02590 #else
02591     /* Call legacy weak Tx complete callback */
02592     HAL_IRDA_TxCpltCallback(hirda);
02593 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02594   }
02595 
02596 }
02597 
02598 /**
02599   * @brief  DMA IRDA transmit process half complete callback.
02600   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
02601   *              the configuration information for the specified DMA module.
02602   * @retval None
02603   */
02604 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
02605 {
02606   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02607 
02608 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02609   /* Call registered Tx Half complete callback */
02610   hirda->TxHalfCpltCallback(hirda);
02611 #else
02612   /* Call legacy weak Tx complete callback */
02613   HAL_IRDA_TxHalfCpltCallback(hirda);
02614 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02615 }
02616 
02617 /**
02618   * @brief  DMA IRDA receive process complete callback.
02619   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
02620   *               the configuration information for the specified DMA module.
02621   * @retval None
02622   */
02623 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
02624 {
02625   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02626 
02627   /* DMA Normal mode */
02628   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
02629   {
02630     hirda->RxXferCount = 0U;
02631 
02632     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
02633     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
02634     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
02635 
02636     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
02637        in the IRDA CR3 register */
02638     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
02639 
02640     /* At end of Rx process, restore hirda->RxState to Ready */
02641     hirda->RxState = HAL_IRDA_STATE_READY;
02642   }
02643 
02644 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02645   /* Call registered Rx complete callback */
02646   hirda->RxCpltCallback(hirda);
02647 #else
02648   /* Call legacy weak Rx complete callback */
02649   HAL_IRDA_RxCpltCallback(hirda);
02650 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
02651 }
02652 
02653 /**
02654   * @brief DMA IRDA receive process half complete callback.
02655   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
02656   *              the configuration information for the specified DMA module.
02657   * @retval None
02658   */
02659 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
02660 {
02661   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02662 
02663 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02664   /*Call registered Rx Half complete callback*/
02665   hirda->RxHalfCpltCallback(hirda);
02666 #else
02667   /* Call legacy weak Rx Half complete callback */
02668   HAL_IRDA_RxHalfCpltCallback(hirda);
02669 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02670 }
02671 
02672 /**
02673   * @brief DMA IRDA communication error callback.
02674   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
02675   *              the configuration information for the specified DMA module.
02676   * @retval None
02677   */
02678 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
02679 {
02680   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02681 
02682   /* Stop IRDA DMA Tx request if ongoing */
02683   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
02684   {
02685     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
02686     {
02687       hirda->TxXferCount = 0U;
02688       IRDA_EndTxTransfer(hirda);
02689     }
02690   }
02691 
02692   /* Stop IRDA DMA Rx request if ongoing */
02693   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
02694   {
02695     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
02696     {
02697       hirda->RxXferCount = 0U;
02698       IRDA_EndRxTransfer(hirda);
02699     }
02700   }
02701 
02702   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
02703 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02704   /* Call registered user error callback */
02705   hirda->ErrorCallback(hirda);
02706 #else
02707   /* Call legacy weak user error callback */
02708   HAL_IRDA_ErrorCallback(hirda);
02709 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02710 }
02711 
02712 /**
02713   * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
02714   *         (To be called at end of DMA Abort procedure following error occurrence).
02715   * @param  hdma DMA handle.
02716   * @retval None
02717   */
02718 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
02719 {
02720   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02721   hirda->RxXferCount = 0U;
02722   hirda->TxXferCount = 0U;
02723 
02724 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02725   /* Call registered user error callback */
02726   hirda->ErrorCallback(hirda);
02727 #else
02728   /* Call legacy weak user error callback */
02729   HAL_IRDA_ErrorCallback(hirda);
02730 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02731 }
02732 
02733 /**
02734   * @brief  DMA IRDA Tx communication abort callback, when initiated by user
02735   *         (To be called at end of DMA Tx Abort procedure following user abort request).
02736   * @note   When this callback is executed, User Abort complete call back is called only if no
02737   *         Abort still ongoing for Rx DMA Handle.
02738   * @param  hdma DMA handle.
02739   * @retval None
02740   */
02741 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
02742 {
02743   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02744 
02745   hirda->hdmatx->XferAbortCallback = NULL;
02746 
02747   /* Check if an Abort process is still ongoing */
02748   if (hirda->hdmarx != NULL)
02749   {
02750     if (hirda->hdmarx->XferAbortCallback != NULL)
02751     {
02752       return;
02753     }
02754   }
02755 
02756   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
02757   hirda->TxXferCount = 0U;
02758   hirda->RxXferCount = 0U;
02759 
02760   /* Reset errorCode */
02761   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
02762 
02763   /* Clear the Error flags in the ICR register */
02764   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
02765 
02766   /* Restore hirda->gState and hirda->RxState to Ready */
02767   hirda->gState  = HAL_IRDA_STATE_READY;
02768   hirda->RxState = HAL_IRDA_STATE_READY;
02769 
02770   /* Call user Abort complete callback */
02771 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02772   /* Call registered Abort complete callback */
02773   hirda->AbortCpltCallback(hirda);
02774 #else
02775   /* Call legacy weak Abort complete callback */
02776   HAL_IRDA_AbortCpltCallback(hirda);
02777 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02778 }
02779 
02780 
02781 /**
02782   * @brief  DMA IRDA Rx communication abort callback, when initiated by user
02783   *         (To be called at end of DMA Rx Abort procedure following user abort request).
02784   * @note   When this callback is executed, User Abort complete call back is called only if no
02785   *         Abort still ongoing for Tx DMA Handle.
02786   * @param  hdma DMA handle.
02787   * @retval None
02788   */
02789 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
02790 {
02791   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02792 
02793   hirda->hdmarx->XferAbortCallback = NULL;
02794 
02795   /* Check if an Abort process is still ongoing */
02796   if (hirda->hdmatx != NULL)
02797   {
02798     if (hirda->hdmatx->XferAbortCallback != NULL)
02799     {
02800       return;
02801     }
02802   }
02803 
02804   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
02805   hirda->TxXferCount = 0U;
02806   hirda->RxXferCount = 0U;
02807 
02808   /* Reset errorCode */
02809   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
02810 
02811   /* Clear the Error flags in the ICR register */
02812   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
02813 
02814   /* Restore hirda->gState and hirda->RxState to Ready */
02815   hirda->gState  = HAL_IRDA_STATE_READY;
02816   hirda->RxState = HAL_IRDA_STATE_READY;
02817 
02818   /* Call user Abort complete callback */
02819 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02820   /* Call registered Abort complete callback */
02821   hirda->AbortCpltCallback(hirda);
02822 #else
02823   /* Call legacy weak Abort complete callback */
02824   HAL_IRDA_AbortCpltCallback(hirda);
02825 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02826 }
02827 
02828 
02829 /**
02830   * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
02831   *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
02832   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
02833   *         and leads to user Tx Abort Complete callback execution).
02834   * @param  hdma DMA handle.
02835   * @retval None
02836   */
02837 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
02838 {
02839   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
02840 
02841   hirda->TxXferCount = 0U;
02842 
02843   /* Restore hirda->gState to Ready */
02844   hirda->gState = HAL_IRDA_STATE_READY;
02845 
02846   /* Call user Abort complete callback */
02847 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02848   /* Call registered Abort Transmit Complete Callback */
02849   hirda->AbortTransmitCpltCallback(hirda);
02850 #else
02851   /* Call legacy weak Abort Transmit Complete Callback */
02852   HAL_IRDA_AbortTransmitCpltCallback(hirda);
02853 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02854 }
02855 
02856 /**
02857   * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
02858   *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
02859   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
02860   *         and leads to user Rx Abort Complete callback execution).
02861   * @param  hdma DMA handle.
02862   * @retval None
02863   */
02864 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
02865 {
02866   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02867 
02868   hirda->RxXferCount = 0U;
02869 
02870   /* Clear the Error flags in the ICR register */
02871   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
02872 
02873   /* Restore hirda->RxState to Ready */
02874   hirda->RxState = HAL_IRDA_STATE_READY;
02875 
02876   /* Call user Abort complete callback */
02877 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02878   /* Call registered Abort Receive Complete Callback */
02879   hirda->AbortReceiveCpltCallback(hirda);
02880 #else
02881   /* Call legacy weak Abort Receive Complete Callback */
02882   HAL_IRDA_AbortReceiveCpltCallback(hirda);
02883 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02884 }
02885 
02886 /**
02887   * @brief  Send an amount of data in interrupt mode.
02888   * @note   Function is called under interruption only, once
02889   *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
02890   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02891   *               the configuration information for the specified IRDA module.
02892   * @retval None
02893   */
02894 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
02895 {
02896   const uint16_t *tmp;
02897 
02898   /* Check that a Tx process is ongoing */
02899   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
02900   {
02901     if (hirda->TxXferCount == 0U)
02902     {
02903       /* Disable the IRDA Transmit Data Register Empty Interrupt */
02904 #if defined(USART_CR1_FIFOEN)
02905       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
02906 #else
02907       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
02908 #endif /* USART_CR1_FIFOEN */
02909 
02910       /* Enable the IRDA Transmit Complete Interrupt */
02911       SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
02912     }
02913     else
02914     {
02915       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
02916       {
02917         tmp = (const uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */
02918         hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
02919         hirda->pTxBuffPtr += 2U;
02920       }
02921       else
02922       {
02923         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU);
02924         hirda->pTxBuffPtr++;
02925       }
02926       hirda->TxXferCount--;
02927     }
02928   }
02929 }
02930 
02931 /**
02932   * @brief  Wrap up transmission in non-blocking mode.
02933   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02934   *               the configuration information for the specified IRDA module.
02935   * @retval None
02936   */
02937 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
02938 {
02939   /* Disable the IRDA Transmit Complete Interrupt */
02940   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
02941 
02942   /* Tx process is ended, restore hirda->gState to Ready */
02943   hirda->gState = HAL_IRDA_STATE_READY;
02944 
02945 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
02946   /* Call registered Tx complete callback */
02947   hirda->TxCpltCallback(hirda);
02948 #else
02949   /* Call legacy weak Tx complete callback */
02950   HAL_IRDA_TxCpltCallback(hirda);
02951 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
02952 }
02953 
02954 /**
02955   * @brief  Receive an amount of data in interrupt mode.
02956   * @note   Function is called under interruption only, once
02957   *         interruptions have been enabled by HAL_IRDA_Receive_IT()
02958   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
02959   *               the configuration information for the specified IRDA module.
02960   * @retval None
02961   */
02962 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
02963 {
02964   uint16_t *tmp;
02965   uint16_t  uhMask = hirda->Mask;
02966   uint16_t  uhdata;
02967 
02968   /* Check that a Rx process is ongoing */
02969   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
02970   {
02971     uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
02972     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
02973     {
02974       tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */
02975       *tmp = (uint16_t)(uhdata & uhMask);
02976       hirda->pRxBuffPtr  += 2U;
02977     }
02978     else
02979     {
02980       *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
02981       hirda->pRxBuffPtr++;
02982     }
02983 
02984     hirda->RxXferCount--;
02985     if (hirda->RxXferCount == 0U)
02986     {
02987       /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */
02988 #if defined(USART_CR1_FIFOEN)
02989       CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
02990 #else
02991       CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
02992 #endif /* USART_CR1_FIFOEN */
02993 
02994       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
02995       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
02996 
02997       /* Rx process is completed, restore hirda->RxState to Ready */
02998       hirda->RxState = HAL_IRDA_STATE_READY;
02999 
03000 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
03001       /* Call registered Rx complete callback */
03002       hirda->RxCpltCallback(hirda);
03003 #else
03004       /* Call legacy weak Rx complete callback */
03005       HAL_IRDA_RxCpltCallback(hirda);
03006 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
03007     }
03008   }
03009   else
03010   {
03011     /* Clear RXNE interrupt flag */
03012     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
03013   }
03014 }
03015 
03016 /**
03017   * @}
03018   */
03019 
03020 #endif /* HAL_IRDA_MODULE_ENABLED */
03021 /**
03022   * @}
03023   */
03024 
03025 /**
03026   * @}
03027   */
03028 
03029