STM32F439xx HAL User Manual
stm32f4xx_hal_irda.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_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 SIR ENDEC block (IrDA):
00008   *           + Initialization and de-initialization methods
00009   *           + IO operation methods
00010   *           + Peripheral Control methods
00011   *
00012   @verbatim
00013   ==============================================================================
00014                         ##### How to use this driver #####
00015   ==============================================================================
00016   [..]
00017     The IRDA HAL driver can be used as follows:
00018     
00019     (#) Declare a IRDA_HandleTypeDef handle structure.
00020     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
00021         (##) Enable the USARTx interface clock.
00022         (##) IRDA pins configuration:
00023             (+++) Enable the clock for the IRDA GPIOs.
00024             (+++) Configure these IRDA pins as alternate function pull-up.
00025         (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
00026              and HAL_IRDA_Receive_IT() APIs):
00027             (+++) Configure the USARTx interrupt priority.
00028             (+++) Enable the NVIC USART IRQ handle.
00029         (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
00030              and HAL_IRDA_Receive_DMA() APIs):
00031             (+++) Declare a DMA handle structure for the Tx/Rx stream.
00032             (+++) Enable the DMAx interface clock.
00033             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.                
00034             (+++) Configure the DMA Tx/Rx Stream.
00035             (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
00036             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
00037 
00038     (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler 
00039         and Mode(Receiver/Transmitter) in the hirda Init structure.
00040 
00041     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
00042         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00043             by calling the customized HAL_IRDA_MspInit() API.
00044     -@@- The specific IRDA interrupts (Transmission complete interrupt, 
00045         RXNE interrupt and Error Interrupts) will be managed using the macros
00046         __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
00047         
00048     (#) Three operation modes are available within this driver :
00049              
00050     *** Polling mode IO operation ***
00051     =================================
00052     [..]    
00053       (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() 
00054       (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
00055        
00056     *** Interrupt mode IO operation ***    
00057     ===================================
00058     [..]    
00059       (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT() 
00060       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can 
00061            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
00062       (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT() 
00063       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can 
00064            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback                                      
00065       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 
00066            add his own code by customization of function pointer HAL_IRDA_ErrorCallback
00067 
00068     *** DMA mode IO operation ***    
00069     =============================
00070     [..]
00071       (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA() 
00072       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can 
00073            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
00074       (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA() 
00075       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can 
00076            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback                                      
00077       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 
00078            add his own code by customization of function pointer HAL_IRDA_ErrorCallback    
00079 
00080     *** IRDA HAL driver macros list ***
00081     ===================================
00082     [..]
00083       Below the list of most used macros in IRDA HAL driver.
00084        
00085      (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral 
00086      (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral     
00087      (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not
00088      (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag
00089      (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt
00090      (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt
00091 
00092     [..]
00093      (@) You can refer to the IRDA HAL driver header file for more useful macros
00094 
00095   @endverbatim
00096   ******************************************************************************
00097   * @attention
00098   *
00099   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00100   *
00101   * Redistribution and use in source and binary forms, with or without modification,
00102   * are permitted provided that the following conditions are met:
00103   *   1. Redistributions of source code must retain the above copyright notice,
00104   *      this list of conditions and the following disclaimer.
00105   *   2. Redistributions in binary form must reproduce the above copyright notice,
00106   *      this list of conditions and the following disclaimer in the documentation
00107   *      and/or other materials provided with the distribution.
00108   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00109   *      may be used to endorse or promote products derived from this software
00110   *      without specific prior written permission.
00111   *
00112   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00113   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00114   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00115   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00116   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00117   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00118   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00119   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00120   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00121   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00122   *
00123   ******************************************************************************
00124   */ 
00125 
00126 /* Includes ------------------------------------------------------------------*/
00127 #include "stm32f4xx_hal.h"
00128 
00129 /** @addtogroup STM32F4xx_HAL_Driver
00130   * @{
00131   */
00132 
00133 /** @defgroup IRDA IRDA
00134   * @brief HAL IRDA module driver
00135   * @{
00136   */
00137 
00138 #ifdef HAL_IRDA_MODULE_ENABLED
00139 
00140 /* Private typedef -----------------------------------------------------------*/
00141 /* Private define ------------------------------------------------------------*/
00142 /** @addtogroup IRDA_Private_Constants
00143   * @{
00144   */
00145 /**
00146   * @}
00147   */
00148 /* Private macro -------------------------------------------------------------*/
00149 /* Private variables ---------------------------------------------------------*/
00150 /* Private function prototypes -----------------------------------------------*/
00151 /** @addtogroup IRDA_Private_Functions
00152   * @{
00153   */
00154 static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
00155 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
00156 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
00157 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
00158 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00159 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
00160 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00161 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
00162 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
00163 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
00164 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
00165 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
00166 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
00167 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
00168 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart,uint32_t Timeout);
00169 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
00170 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
00171 /**
00172   * @}
00173   */
00174 /* Exported functions --------------------------------------------------------*/
00175 /** @defgroup IRDA_Exported_Functions IrDA Exported Functions
00176   * @{
00177   */
00178 
00179 /** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions 
00180   *  @brief    Initialization and Configuration functions 
00181   *
00182 @verbatim 
00183 
00184 ===============================================================================
00185             ##### Initialization and Configuration functions #####
00186  ===============================================================================  
00187     [..]
00188     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy 
00189     in IrDA mode.
00190       (+) For the asynchronous mode only these parameters can be configured: 
00191         (++) BaudRate
00192         (++) WordLength 
00193         (++) Parity: If the parity is enabled, then the MSB bit of the data written
00194              in the data register is transmitted but is changed by the parity bit.
00195              Depending on the frame length defined by the M bit (8-bits or 9-bits),
00196              please refer to Reference manual for possible IRDA frame formats.
00197         (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
00198              not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
00199              specification specifies a minimum of 10 ms delay between transmission and 
00200              reception (IrDA is a half duplex protocol).
00201         (++) Mode: Receiver/transmitter modes
00202         (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
00203     [..]
00204     The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
00205     are available in reference manual).
00206 
00207 @endverbatim
00208   * @{
00209   */
00210 
00211 /**
00212   * @brief  Initializes the IRDA mode according to the specified
00213   *         parameters in the IRDA_InitTypeDef and create the associated handle.
00214   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00215   *                the configuration information for the specified IRDA module.
00216   * @retval HAL status
00217   */
00218 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
00219 {
00220   /* Check the IRDA handle allocation */
00221   if(hirda == NULL)
00222   {
00223     return HAL_ERROR;
00224   }
00225   
00226   /* Check the IRDA instance parameters */
00227   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00228   /* Check the IRDA mode parameter in the IRDA handle */
00229   assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode)); 
00230   
00231   if(hirda->gState == HAL_IRDA_STATE_RESET)
00232   {
00233     /* Allocate lock resource and initialize it */
00234     hirda->Lock = HAL_UNLOCKED;
00235     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00236     HAL_IRDA_MspInit(hirda);
00237   }
00238   
00239   hirda->gState = HAL_IRDA_STATE_BUSY;
00240   
00241   /* Disable the IRDA peripheral */
00242   __HAL_IRDA_DISABLE(hirda);
00243   
00244   /* Set the IRDA communication parameters */
00245   IRDA_SetConfig(hirda);
00246   
00247   /* In IrDA mode, the following bits must be kept cleared: 
00248   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
00249   - SCEN and HDSEL bits in the USART_CR3 register.*/
00250   CLEAR_BIT(hirda->Instance->CR2, USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN);
00251   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_SCEN | USART_CR3_HDSEL);
00252   
00253   /* Enable the IRDA peripheral */
00254   __HAL_IRDA_ENABLE(hirda);
00255   
00256   /* Set the prescaler */
00257   MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
00258   
00259   /* Configure the IrDA mode */
00260   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
00261   
00262   /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
00263   SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
00264   
00265   /* Initialize the IRDA state*/
00266   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00267   hirda->gState= HAL_IRDA_STATE_READY;
00268   hirda->RxState= HAL_IRDA_STATE_READY;
00269   
00270   return HAL_OK;
00271 }
00272 
00273 /**
00274   * @brief  DeInitializes the IRDA peripheral 
00275   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00276   *                the configuration information for the specified IRDA module.
00277   * @retval HAL status
00278   */
00279 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
00280 {
00281   /* Check the IRDA handle allocation */
00282   if(hirda == NULL)
00283   {
00284     return HAL_ERROR;
00285   }
00286   
00287   /* Check the parameters */
00288   assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 
00289   
00290   hirda->gState = HAL_IRDA_STATE_BUSY;
00291   
00292   /* Disable the Peripheral */
00293   __HAL_IRDA_DISABLE(hirda);
00294   
00295   /* DeInit the low level hardware */
00296   HAL_IRDA_MspDeInit(hirda);
00297   
00298   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00299   
00300   hirda->gState = HAL_IRDA_STATE_RESET; 
00301   hirda->RxState = HAL_IRDA_STATE_RESET;
00302   
00303   /* Release Lock */
00304   __HAL_UNLOCK(hirda);
00305   
00306   return HAL_OK;
00307 }
00308 
00309 /**
00310   * @brief  IRDA MSP Init.
00311   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00312   *                the configuration information for the specified IRDA module.
00313   * @retval None
00314   */
00315 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
00316 {
00317   /* Prevent unused argument(s) compilation warning */
00318   UNUSED(hirda);
00319   /* NOTE : This function Should not be modified, when the callback is needed,
00320   the HAL_IRDA_MspInit could be implemented in the user file
00321   */ 
00322 }
00323 
00324 /**
00325   * @brief  IRDA MSP DeInit.
00326   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00327   *                the configuration information for the specified IRDA module.
00328   * @retval None
00329   */
00330 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
00331 {
00332   /* Prevent unused argument(s) compilation warning */
00333   UNUSED(hirda);
00334   /* NOTE : This function Should not be modified, when the callback is needed,
00335   the HAL_IRDA_MspDeInit could be implemented in the user file
00336   */ 
00337 }
00338 
00339 /**
00340   * @}
00341   */
00342 
00343 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions 
00344   *  @brief   IRDA Transmit/Receive functions 
00345   *
00346 @verbatim   
00347  ===============================================================================
00348                       ##### IO operation functions #####
00349  ===============================================================================  
00350     This subsection provides a set of functions allowing to manage the IRDA data transfers.
00351     [..]
00352     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
00353     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver 
00354     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
00355     While receiving data, transmission should be avoided as the data to be transmitted
00356     could be corrupted.
00357 
00358     (#) There are two modes of transfer:
00359        (++) Blocking mode: The communication is performed in polling mode. 
00360             The HAL status of all data processing is returned by the same function 
00361             after finishing transfer.  
00362        (++) No-Blocking mode: The communication is performed using Interrupts 
00363            or DMA, These APIs return the HAL status.
00364            The end of the data processing will be indicated through the 
00365            dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when 
00366            using DMA mode.
00367            The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks 
00368            will be executed respectively at the end of the transmit or Receive process
00369            The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
00370 
00371     (#) Blocking mode API's are :
00372         (++) HAL_IRDA_Transmit()
00373         (++) HAL_IRDA_Receive() 
00374         
00375     (#) Non Blocking mode APIs with Interrupt are :
00376         (++) HAL_IRDA_Transmit_IT()
00377         (++) HAL_IRDA_Receive_IT()
00378         (++) HAL_IRDA_IRQHandler()
00379 
00380     (#) Non Blocking mode functions with DMA are :
00381         (++) HAL_IRDA_Transmit_DMA()
00382         (++) HAL_IRDA_Receive_DMA()
00383 
00384     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
00385         (++) HAL_IRDA_TxCpltCallback()
00386         (++) HAL_IRDA_RxCpltCallback()
00387         (++) HAL_IRDA_ErrorCallback()
00388 
00389 @endverbatim
00390   * @{
00391   */
00392 
00393 /**
00394   * @brief  Sends an amount of data in blocking mode.
00395   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00396   *                the configuration information for the specified IRDA module.
00397   * @param  pData Pointer to data buffer
00398   * @param  Size Amount of data to be sent
00399   * @param  Timeout Specify timeout value  
00400   * @retval HAL status
00401   */
00402 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00403 {
00404   uint16_t* tmp;
00405   uint32_t tickstart = 0U;
00406   
00407   /* Check that a Tx process is not already ongoing */
00408   if(hirda->gState == HAL_IRDA_STATE_READY) 
00409   {
00410     if((pData == NULL) || (Size == 0)) 
00411     {
00412       return  HAL_ERROR;
00413     }
00414     
00415     /* Process Locked */
00416     __HAL_LOCK(hirda);
00417     
00418     hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 
00419     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00420     
00421     /* Init tickstart for timeout managment*/
00422     tickstart = HAL_GetTick();
00423     
00424     hirda->TxXferSize = Size;
00425     hirda->TxXferCount = Size;
00426     while(hirda->TxXferCount > 0U)
00427     {
00428       hirda->TxXferCount--;
00429       if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
00430       {
00431         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
00432         { 
00433           return HAL_TIMEOUT;
00434         }
00435         tmp = (uint16_t*) pData;
00436         hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
00437         if(hirda->Init.Parity == IRDA_PARITY_NONE)
00438         {
00439           pData +=2;
00440         }
00441         else
00442         {
00443           pData +=1;
00444         }
00445       } 
00446       else
00447       {
00448         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
00449         {
00450           return HAL_TIMEOUT;
00451         }
00452         hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
00453       }
00454     }
00455     
00456     if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00457     { 
00458       return HAL_TIMEOUT;
00459     }
00460     
00461     /* At end of Tx process, restore hirda->gState to Ready */
00462     hirda->gState = HAL_IRDA_STATE_READY;
00463     
00464     /* Process Unlocked */
00465     __HAL_UNLOCK(hirda);
00466     
00467     return HAL_OK;
00468   }
00469   else
00470   {
00471     return HAL_BUSY;
00472   }
00473 }
00474 
00475 /**
00476   * @brief  Receive an amount of data in blocking mode. 
00477   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00478   *                the configuration information for the specified IRDA module.
00479   * @param  pData Pointer to data buffer
00480   * @param  Size Amount of data to be received
00481   * @param  Timeout Specify timeout value    
00482   * @retval HAL status
00483   */
00484 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00485 { 
00486   uint16_t* tmp;
00487   uint32_t tickstart = 0U;
00488   
00489   /* Check that a Rx process is not already ongoing */
00490   if(hirda->RxState == HAL_IRDA_STATE_READY) 
00491   {
00492     if((pData == NULL) || (Size == 0)) 
00493     {
00494       return  HAL_ERROR;
00495     }
00496     
00497     /* Process Locked */
00498     __HAL_LOCK(hirda);
00499     
00500     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00501     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00502     
00503     /* Init tickstart for timeout managment*/
00504     tickstart = HAL_GetTick();
00505     
00506     hirda->RxXferSize = Size;
00507     hirda->RxXferCount = Size;
00508     /* Check the remain data to be received */
00509     while(hirda->RxXferCount > 0U)
00510     {
00511       hirda->RxXferCount--;
00512       if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
00513       {
00514         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00515         { 
00516           return HAL_TIMEOUT;
00517         }
00518         tmp = (uint16_t*) pData ;
00519         if(hirda->Init.Parity == IRDA_PARITY_NONE)
00520         {
00521           *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
00522           pData +=2;
00523         }
00524         else
00525         {
00526           *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
00527           pData +=1;
00528         }
00529       } 
00530       else
00531       {
00532         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00533         { 
00534           return HAL_TIMEOUT;
00535         }
00536         if(hirda->Init.Parity == IRDA_PARITY_NONE)
00537         {
00538           *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
00539         }
00540         else
00541         {
00542           *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
00543         }
00544       }
00545     }
00546     
00547     /* At end of Rx process, restore hirda->RxState to Ready */
00548     hirda->RxState = HAL_IRDA_STATE_READY;
00549     
00550     /* Process Unlocked */
00551     __HAL_UNLOCK(hirda);
00552     
00553     return HAL_OK;
00554   }
00555   else
00556   {
00557     return HAL_BUSY;
00558   }
00559 }
00560 
00561 /**
00562   * @brief  Send an amount of data in non blocking mode. 
00563   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00564   *                the configuration information for the specified IRDA module.
00565   * @param  pData Pointer to data buffer
00566   * @param  Size Amount of data to be sent
00567   * @retval HAL status
00568   */
00569 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00570 {
00571   /* Check that a Tx process is not already ongoing */
00572   if(hirda->gState == HAL_IRDA_STATE_READY) 
00573   {
00574     if((pData == NULL) || (Size == 0)) 
00575     {
00576       return HAL_ERROR;
00577     }
00578     /* Process Locked */
00579     __HAL_LOCK(hirda);
00580 
00581     hirda->pTxBuffPtr = pData;
00582     hirda->TxXferSize = Size;
00583     hirda->TxXferCount = Size;
00584     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00585     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00586 
00587     /* Process Unlocked */
00588     __HAL_UNLOCK(hirda);
00589 
00590     /* Enable the IRDA Transmit Data Register Empty Interrupt */
00591     SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
00592 
00593     return HAL_OK;
00594   }
00595   else
00596   {
00597     return HAL_BUSY;
00598   }
00599 }
00600 
00601 /**
00602   * @brief  Receives an amount of data in non blocking mode. 
00603   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00604   *                the configuration information for the specified IRDA module.
00605   * @param  pData Pointer to data buffer
00606   * @param  Size Amount of data to be received
00607   * @retval HAL status
00608   */
00609 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00610 {
00611   /* Check that a Rx process is not already ongoing */  
00612   if(hirda->RxState == HAL_IRDA_STATE_READY) 
00613   {
00614     if((pData == NULL) || (Size == 0)) 
00615     {
00616       return HAL_ERROR;
00617     }
00618     
00619     /* Process Locked */
00620     __HAL_LOCK(hirda);
00621     
00622     hirda->pRxBuffPtr = pData;
00623     hirda->RxXferSize = Size;
00624     hirda->RxXferCount = Size;
00625     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00626     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00627     
00628     /* Process Unlocked */
00629     __HAL_UNLOCK(hirda);
00630 
00631     /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
00632     SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE);
00633 
00634     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
00635     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
00636 
00637     return HAL_OK;
00638   }
00639   else
00640   {
00641     return HAL_BUSY;
00642   }
00643 }
00644 
00645 /**
00646   * @brief  Sends an amount of data in non blocking mode. 
00647   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00648   *                the configuration information for the specified IRDA module.
00649   * @param  pData Pointer to data buffer
00650   * @param  Size Amount of data to be sent
00651   * @retval HAL status
00652   */
00653 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00654 {
00655   uint32_t *tmp;
00656   
00657   /* Check that a Tx process is not already ongoing */
00658   if(hirda->gState == HAL_IRDA_STATE_READY) 
00659   {
00660     if((pData == NULL) || (Size == 0)) 
00661     {
00662       return HAL_ERROR;
00663     }
00664     
00665     /* Process Locked */
00666     __HAL_LOCK(hirda);
00667 
00668     hirda->pTxBuffPtr = pData;
00669     hirda->TxXferSize = Size;
00670     hirda->TxXferCount = Size;
00671     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00672     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00673 
00674     /* Set the IRDA DMA transfer complete callback */
00675     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
00676 
00677     /* Set the IRDA DMA half transfer complete callback */
00678     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
00679 
00680     /* Set the DMA error callback */
00681     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
00682 
00683     /* Set the DMA abort callback */
00684     hirda->hdmatx->XferAbortCallback = NULL;
00685 
00686     /* Enable the IRDA transmit DMA Stream */
00687     tmp = (uint32_t*)&pData;
00688     HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size);
00689 
00690     /* Clear the TC flag in the SR register by writing 0 to it */
00691     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
00692     
00693     /* Process Unlocked */
00694     __HAL_UNLOCK(hirda);
00695 
00696     /* Enable the DMA transfer for transmit request by setting the DMAT bit
00697     in the USART CR3 register */
00698     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00699 
00700     return HAL_OK;
00701   }
00702   else
00703   {
00704     return HAL_BUSY;
00705   }
00706 }
00707 
00708 /**
00709   * @brief  Receives an amount of data in non blocking mode. 
00710   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00711   *                the configuration information for the specified IRDA module.
00712   * @param  pData Pointer to data buffer
00713   * @param  Size Amount of data to be received
00714   * @note   When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
00715   * @retval HAL status
00716   */
00717 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00718 {
00719   uint32_t *tmp;
00720   
00721   /* Check that a Rx process is not already ongoing */
00722   if(hirda->RxState == HAL_IRDA_STATE_READY) 
00723   {
00724     if((pData == NULL) || (Size == 0)) 
00725     {
00726       return HAL_ERROR;
00727     }
00728 
00729     /* Process Locked */
00730     __HAL_LOCK(hirda);
00731 
00732     hirda->pRxBuffPtr = pData;
00733     hirda->RxXferSize = Size;   
00734     hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 
00735     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00736 
00737     /* Set the IRDA DMA transfer complete callback */
00738     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
00739 
00740     /* Set the IRDA DMA half transfer complete callback */
00741     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
00742 
00743     /* Set the DMA error callback */
00744     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
00745 
00746     /* Set the DMA abort callback */
00747     hirda->hdmarx->XferAbortCallback = NULL;
00748 
00749     /* Enable the DMA Stream */
00750     tmp = (uint32_t*)&pData;
00751     HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size);
00752         
00753     /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
00754     __HAL_IRDA_CLEAR_OREFLAG(hirda);
00755 
00756     /* Process Unlocked */
00757     __HAL_UNLOCK(hirda);
00758 
00759     /* Enable the IRDA Parity Error Interrupt */
00760     SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
00761 
00762     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
00763     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
00764 
00765     /* Enable the DMA transfer for the receiver request by setting the DMAR bit 
00766     in the USART CR3 register */
00767     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00768 
00769     return HAL_OK;
00770   }
00771   else
00772   {
00773     return HAL_BUSY;
00774   }
00775 }
00776     
00777 /**
00778   * @brief Pauses the DMA Transfer.
00779   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00780   *                the configuration information for the specified IRDA module.
00781   * @retval HAL status
00782   */
00783 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
00784 {
00785   uint32_t dmarequest = 0x00U;
00786 
00787   /* Process Locked */
00788   __HAL_LOCK(hirda);
00789   
00790   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
00791   if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
00792   {
00793     /* Disable the IRDA DMA Tx request */
00794     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00795   }
00796   
00797   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
00798   if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
00799   {
00800     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
00801     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
00802     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
00803     
00804     /* Disable the IRDA DMA Rx request */
00805     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00806   }
00807   
00808   /* Process Unlocked */
00809   __HAL_UNLOCK(hirda);
00810   
00811   return HAL_OK;
00812 }
00813 
00814 /**
00815   * @brief Resumes the DMA Transfer.
00816   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00817   *                the configuration information for the specified IRDA module.
00818   * @retval HAL status
00819   */
00820 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
00821 {
00822   /* Process Locked */
00823   __HAL_LOCK(hirda);
00824   
00825   if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
00826   {
00827     /* Enable the IRDA DMA Tx request */
00828     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00829   }
00830   if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
00831   {
00832     /* Clear the Overrun flag before resuming the Rx transfer */
00833     __HAL_IRDA_CLEAR_OREFLAG(hirda);
00834     
00835     /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
00836     SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
00837     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
00838     
00839     /* Enable the IRDA DMA Rx request */
00840     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00841   }
00842   
00843   /* Process Unlocked */
00844   __HAL_UNLOCK(hirda);
00845   
00846   return HAL_OK;
00847 }
00848 
00849 /**
00850   * @brief Stops the DMA Transfer.
00851   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
00852   *                the configuration information for the specified IRDA module.
00853   * @retval HAL status
00854   */
00855 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
00856 {
00857   uint32_t dmarequest = 0x00U;
00858   /* The Lock is not implemented on this API to allow the user application
00859   to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
00860   when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
00861   and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
00862   */
00863   
00864   /* Stop IRDA DMA Tx request if ongoing */
00865   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
00866   if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
00867   {
00868     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00869     
00870     /* Abort the IRDA DMA Tx channel */
00871     if(hirda->hdmatx != NULL)
00872     {
00873       HAL_DMA_Abort(hirda->hdmatx);
00874     }
00875     IRDA_EndTxTransfer(hirda);
00876   }
00877 
00878   /* Stop IRDA DMA Rx request if ongoing */
00879   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
00880   if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
00881   {
00882     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00883     
00884     /* Abort the IRDA DMA Rx channel */
00885     if(hirda->hdmarx != NULL)
00886     {
00887       HAL_DMA_Abort(hirda->hdmarx);
00888     }
00889     IRDA_EndRxTransfer(hirda);
00890   }
00891   return HAL_OK;
00892 }
00893 
00894 /**
00895   * @brief  Abort ongoing transfers (blocking mode).
00896   * @param  hirda IRDA handle.
00897   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
00898   *         This procedure performs following operations :
00899   *           - Disable PPP Interrupts
00900   *           - Disable the DMA transfer in the peripheral register (if enabled)
00901   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
00902   *           - Set handle State to READY
00903   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
00904   * @retval HAL status
00905 */
00906 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
00907 {
00908   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
00909   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
00910   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
00911   
00912   /* Disable the IRDA DMA Tx request if enabled */
00913   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
00914   {
00915     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00916 
00917     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
00918     if(hirda->hdmatx != NULL)
00919     {
00920       /* Set the IRDA DMA Abort callback to Null. 
00921          No call back execution at end of DMA abort procedure */
00922       hirda->hdmatx->XferAbortCallback = NULL;
00923 
00924       HAL_DMA_Abort(hirda->hdmatx);
00925     }
00926   }
00927 
00928   /* Disable the IRDA DMA Rx request if enabled */
00929   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
00930   {
00931     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00932 
00933     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
00934     if(hirda->hdmarx != NULL)
00935     {
00936       /* Set the IRDA DMA Abort callback to Null. 
00937          No call back execution at end of DMA abort procedure */
00938       hirda->hdmarx->XferAbortCallback = NULL;
00939 
00940       HAL_DMA_Abort(hirda->hdmarx);
00941     }
00942   }
00943 
00944   /* Reset Tx and Rx transfer counters */
00945   hirda->TxXferCount = 0x00U;
00946   hirda->RxXferCount = 0x00U;
00947 
00948   /* Reset ErrorCode */
00949   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00950 
00951   /* Restore hirda->RxState and hirda->gState to Ready */
00952   hirda->RxState = HAL_IRDA_STATE_READY;
00953   hirda->gState = HAL_IRDA_STATE_READY;
00954 
00955   return HAL_OK;
00956 }
00957 
00958 /**
00959   * @brief  Abort ongoing Transmit transfer (blocking mode).
00960   * @param  hirda IRDA handle.
00961   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
00962   *         This procedure performs following operations :
00963   *           - Disable PPP Interrupts
00964   *           - Disable the DMA transfer in the peripheral register (if enabled)
00965   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
00966   *           - Set handle State to READY
00967   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
00968   * @retval HAL status
00969 */
00970 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
00971 {
00972   /* Disable TXEIE and TCIE interrupts */
00973   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
00974 
00975   /* Disable the IRDA DMA Tx request if enabled */
00976   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
00977   {
00978     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00979 
00980     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
00981     if(hirda->hdmatx != NULL)
00982     {
00983       /* Set the IRDA DMA Abort callback to Null. 
00984          No call back execution at end of DMA abort procedure */
00985       hirda->hdmatx->XferAbortCallback = NULL;
00986 
00987       HAL_DMA_Abort(hirda->hdmatx);
00988     }
00989   }
00990 
00991   /* Reset Tx transfer counter */
00992   hirda->TxXferCount = 0x00U;
00993 
00994   /* Restore hirda->gState to Ready */
00995   hirda->gState = HAL_IRDA_STATE_READY;
00996 
00997   return HAL_OK;
00998 }
00999 
01000 /**
01001   * @brief  Abort ongoing Receive transfer (blocking mode).
01002   * @param  hirda IRDA handle.
01003   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
01004   *         This procedure performs following operations :
01005   *           - Disable PPP Interrupts
01006   *           - Disable the DMA transfer in the peripheral register (if enabled)
01007   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
01008   *           - Set handle State to READY
01009   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
01010   * @retval HAL status
01011 */
01012 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
01013 {
01014   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01015   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01016   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01017 
01018   /* Disable the IRDA DMA Rx request if enabled */
01019   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01020   {
01021     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01022 
01023     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
01024     if(hirda->hdmarx != NULL)
01025     {
01026       /* Set the IRDA DMA Abort callback to Null. 
01027          No call back execution at end of DMA abort procedure */
01028       hirda->hdmarx->XferAbortCallback = NULL;
01029 
01030       HAL_DMA_Abort(hirda->hdmarx);
01031     }
01032   }
01033 
01034   /* Reset Rx transfer counter */
01035   hirda->RxXferCount = 0x00U;
01036 
01037   /* Restore hirda->RxState to Ready */
01038   hirda->RxState = HAL_IRDA_STATE_READY;
01039 
01040   return HAL_OK;
01041 }
01042 
01043 /**
01044   * @brief  Abort ongoing transfers (Interrupt mode).
01045   * @param  hirda IRDA handle.
01046   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
01047   *         This procedure performs following operations :
01048   *           - Disable PPP Interrupts
01049   *           - Disable the DMA transfer in the peripheral register (if enabled)
01050   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01051   *           - Set handle State to READY
01052   *           - At abort completion, call user abort complete callback
01053   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01054   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01055   * @retval HAL status
01056 */
01057 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
01058 {
01059     uint32_t AbortCplt = 1U;
01060 
01061   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01062   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
01063   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01064 
01065   /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
01066      before any call to DMA Abort functions */
01067   /* DMA Tx Handle is valid */
01068   if(hirda->hdmatx != NULL)
01069   {
01070     /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
01071        Otherwise, set it to NULL */
01072     if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01073     {
01074       hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
01075     }
01076     else
01077     {
01078       hirda->hdmatx->XferAbortCallback = NULL;
01079     }
01080   }
01081   /* DMA Rx Handle is valid */
01082   if(hirda->hdmarx != NULL)
01083   {
01084     /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
01085        Otherwise, set it to NULL */
01086     if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01087     {
01088       hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
01089     }
01090     else
01091     {
01092       hirda->hdmarx->XferAbortCallback = NULL;
01093     }
01094   }
01095 
01096   /* Disable the IRDA DMA Tx request if enabled */
01097   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01098   {
01099     /* Disable DMA Tx at IRDA level */
01100     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01101 
01102     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
01103     if(hirda->hdmatx != NULL)
01104     {
01105       /* IRDA Tx DMA Abort callback has already been initialised : 
01106          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01107 
01108       /* Abort DMA TX */
01109       if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
01110       {
01111         hirda->hdmatx->XferAbortCallback = NULL;
01112       }
01113       else
01114       {
01115         AbortCplt = 0x00U;
01116       }
01117     }
01118   }
01119 
01120   /* Disable the IRDA DMA Rx request if enabled */
01121   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01122   {
01123     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01124 
01125     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
01126     if(hirda->hdmarx != NULL)
01127     {
01128       /* IRDA Rx DMA Abort callback has already been initialised : 
01129          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01130 
01131       /* Abort DMA RX */
01132       if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
01133       {
01134         hirda->hdmarx->XferAbortCallback = NULL;
01135         AbortCplt = 0x01U;
01136       }
01137       else
01138       {
01139         AbortCplt = 0x00U;
01140       }
01141     }
01142   }
01143 
01144   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
01145   if(AbortCplt == 0x01U)
01146   {
01147     /* Reset Tx and Rx transfer counters */
01148     hirda->TxXferCount = 0x00U; 
01149     hirda->RxXferCount = 0x00U;
01150 
01151     /* Reset ErrorCode */
01152     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01153 
01154     /* Restore hirda->gState and hirda->RxState to Ready */
01155     hirda->gState  = HAL_IRDA_STATE_READY;
01156     hirda->RxState = HAL_IRDA_STATE_READY;
01157 
01158     /* As no DMA to be aborted, call directly user Abort complete callback */
01159     HAL_IRDA_AbortCpltCallback(hirda);
01160   }
01161 
01162   return HAL_OK;
01163 }
01164 
01165 /**
01166   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
01167   * @param  hirda IRDA handle.
01168   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
01169   *         This procedure performs following operations :
01170   *           - Disable PPP Interrupts
01171   *           - Disable the DMA transfer in the peripheral register (if enabled)
01172   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01173   *           - Set handle State to READY
01174   *           - At abort completion, call user abort complete callback
01175   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01176   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01177   * @retval HAL status
01178 */
01179 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
01180 {
01181   /* Disable TXEIE and TCIE interrupts */
01182   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
01183 
01184   /* Disable the IRDA DMA Tx request if enabled */
01185   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
01186   {
01187     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01188 
01189     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
01190     if(hirda->hdmatx != NULL)
01191     {
01192       /* Set the IRDA DMA Abort callback : 
01193          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01194       hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
01195 
01196       /* Abort DMA TX */
01197       if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
01198       {
01199         /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
01200         hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
01201       }
01202     }
01203     else
01204     {
01205       /* Reset Tx transfer counter */
01206       hirda->TxXferCount = 0x00U;
01207 
01208       /* Restore hirda->gState to Ready */
01209       hirda->gState = HAL_IRDA_STATE_READY;
01210       
01211       /* As no DMA to be aborted, call directly user Abort complete callback */
01212       HAL_IRDA_AbortTransmitCpltCallback(hirda);
01213     }
01214   }
01215   else
01216   {
01217     /* Reset Tx transfer counter */
01218     hirda->TxXferCount = 0x00U;
01219 
01220     /* Restore hirda->gState to Ready */
01221     hirda->gState = HAL_IRDA_STATE_READY;
01222 
01223     /* As no DMA to be aborted, call directly user Abort complete callback */
01224     HAL_IRDA_AbortTransmitCpltCallback(hirda);
01225   }
01226 
01227   return HAL_OK;
01228 }
01229 
01230 /**
01231   * @brief  Abort ongoing Receive transfer (Interrupt mode).
01232   * @param  hirda IRDA handle.
01233   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 
01234   *         This procedure performs following operations :
01235   *           - Disable PPP Interrupts
01236   *           - Disable the DMA transfer in the peripheral register (if enabled)
01237   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01238   *           - Set handle State to READY
01239   *           - At abort completion, call user abort complete callback
01240   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01241   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01242   * @retval HAL status
01243 */
01244 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
01245 {
01246   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01247   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01248   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01249 
01250   /* Disable the IRDA DMA Rx request if enabled */
01251   if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01252   {
01253     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01254 
01255     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
01256     if(hirda->hdmarx != NULL)
01257     {
01258       /* Set the IRDA DMA Abort callback : 
01259          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
01260       hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
01261 
01262       /* Abort DMA RX */
01263       if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
01264       {
01265         /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
01266         hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
01267       }
01268     }
01269     else
01270     {
01271       /* Reset Rx transfer counter */
01272       hirda->RxXferCount = 0x00U;
01273 
01274       /* Restore hirda->RxState to Ready */
01275       hirda->RxState = HAL_IRDA_STATE_READY;
01276 
01277       /* As no DMA to be aborted, call directly user Abort complete callback */
01278       HAL_IRDA_AbortReceiveCpltCallback(hirda);
01279     }
01280   }
01281   else
01282   {
01283     /* Reset Rx transfer counter */
01284     hirda->RxXferCount = 0x00U;
01285 
01286     /* Restore hirda->RxState to Ready */
01287     hirda->RxState = HAL_IRDA_STATE_READY;
01288 
01289     /* As no DMA to be aborted, call directly user Abort complete callback */
01290     HAL_IRDA_AbortReceiveCpltCallback(hirda);
01291   }
01292 
01293   return HAL_OK;
01294 }
01295 
01296 /**
01297   * @brief  This function handles IRDA interrupt request.
01298   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01299   *                the configuration information for the specified IRDA module.
01300   * @retval None
01301   */
01302 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
01303 {
01304    uint32_t isrflags   = READ_REG(hirda->Instance->SR);
01305    uint32_t cr1its     = READ_REG(hirda->Instance->CR1);
01306    uint32_t cr3its     = READ_REG(hirda->Instance->CR3);
01307    uint32_t errorflags = 0x00U;
01308    uint32_t dmarequest = 0x00U;
01309 
01310   /* If no error occurs */
01311   errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
01312   if(errorflags == RESET)
01313   {
01314     /* IRDA in mode Receiver -----------------------------------------------*/
01315     if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
01316     {
01317       IRDA_Receive_IT(hirda);
01318       return;
01319     }
01320   }  
01321 
01322   /* If some errors occur */
01323   if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
01324   {
01325     /* IRDA parity error interrupt occurred -------------------------------*/
01326     if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
01327     {
01328       hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
01329     }
01330 
01331     /* IRDA noise error interrupt occurred --------------------------------*/
01332     if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
01333     {
01334       hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
01335     }
01336 
01337     /* IRDA frame error interrupt occurred --------------------------------*/
01338     if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
01339     {
01340       hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
01341     }
01342 
01343     /* IRDA Over-Run interrupt occurred -----------------------------------*/
01344     if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
01345     { 
01346       hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
01347     }
01348     /* Call IRDA Error Call back function if need be -----------------------*/ 
01349     if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
01350     {
01351       /* IRDA in mode Receiver ---------------------------------------------*/
01352       if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
01353       {
01354         IRDA_Receive_IT(hirda);
01355       }
01356 
01357       dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
01358       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
01359          consider error as blocking */
01360       if(((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
01361       {
01362         /* Blocking error : transfer is aborted
01363            Set the IRDA state ready to be able to start again the process,
01364            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
01365         IRDA_EndRxTransfer(hirda);
01366 
01367         /* Disable the IRDA DMA Rx request if enabled */
01368         if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
01369         {
01370           CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01371 
01372           /* Abort the IRDA DMA Rx channel */
01373           if(hirda->hdmarx != NULL)
01374           {
01375             /* Set the IRDA DMA Abort callback : 
01376             will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
01377             hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
01378 
01379             if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
01380             {
01381               /* Call Directly XferAbortCallback function in case of error */
01382               hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
01383             }
01384           }
01385           else
01386           {
01387             /* Call user error callback */
01388             HAL_IRDA_ErrorCallback(hirda);
01389           }
01390         }
01391         else
01392         {
01393           /* Call user error callback */
01394           HAL_IRDA_ErrorCallback(hirda);
01395         }
01396       }
01397       else
01398       {
01399         /* Non Blocking error : transfer could go on. 
01400            Error is notified to user through user error callback */
01401         HAL_IRDA_ErrorCallback(hirda);
01402         hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01403       }
01404     }
01405     return;
01406   } /* End if some error occurs */
01407 
01408   /* IRDA in mode Transmitter ------------------------------------------------*/
01409   if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
01410   {
01411     IRDA_Transmit_IT(hirda);
01412     return;
01413   }
01414 
01415   /* IRDA in mode Transmitter end --------------------------------------------*/
01416   if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
01417   {
01418     IRDA_EndTransmit_IT(hirda);
01419     return;
01420   }
01421 }
01422 
01423 /**
01424   * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
01425   * @param  hirda IRDA handle.
01426   * @retval None
01427   */
01428 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
01429 {
01430   /* Disable TXEIE and TCIE interrupts */
01431   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
01432 
01433   /* At end of Tx process, restore hirda->gState to Ready */
01434   hirda->gState = HAL_IRDA_STATE_READY;
01435 }
01436 
01437 /**
01438   * @brief  End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
01439   * @param  hirda IRDA handle.
01440   * @retval None
01441   */
01442 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
01443 {
01444   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01445   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01446   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01447 
01448   /* At end of Rx process, restore hirda->RxState to Ready */
01449   hirda->RxState = HAL_IRDA_STATE_READY;
01450 }
01451 
01452 /**
01453   * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
01454   *         (To be called at end of DMA Abort procedure following error occurrence).
01455   * @param  hdma DMA handle.
01456   * @retval None
01457   */
01458 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
01459 {
01460   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01461   hirda->RxXferCount = 0x00U;
01462   hirda->TxXferCount = 0x00U;
01463 
01464   HAL_IRDA_ErrorCallback(hirda);
01465 }
01466 
01467 /**
01468   * @brief  DMA IRDA Tx communication abort callback, when initiated by user
01469   *         (To be called at end of DMA Tx Abort procedure following user abort request).
01470   * @note   When this callback is executed, User Abort complete call back is called only if no
01471   *         Abort still ongoing for Rx DMA Handle.
01472   * @param  hdma DMA handle.
01473   * @retval None
01474   */
01475 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
01476 {
01477   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01478   
01479   hirda->hdmatx->XferAbortCallback = NULL;
01480 
01481   /* Check if an Abort process is still ongoing */
01482   if(hirda->hdmarx != NULL)
01483   {
01484     if(hirda->hdmarx->XferAbortCallback != NULL)
01485     {
01486       return;
01487     }
01488   }
01489   
01490   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
01491   hirda->TxXferCount = 0x00U;
01492   hirda->RxXferCount = 0x00U;
01493 
01494   /* Reset ErrorCode */
01495   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01496 
01497   /* Restore hirda->gState and hirda->RxState to Ready */
01498   hirda->gState  = HAL_IRDA_STATE_READY;
01499   hirda->RxState = HAL_IRDA_STATE_READY;
01500 
01501   /* Call user Abort complete callback */
01502   HAL_IRDA_AbortCpltCallback(hirda);
01503 }
01504 
01505 /**
01506   * @brief  DMA IRDA Rx communication abort callback, when initiated by user
01507   *         (To be called at end of DMA Rx Abort procedure following user abort request).
01508   * @note   When this callback is executed, User Abort complete call back is called only if no
01509   *         Abort still ongoing for Tx DMA Handle.
01510   * @param  hdma DMA handle.
01511   * @retval None
01512   */
01513 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
01514 {
01515   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01516   
01517   hirda->hdmarx->XferAbortCallback = NULL;
01518 
01519   /* Check if an Abort process is still ongoing */
01520   if(hirda->hdmatx != NULL)
01521   {
01522     if(hirda->hdmatx->XferAbortCallback != NULL)
01523     {
01524       return;
01525     }
01526   }
01527   
01528   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
01529   hirda->TxXferCount = 0x00U;
01530   hirda->RxXferCount = 0x00U;
01531 
01532   /* Reset ErrorCode */
01533   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01534 
01535   /* Restore hirda->gState and hirda->RxState to Ready */
01536   hirda->gState  = HAL_IRDA_STATE_READY;
01537   hirda->RxState = HAL_IRDA_STATE_READY;
01538 
01539   /* Call user Abort complete callback */
01540   HAL_IRDA_AbortCpltCallback(hirda);
01541 }
01542 
01543 /**
01544   * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
01545   *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
01546   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
01547   *         and leads to user Tx Abort Complete callback execution).
01548   * @param  hdma DMA handle.
01549   * @retval None
01550   */
01551 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
01552 {
01553   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01554 
01555   hirda->TxXferCount = 0x00U;
01556 
01557   /* Restore hirda->gState to Ready */
01558   hirda->gState = HAL_IRDA_STATE_READY;
01559 
01560   /* Call user Abort complete callback */
01561   HAL_IRDA_AbortTransmitCpltCallback(hirda);
01562 }
01563 
01564 /**
01565   * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
01566   *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
01567   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
01568   *         and leads to user Rx Abort Complete callback execution).
01569   * @param  hdma DMA handle.
01570   * @retval None
01571   */
01572 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
01573 {
01574   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01575 
01576   hirda->RxXferCount = 0x00U;
01577 
01578   /* Restore hirda->RxState to Ready */
01579   hirda->RxState = HAL_IRDA_STATE_READY;
01580 
01581   /* Call user Abort complete callback */
01582   HAL_IRDA_AbortReceiveCpltCallback(hirda);
01583 }
01584 
01585 /**
01586   * @brief  Tx Transfer complete callbacks.
01587   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01588   *                the configuration information for the specified IRDA module.
01589   * @retval None
01590   */
01591 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
01592 {
01593   /* Prevent unused argument(s) compilation warning */
01594   UNUSED(hirda);
01595   /* NOTE : This function Should not be modified, when the callback is needed,
01596   the HAL_IRDA_TxCpltCallback could be implemented in the user file
01597   */ 
01598 }
01599 
01600 /**
01601   * @brief  Tx Half Transfer completed callbacks.
01602   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01603   *                the configuration information for the specified USART module.
01604   * @retval None
01605   */
01606 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
01607 {
01608   /* Prevent unused argument(s) compilation warning */
01609   UNUSED(hirda);
01610   /* NOTE: This function Should not be modified, when the callback is needed,
01611   the HAL_IRDA_TxHalfCpltCallback could be implemented in the user file
01612   */
01613 }
01614 
01615 /**
01616   * @brief  Rx Transfer complete callbacks.
01617   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01618   *                the configuration information for the specified IRDA module.
01619   * @retval None
01620   */
01621 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
01622 {
01623   /* Prevent unused argument(s) compilation warning */
01624   UNUSED(hirda);
01625   /* NOTE : This function Should not be modified, when the callback is needed,
01626   the HAL_IRDA_RxCpltCallback could be implemented in the user file
01627   */
01628 }
01629 
01630 /**
01631   * @brief  Rx Half Transfer complete callbacks.
01632   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01633   *                the configuration information for the specified IRDA module.
01634   * @retval None
01635   */
01636 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
01637 {
01638   /* Prevent unused argument(s) compilation warning */
01639   UNUSED(hirda);
01640   /* NOTE : This function Should not be modified, when the callback is needed,
01641   the HAL_IRDA_RxHalfCpltCallback could be implemented in the user file
01642   */
01643 }
01644 
01645 /**
01646   * @brief IRDA error callbacks.
01647   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01648   *                the configuration information for the specified IRDA module.
01649   * @retval None
01650   */
01651 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
01652 {
01653   /* Prevent unused argument(s) compilation warning */
01654   UNUSED(hirda);
01655   /* NOTE : This function Should not be modified, when the callback is needed,
01656   the HAL_IRDA_ErrorCallback could be implemented in the user file
01657   */ 
01658 }
01659 
01660 /**
01661   * @brief  IRDA Abort Complete callback.
01662   * @param  hirda IRDA handle.
01663   * @retval None
01664   */
01665 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
01666 {
01667   /* Prevent unused argument(s) compilation warning */
01668   UNUSED(hirda);
01669 
01670   /* NOTE : This function should not be modified, when the callback is needed,
01671             the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
01672    */
01673 }
01674 
01675 /**
01676   * @brief  IRDA Abort Transmit Complete callback.
01677   * @param  hirda IRDA handle.
01678   * @retval None
01679   */
01680 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
01681 {
01682   /* Prevent unused argument(s) compilation warning */
01683   UNUSED(hirda);
01684 
01685   /* NOTE : This function should not be modified, when the callback is needed,
01686             the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
01687    */
01688 }
01689 
01690 /**
01691   * @brief  IRDA Abort ReceiveComplete callback.
01692   * @param  hirda IRDA handle.
01693   * @retval None
01694   */
01695 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
01696 {
01697   /* Prevent unused argument(s) compilation warning */
01698   UNUSED(hirda);
01699 
01700   /* NOTE : This function should not be modified, when the callback is needed,
01701             the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
01702    */
01703 }
01704 
01705 /**
01706   * @}
01707   */
01708 
01709 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions 
01710   *  @brief   IRDA State and Errors functions 
01711   *
01712 @verbatim   
01713   ==============================================================================
01714                   ##### Peripheral State and Errors functions #####
01715   ==============================================================================  
01716   [..]
01717     This subsection provides a set of functions allowing to return the State of IrDA 
01718     communication process and also return Peripheral Errors occurred during communication process
01719      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
01720      (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication. 
01721      
01722 @endverbatim
01723   * @{
01724   */
01725 
01726 /**
01727   * @brief  Returns the IRDA state.
01728   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01729   *                the configuration information for the specified IRDA module.
01730   * @retval HAL state
01731   */
01732 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
01733 {
01734   uint32_t temp1 = 0x00U, temp2 = 0x00U;
01735   temp1 = hirda->gState;
01736   temp2 = hirda->RxState;
01737   
01738   return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
01739 }
01740 
01741 /**
01742   * @brief  Return the IARDA error code
01743   * @param  hirda  pointer to a IRDA_HandleTypeDef structure that contains
01744   *              the configuration information for the specified IRDA.
01745   * @retval IRDA Error Code
01746   */
01747 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
01748 {
01749   return hirda->ErrorCode;
01750 }
01751 
01752 /**
01753   * @}
01754   */
01755   
01756 /**
01757   * @brief  DMA IRDA transmit process complete callback. 
01758   * @param  hdma  DMA handle
01759   * @retval None
01760   */
01761 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
01762 {
01763   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01764   /* DMA Normal mode */
01765   if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
01766   {
01767     hirda->TxXferCount = 0U;
01768     
01769     /* Disable the DMA transfer for transmit request by setting the DMAT bit
01770     in the IRDA CR3 register */
01771     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
01772     
01773     /* Enable the IRDA Transmit Complete Interrupt */
01774     SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
01775   }
01776   /* DMA Circular mode */
01777   else
01778   {
01779     HAL_IRDA_TxCpltCallback(hirda);
01780   }
01781 }
01782 
01783 /**
01784   * @brief DMA IRDA receive process half complete callback 
01785   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
01786   *                the configuration information for the specified DMA module.
01787   * @retval None
01788   */
01789 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
01790 {
01791   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01792   
01793   HAL_IRDA_TxHalfCpltCallback(hirda); 
01794 }
01795 
01796 /**
01797   * @brief  DMA IRDA receive process complete callback. 
01798   * @param  hdma DMA handle
01799   * @retval None
01800   */
01801 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)   
01802 {
01803   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01804   /* DMA Normal mode */
01805   if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
01806   {
01807     hirda->RxXferCount = 0U;
01808     
01809     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
01810     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
01811     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01812     
01813     /* Disable the DMA transfer for the receiver request by setting the DMAR bit 
01814     in the IRDA CR3 register */
01815     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
01816     
01817     /* At end of Rx process, restore hirda->RxState to Ready */
01818     hirda->RxState = HAL_IRDA_STATE_READY;
01819   }
01820   
01821   HAL_IRDA_RxCpltCallback(hirda);
01822 }
01823 
01824 /**
01825   * @brief DMA IRDA receive process half complete callback 
01826   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
01827   *                the configuration information for the specified DMA module.
01828   * @retval None
01829   */
01830 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
01831 {
01832   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01833   HAL_IRDA_RxHalfCpltCallback(hirda); 
01834 }
01835 
01836 /**
01837   * @brief  DMA IRDA communication error callback.
01838   * @param  hdma DMA handle
01839   * @retval None
01840   */
01841 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
01842 {
01843   uint32_t dmarequest = 0x00U;
01844   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01845   
01846   /* Stop IRDA DMA Tx request if ongoing */
01847   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
01848   if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
01849   {
01850     hirda->TxXferCount = 0U;
01851     IRDA_EndTxTransfer(hirda);
01852   }
01853 
01854   /* Stop IRDA DMA Rx request if ongoing */
01855   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
01856   if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
01857   {
01858     hirda->RxXferCount = 0U;
01859     IRDA_EndRxTransfer(hirda);
01860   }
01861   
01862   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; 
01863   
01864   HAL_IRDA_ErrorCallback(hirda);
01865 }
01866 
01867 /**
01868   * @brief  This function handles IRDA Communication Timeout.
01869   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01870   *                the configuration information for the specified IRDA module.
01871   * @param  Flag specifies the IRDA flag to check.
01872   * @param  Status The new Flag status (SET or RESET).
01873   * @param  Tickstart Tick start value
01874   * @param  Timeout Timeout duration
01875   * @retval HAL status
01876   */
01877 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
01878 {
01879   /* Wait until flag is set */
01880   while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
01881   {
01882     /* Check for the Timeout */
01883     if(Timeout != HAL_MAX_DELAY)
01884     {
01885       if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
01886       {
01887         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
01888         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
01889         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01890         
01891         hirda->gState  = HAL_IRDA_STATE_READY;
01892         hirda->RxState = HAL_IRDA_STATE_READY;
01893         
01894         /* Process Unlocked */
01895         __HAL_UNLOCK(hirda);
01896         
01897         return HAL_TIMEOUT;
01898       }
01899     }
01900   }
01901   return HAL_OK;
01902 }
01903 
01904  /**
01905   * @brief  Send an amount of data in non blocking mode. 
01906   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01907   *                the configuration information for the specified IRDA module.
01908   * @retval HAL status
01909   */
01910 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
01911 {
01912   uint16_t* tmp;
01913   
01914   /* Check that a Tx process is ongoing */
01915   if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
01916   {
01917     if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
01918     {
01919       tmp = (uint16_t*) hirda->pTxBuffPtr;
01920       hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
01921       if(hirda->Init.Parity == IRDA_PARITY_NONE)
01922       {
01923         hirda->pTxBuffPtr += 2U;
01924       }
01925       else
01926       {
01927         hirda->pTxBuffPtr += 1U;
01928       }
01929     } 
01930     else
01931     {
01932       hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
01933     }
01934     
01935     if(--hirda->TxXferCount == 0U)
01936     {
01937       /* Disable the IRDA Transmit Data Register Empty Interrupt */
01938       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
01939       
01940       /* Enable the IRDA Transmit Complete Interrupt */
01941       SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
01942     }
01943     
01944     return HAL_OK;
01945   }
01946   else
01947   {
01948     return HAL_BUSY;
01949   }
01950 }
01951 
01952 /**
01953   * @brief  Wraps up transmission in non blocking mode.
01954   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01955   *                the configuration information for the specified IRDA module.
01956   * @retval HAL status
01957   */
01958 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
01959 {
01960   /* Disable the IRDA Transmit Complete Interrupt */    
01961   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
01962   
01963   /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
01964   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01965   
01966   /* Tx process is ended, restore hirda->gState to Ready */
01967   hirda->gState = HAL_IRDA_STATE_READY;
01968   
01969   HAL_IRDA_TxCpltCallback(hirda);
01970   
01971   return HAL_OK;
01972 }
01973 
01974 /**
01975   * @brief  Receives an amount of data in non blocking mode. 
01976   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
01977   *                the configuration information for the specified IRDA module.
01978   * @retval HAL status
01979   */
01980 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
01981 {
01982   uint16_t* tmp;
01983   uint16_t  uhdata;
01984   
01985   /* Check that a Rx process is ongoing */
01986   if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 
01987   {
01988     uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
01989     if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
01990     {
01991       tmp = (uint16_t*) hirda->pRxBuffPtr;
01992       if(hirda->Init.Parity == IRDA_PARITY_NONE)
01993       {
01994         *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
01995         hirda->pRxBuffPtr += 2U;
01996       }
01997       else
01998       {
01999         *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
02000         hirda->pRxBuffPtr += 1U;
02001       }
02002     } 
02003     else
02004     {
02005       if(hirda->Init.Parity == IRDA_PARITY_NONE)
02006       {
02007         *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
02008       }
02009       else
02010       {
02011         *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
02012       }
02013     }
02014     
02015     if(--hirda->RxXferCount == 0U)
02016     {
02017       /* Disable the IRDA Data Register not empty Interrupt */
02018       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
02019       
02020       /* Disable the IRDA Parity Error Interrupt */
02021       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
02022       
02023       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
02024       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
02025       
02026       /* Rx process is completed, restore hirda->RxState to Ready */
02027       hirda->RxState = HAL_IRDA_STATE_READY;
02028       
02029       HAL_IRDA_RxCpltCallback(hirda);
02030       
02031       return HAL_OK;
02032     }
02033     return HAL_OK;
02034   }
02035   else
02036   {
02037     return HAL_BUSY; 
02038   }
02039 }
02040 
02041 /**
02042   * @brief  Configures the IRDA peripheral. 
02043   * @param  hirda pointer to a IRDA_HandleTypeDef structure that contains
02044   *                the configuration information for the specified IRDA module.
02045   * @retval None
02046   */
02047 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
02048 {
02049   /* Check the parameters */
02050   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
02051   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));  
02052   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
02053   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
02054   assert_param(IS_IRDA_MODE(hirda->Init.Mode));
02055   
02056   /*-------------------------- IRDA CR2 Configuration ------------------------*/
02057   /* Clear STOP[13:12] bits */
02058   CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
02059   
02060   /*-------------------------- USART CR1 Configuration -----------------------*/
02061   /* Clear M, PCE, PS, TE and RE bits */
02062   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE);
02063   
02064   /* Configure the USART Word Length, Parity and mode: 
02065   Set the M bits according to hirda->Init.WordLength value 
02066   Set PCE and PS bits according to hirda->Init.Parity value
02067   Set TE and RE bits according to hirda->Init.Mode value */
02068   /* Write to USART CR1 */
02069   SET_BIT(hirda->Instance->CR1, (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode);
02070   
02071   /*-------------------------- USART CR3 Configuration -----------------------*/
02072   /* Clear CTSE and RTSE bits */
02073   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_RTSE | USART_CR3_CTSE);
02074   
02075   /*-------------------------- USART BRR Configuration -----------------------*/
02076 #if defined(USART6)  
02077   if((hirda->Instance == USART1) || (hirda->Instance == USART6))
02078   {
02079     SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
02080   }
02081 #else
02082   if(hirda->Instance == USART1)
02083   {
02084     SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
02085   }     
02086 #endif /* USART6 */
02087   else
02088   {
02089     SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate));
02090   }
02091 }
02092 
02093 /**
02094   * @}
02095   */
02096 
02097 #endif /* HAL_IRDA_MODULE_ENABLED */
02098 /**
02099   * @}
02100   */
02101 
02102 /**
02103   * @}
02104   */
02105 
02106 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/