L4 HAL Drivers

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_irda.c Source File

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   * @version V1.1.0
00006   * @date    16-September-2015
00007   * @brief   IRDA HAL module driver.
00008   *          This file provides firmware functions to manage the following
00009   *          functionalities of the IrDA (Infrared Data Association) Peripheral
00010   *          (IRDA)
00011   *           + Initialization and de-initialization functions
00012   *           + IO operation functions
00013   *           + Peripheral State and Errors functions
00014   *           + Peripheral Control functions
00015   *
00016   @verbatim
00017   ==============================================================================
00018                         ##### How to use this driver #####
00019   ==============================================================================
00020   [..]
00021     The IRDA HAL driver can be used as follows:
00022 
00023     (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda).
00024     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API
00025         in setting the associated USART or UART in IRDA mode:
00026         (++) Enable the USARTx/UARTx interface clock.
00027         (++) USARTx/UARTx pins configuration:
00028             (+++) Enable the clock for the USARTx/UARTx GPIOs.
00029             (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input).
00030         (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
00031              and HAL_IRDA_Receive_IT() APIs): 
00032             (+++) Configure the USARTx/UARTx interrupt priority.
00033             (+++) Enable the NVIC USARTx/UARTx IRQ handle.            
00034             (+++) The specific IRDA interrupts (Transmission complete interrupt,
00035                   RXNE interrupt and Error Interrupts) will be managed using the macros
00036                   __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
00037                 
00038         (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
00039              and HAL_IRDA_Receive_DMA() APIs):
00040             (+++) Declare a DMA handle structure for the Tx/Rx channel.
00041             (+++) Enable the DMAx interface clock.
00042             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
00043             (+++) Configure the DMA Tx/Rx channel.
00044             (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
00045             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
00046 
00047     (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
00048         the normal or low power mode and the clock prescaler in the hirda handle Init structure.
00049 
00050     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
00051         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00052              by calling the customized HAL_IRDA_MspInit() API.
00053         
00054          -@@- The specific IRDA interrupts (Transmission complete interrupt,
00055              RXNE interrupt and Error Interrupts) will be managed using the macros
00056              __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
00057      
00058     (#) Three operation modes are available within this driver :
00059 
00060      *** Polling mode IO operation ***
00061      =================================
00062      [..]
00063        (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
00064        (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
00065 
00066      *** Interrupt mode IO operation ***
00067      ===================================
00068      [..]
00069        (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT()
00070        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
00071             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
00072        (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT()
00073        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
00074             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
00075        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
00076             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
00077 
00078      *** DMA mode IO operation ***
00079      ==============================
00080      [..]
00081        (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
00082        (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can
00083             add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback()
00084        (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
00085             add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
00086        (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA()
00087        (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can
00088             add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback()
00089        (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
00090             add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
00091        (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
00092             add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
00093 
00094      *** IRDA HAL driver macros list ***
00095      ====================================
00096      [..]
00097        Below the list of most used macros in IRDA HAL driver.
00098 
00099        (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
00100        (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
00101        (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
00102        (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
00103        (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
00104        (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
00105        (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled
00106 
00107      [..]
00108        (@) You can refer to the IRDA HAL driver header file for more useful macros
00109 
00110   @endverbatim
00111   ******************************************************************************
00112   * @attention
00113   *
00114   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00115   *
00116   * Redistribution and use in source and binary forms, with or without modification,
00117   * are permitted provided that the following conditions are met:
00118   *   1. Redistributions of source code must retain the above copyright notice,
00119   *      this list of conditions and the following disclaimer.
00120   *   2. Redistributions in binary form must reproduce the above copyright notice,
00121   *      this list of conditions and the following disclaimer in the documentation
00122   *      and/or other materials provided with the distribution.
00123   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00124   *      may be used to endorse or promote products derived from this software
00125   *      without specific prior written permission.
00126   *
00127   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00128   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00129   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00130   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00131   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00132   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00133   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00134   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00135   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00136   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00137   *
00138   ******************************************************************************
00139   */
00140 
00141 /* Includes ------------------------------------------------------------------*/
00142 #include "stm32l4xx_hal.h"
00143 
00144 /** @addtogroup STM32L4xx_HAL_Driver
00145   * @{
00146   */
00147 
00148 /** @defgroup IRDA IRDA
00149   * @brief HAL IRDA module driver
00150   * @{
00151   */
00152 
00153 #ifdef HAL_IRDA_MODULE_ENABLED
00154 
00155 /* Private typedef -----------------------------------------------------------*/
00156 /* Private define ------------------------------------------------------------*/
00157 /** @defgroup IRDA_Private_Constants IRDA Private Constants
00158   * @{
00159   */
00160 #define IRDA_TEACK_REACK_TIMEOUT            1000                                   /*!< IRDA TX or RX enable acknowledge time-out value  */
00161 #define IRDA_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
00162                                    | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))  /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */
00163 /**
00164   * @}
00165   */
00166 
00167 /* Private macros ------------------------------------------------------------*/
00168 /* Private variables ---------------------------------------------------------*/
00169 /* Private function prototypes -----------------------------------------------*/
00170 /** @addtogroup IRDA_Private_Functions
00171   * @{
00172   */
00173 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
00174 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
00175 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
00176 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
00177 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
00178 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00179 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
00180 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00181 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
00182 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
00183 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
00184 /**
00185   * @}
00186   */
00187 
00188 /* Exported functions --------------------------------------------------------*/
00189 
00190 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions
00191   * @{
00192   */
00193 
00194 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
00195   *  @brief    Initialization and Configuration functions
00196   *
00197 @verbatim
00198   ==============================================================================
00199               ##### Initialization and Configuration functions #####
00200   ==============================================================================
00201   [..]
00202   This subsection provides a set of functions allowing to initialize the USARTx
00203   in asynchronous IRDA mode.
00204   (+) For the asynchronous mode only these parameters can be configured:
00205       (++) Baud Rate
00206       (++) Word Length
00207       (++) Parity: If the parity is enabled, then the MSB bit of the data written
00208            in the data register is transmitted but is changed by the parity bit.
00209            Depending on the frame length defined by the M1 and M0 bits (7-bit, 
00210            8-bit or 9-bit), the possible IRDA frame formats are listed in the 
00211            following table.
00212             (+++) Table 1. IRDA frame format.
00213             (+++)    +-----------------------------------------------------------------------+
00214             (+++)    |  M1 bit |  M0 bit |  PCE bit  |             IRDA frame                |
00215             (+++)    |---------|---------|-----------|---------------------------------------|
00216             (+++)    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
00217             (+++)    |---------|---------|-----------|---------------------------------------|
00218             (+++)    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
00219             (+++)    |---------|---------|-----------|---------------------------------------|
00220             (+++)    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
00221             (+++)    |---------|---------|-----------|---------------------------------------|
00222             (+++)    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
00223             (+++)    |---------|---------|-----------|---------------------------------------|
00224             (+++)    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
00225             (+++)    |---------|---------|-----------|---------------------------------------|
00226             (+++)    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
00227             (+++)    +-----------------------------------------------------------------------+
00228 
00229         (++) Power mode
00230         (++) Prescaler setting
00231         (++) Receiver/transmitter modes
00232 
00233   [..]
00234   The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
00235   (details for the procedures are available in reference manual).
00236 
00237 @endverbatim
00238   * @{
00239   */
00240 
00241 /**
00242   * @brief Initialize the IRDA mode according to the specified
00243   *        parameters in the IRDA_InitTypeDef and initialize the associated handle.
00244   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00245   *               the configuration information for the specified IRDA module.
00246   * @retval HAL status
00247   */
00248 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
00249 {
00250   /* Check the IRDA handle allocation */
00251   if(hirda == NULL)
00252   {
00253     return HAL_ERROR;
00254   }
00255 
00256   /* Check the USART/UART associated to the IRDA handle */
00257   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00258 
00259   if(hirda->State == HAL_IRDA_STATE_RESET)
00260   {
00261     /* Allocate lock resource and initialize it */
00262     hirda->Lock = HAL_UNLOCKED;
00263 
00264     /* Init the low level hardware : GPIO, CLOCK */
00265     HAL_IRDA_MspInit(hirda);
00266   }
00267 
00268   hirda->State = HAL_IRDA_STATE_BUSY;
00269 
00270   /* Disable the Peripheral to update the configuration registers */
00271   __HAL_IRDA_DISABLE(hirda);
00272 
00273   /* Set the IRDA Communication parameters */
00274   if (IRDA_SetConfig(hirda) == HAL_ERROR)
00275   {
00276     return HAL_ERROR;
00277   }
00278 
00279   /* In IRDA mode, the following bits must be kept cleared:
00280   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
00281   - SCEN and HDSEL bits in the USART_CR3 register.*/
00282   hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP);
00283   hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL);
00284 
00285   /* set the UART/USART in IRDA mode */
00286   hirda->Instance->CR3 |= USART_CR3_IREN;
00287 
00288   /* Enable the Peripheral */
00289   __HAL_IRDA_ENABLE(hirda);
00290 
00291   /* TEACK and/or REACK to check before moving hirda->State to Ready */
00292   return (IRDA_CheckIdleState(hirda));
00293 }
00294 
00295 /**
00296   * @brief DeInitialize the IRDA peripheral.
00297   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00298   *               the configuration information for the specified IRDA module.
00299   * @retval HAL status
00300   */
00301 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
00302 {
00303   /* Check the IRDA handle allocation */
00304   if(hirda == NULL)
00305   {
00306     return HAL_ERROR;
00307   }
00308 
00309   /* Check the USART/UART associated to the IRDA handle */
00310   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00311 
00312   hirda->State = HAL_IRDA_STATE_BUSY;
00313 
00314   /* DeInit the low level hardware */
00315   HAL_IRDA_MspDeInit(hirda);
00316   /* Disable the Peripheral */
00317   __HAL_IRDA_DISABLE(hirda);
00318 
00319   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00320   hirda->State = HAL_IRDA_STATE_RESET;
00321 
00322   /* Process Unlock */
00323   __HAL_UNLOCK(hirda);
00324 
00325   return HAL_OK;
00326 }
00327 
00328 /**
00329   * @brief Initialize the IRDA MSP.
00330   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00331   *               the configuration information for the specified IRDA module.
00332   * @retval None
00333   */
00334  __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
00335 {
00336   /* NOTE: This function should not be modified, when the callback is needed,
00337            the HAL_IRDA_MspInit can be implemented in the user file
00338    */
00339 }
00340 
00341 /**
00342   * @brief DeInitialize the IRDA MSP.
00343   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00344   *               the configuration information for the specified IRDA module.
00345   * @retval None
00346   */
00347  __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
00348 {
00349   /* NOTE: This function should not be modified, when the callback is needed,
00350            the HAL_IRDA_MspDeInit can be implemented in the user file
00351    */
00352 }
00353 
00354 /**
00355   * @}
00356   */
00357 
00358 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
00359   *  @brief   IRDA Transmit and Receive functions
00360   *
00361 @verbatim
00362   ==============================================================================
00363                          ##### IO operation functions #####
00364   ==============================================================================
00365   [..]
00366     This subsection provides a set of functions allowing to manage the IRDA data transfers.
00367 
00368   [..]
00369     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
00370     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
00371     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
00372     While receiving data, transmission should be avoided as the data to be transmitted
00373     could be corrupted.
00374 
00375     (#) There are two modes of transfer:
00376         (++) Blocking mode: the communication is performed in polling mode.
00377              The HAL status of all data processing is returned by the same function
00378              after finishing transfer.
00379         (++) No-Blocking mode: the communication is performed using Interrupts
00380              or DMA, these API's return the HAL status.
00381              The end of the data processing will be indicated through the
00382              dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
00383              using DMA mode.
00384              The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
00385              will be executed respectively at the end of the Transmit or Receive process
00386              The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
00387 
00388     (#) Blocking mode APIs are :
00389         (++) HAL_IRDA_Transmit()
00390         (++) HAL_IRDA_Receive()
00391 
00392     (#) Non Blocking mode APIs with Interrupt are :
00393         (++) HAL_IRDA_Transmit_IT()
00394         (++) HAL_IRDA_Receive_IT()
00395         (++) HAL_IRDA_IRQHandler()
00396 
00397     (#) Non Blocking mode functions with DMA are :
00398         (++) HAL_IRDA_Transmit_DMA()
00399         (++) HAL_IRDA_Receive_DMA()
00400         (++) HAL_IRDA_DMAPause()
00401         (++) HAL_IRDA_DMAResume()
00402         (++) HAL_IRDA_DMAStop()
00403 
00404     (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
00405         (++) HAL_IRDA_TxHalfCpltCallback()
00406         (++) HAL_IRDA_TxCpltCallback()
00407         (++) HAL_IRDA_RxHalfCpltCallback()
00408         (++) HAL_IRDA_RxCpltCallback()
00409         (++) HAL_IRDA_ErrorCallback()
00410 
00411 @endverbatim
00412   * @{
00413   */
00414 
00415 /**
00416   * @brief Send an amount of data in blocking mode.
00417   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00418   *               the configuration information for the specified IRDA module.
00419   * @param pData: Pointer to data buffer.
00420   * @param Size: Amount of data to be sent.
00421   * @param  Timeout: Specify timeout value.
00422   * @retval HAL status
00423   */
00424 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00425 {
00426   uint16_t* tmp;
00427 
00428   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
00429   {
00430     if((pData == NULL) || (Size == 0))
00431     {
00432       return  HAL_ERROR;
00433     }
00434 
00435     /* Process Locked */
00436     __HAL_LOCK(hirda);
00437 
00438     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00439 
00440     if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
00441     {
00442       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00443     }
00444     else
00445     {
00446       hirda->State = HAL_IRDA_STATE_BUSY_TX;
00447     }
00448 
00449     hirda->TxXferSize = Size;
00450     hirda->TxXferCount = Size;
00451     while(hirda->TxXferCount > 0)
00452     {
00453       hirda->TxXferCount--;
00454 
00455         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK)
00456         {
00457           return HAL_TIMEOUT;
00458         }
00459       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00460         {
00461           tmp = (uint16_t*) pData;
00462           hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
00463           pData +=2;
00464         }
00465         else
00466         {
00467           hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF);
00468         }
00469       }
00470 
00471     if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK)
00472     {
00473       return HAL_TIMEOUT;
00474     }
00475 
00476     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
00477     {
00478       hirda->State = HAL_IRDA_STATE_BUSY_RX;
00479     }
00480     else
00481     {
00482       hirda->State = HAL_IRDA_STATE_READY;
00483     }
00484 
00485     /* Process Unlocked */
00486     __HAL_UNLOCK(hirda);
00487 
00488     return HAL_OK;
00489   }
00490   else
00491   {
00492     return HAL_BUSY;
00493   }
00494 }
00495 
00496 /**
00497   * @brief Receive an amount of data in blocking mode.
00498   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00499   *                the configuration information for the specified IRDA module.
00500   * @param pData: Pointer to data buffer.
00501   * @param Size: Amount of data to be received.
00502   * @param  Timeout: Specify timeout value.
00503   * @retval HAL status
00504   */
00505 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00506 {
00507   uint16_t* tmp;
00508   uint16_t uhMask;
00509 
00510   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
00511   {
00512     if((pData == NULL) || (Size == 0))
00513     {
00514       return  HAL_ERROR;
00515     }
00516 
00517     /* Process Locked */
00518     __HAL_LOCK(hirda);
00519 
00520     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00521 
00522     if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
00523     {
00524       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00525     }
00526     else
00527     {
00528       hirda->State = HAL_IRDA_STATE_BUSY_RX;
00529     }
00530 
00531     hirda->RxXferSize = Size;
00532     hirda->RxXferCount = Size;
00533 
00534     /* Computation of the mask to apply to the RDR register
00535        of the UART associated to the IRDA */
00536     IRDA_MASK_COMPUTATION(hirda);
00537     uhMask = hirda->Mask;
00538 
00539     /* Check data remaining to be received */
00540     while(hirda->RxXferCount > 0)
00541     {
00542       hirda->RxXferCount--;
00543 
00544       if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK)
00545       {
00546         return HAL_TIMEOUT;
00547       }
00548       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00549       {
00550         tmp = (uint16_t*) pData ;
00551         *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
00552         pData +=2;
00553       }
00554       else
00555       {
00556         *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
00557       }
00558     }
00559 
00560     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
00561     {
00562       hirda->State = HAL_IRDA_STATE_BUSY_TX;
00563     }
00564     else
00565     {
00566       hirda->State = HAL_IRDA_STATE_READY;
00567     }
00568 
00569     /* Process Unlocked */
00570     __HAL_UNLOCK(hirda);
00571 
00572     return HAL_OK;
00573   }
00574   else
00575   {
00576     return HAL_BUSY;
00577   }
00578 }
00579 
00580 /**
00581   * @brief Send an amount of data in interrupt mode.
00582   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00583   *                the configuration information for the specified IRDA module.
00584   * @param pData: Pointer to data buffer.
00585   * @param Size: Amount of data to be sent.
00586   * @retval HAL status
00587   */
00588 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00589 {
00590   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
00591   {
00592     if((pData == NULL) || (Size == 0))
00593     {
00594       return HAL_ERROR;
00595     }
00596 
00597     /* Process Locked */
00598     __HAL_LOCK(hirda);
00599 
00600     hirda->pTxBuffPtr = pData;
00601     hirda->TxXferSize = Size;
00602     hirda->TxXferCount = Size;
00603 
00604     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00605 
00606     if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
00607     {
00608       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00609     }
00610     else
00611     {
00612       hirda->State = HAL_IRDA_STATE_BUSY_TX;
00613     }
00614 
00615     /* Process Unlocked */
00616     __HAL_UNLOCK(hirda);
00617 
00618     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
00619     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
00620     /* Enable the IRDA Transmit Data Register Empty Interrupt */
00621     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
00622 
00623     return HAL_OK;
00624   }
00625   else
00626   {
00627     return HAL_BUSY;
00628   }
00629 }
00630 
00631 /**
00632   * @brief Receive an amount of data in interrupt mode.
00633   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00634   *                the configuration information for the specified IRDA module.
00635   * @param pData: Pointer to data buffer.
00636   * @param Size: Amount of data to be received.
00637   * @retval HAL status
00638   */
00639 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00640 {
00641   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
00642   {
00643     if((pData == NULL) || (Size == 0))
00644     {
00645       return HAL_ERROR;
00646     }
00647 
00648     /* Process Locked */
00649   __HAL_LOCK(hirda);
00650 
00651     hirda->pRxBuffPtr = pData;
00652     hirda->RxXferSize = Size;
00653     hirda->RxXferCount = Size;
00654 
00655     /* Computation of the mask to apply to the RDR register
00656        of the UART associated to the IRDA */
00657     IRDA_MASK_COMPUTATION(hirda);
00658 
00659     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00660 
00661     if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
00662     {
00663       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00664     }
00665     else
00666     {
00667       hirda->State = HAL_IRDA_STATE_BUSY_RX;
00668     }
00669 
00670     /* Process Unlocked */
00671     __HAL_UNLOCK(hirda);
00672 
00673     /* Enable the IRDA Data Register not empty Interrupt */
00674     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
00675 
00676     /* Enable the IRDA Parity Error Interrupt */
00677     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
00678 
00679     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
00680     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
00681 
00682     return HAL_OK;
00683   }
00684   else
00685   {
00686     return HAL_BUSY;
00687   }
00688 }
00689 
00690 /**
00691   * @brief Send an amount of data in DMA mode.
00692   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00693   *               the configuration information for the specified IRDA module.
00694   * @param pData: pointer to data buffer.
00695   * @param Size: amount of data to be sent.
00696   * @retval HAL status
00697   */
00698 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00699 {
00700   uint32_t *tmp;
00701 
00702   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
00703   {
00704     if((pData == NULL) || (Size == 0))
00705     {
00706       return HAL_ERROR;
00707     }
00708 
00709     /* Process Locked */
00710     __HAL_LOCK(hirda);
00711 
00712     hirda->pTxBuffPtr = pData;
00713     hirda->TxXferSize = Size;
00714     hirda->TxXferCount = Size;
00715 
00716     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00717 
00718     if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
00719     {
00720       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00721     }
00722     else
00723     {
00724       hirda->State = HAL_IRDA_STATE_BUSY_TX;
00725     }
00726 
00727     /* Set the IRDA DMA transfer complete callback */
00728     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
00729 
00730     /* Set the IRDA DMA half transfer complete callback */
00731     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
00732 
00733     /* Set the DMA error callback */
00734     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
00735 
00736     /* Enable the IRDA transmit DMA channel */
00737     tmp = (uint32_t*)&pData;
00738     HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
00739 
00740     /* Clear the TC flag in the ICR register */
00741     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
00742 
00743     /* Enable the DMA transfer for transmit request by setting the DMAT bit
00744        in the USART CR3 register */
00745     hirda->Instance->CR3 |= USART_CR3_DMAT;
00746 
00747     /* Process Unlocked */
00748     __HAL_UNLOCK(hirda);
00749 
00750     return HAL_OK;
00751   }
00752   else
00753   {
00754     return HAL_BUSY;
00755   }
00756 }
00757 
00758 /**
00759   * @brief Receive an amount of data in DMA mode.
00760   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00761   *               the configuration information for the specified IRDA module.
00762   * @param pData: Pointer to data buffer.
00763   * @param Size: Amount of data to be received.
00764   * @note   When the IRDA parity is enabled (PCE = 1) the received data contains
00765   *         the parity bit (MSB position).
00766   * @retval HAL status
00767   */
00768 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00769 {
00770   uint32_t *tmp;
00771 
00772   if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
00773   {
00774     if((pData == NULL) || (Size == 0))
00775     {
00776       return HAL_ERROR;
00777     }
00778 
00779     /* Process Locked */
00780     __HAL_LOCK(hirda);
00781 
00782     hirda->pRxBuffPtr = pData;
00783     hirda->RxXferSize = Size;
00784 
00785     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00786 
00787     if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
00788     {
00789       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
00790     }
00791     else
00792     {
00793       hirda->State = HAL_IRDA_STATE_BUSY_RX;
00794     }
00795 
00796     /* Set the IRDA DMA transfer complete callback */
00797     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
00798 
00799     /* Set the IRDA DMA half transfer complete callback */
00800     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
00801 
00802     /* Set the DMA error callback */
00803     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
00804 
00805     /* Enable the DMA channel */
00806     tmp = (uint32_t*)&pData;
00807     HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
00808 
00809     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
00810        in the USART CR3 register */
00811      hirda->Instance->CR3 |= USART_CR3_DMAR;
00812 
00813      /* Process Unlocked */
00814      __HAL_UNLOCK(hirda);
00815 
00816     return HAL_OK;
00817   }
00818   else
00819   {
00820     return HAL_BUSY;
00821   }
00822 }
00823 
00824 
00825 /**
00826   * @brief Pause the DMA Transfer.
00827   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00828   *                the configuration information for the specified IRDA module.
00829   * @retval HAL status
00830   */
00831 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
00832 {
00833   /* Process Locked */
00834   __HAL_LOCK(hirda);
00835   
00836   if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
00837   {
00838     /* Disable the IRDA DMA Tx request */
00839     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00840   }
00841   else if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
00842   {
00843     /* Disable the IRDA DMA Rx request */
00844     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00845   }
00846   else if (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
00847   {
00848     /* Disable the IRDA DMA Tx & Rx requests */
00849     CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
00850   }
00851   else
00852   {
00853     /* Process Unlocked */
00854     __HAL_UNLOCK(hirda);
00855   
00856     return HAL_ERROR; 
00857   }
00858 
00859   /* Process Unlocked */
00860   __HAL_UNLOCK(hirda);
00861   
00862   return HAL_OK; 
00863 }
00864 
00865 /**
00866   * @brief Resume the DMA Transfer.
00867   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00868   *                the configuration information for the specified UART module.
00869   * @retval HAL status
00870   */
00871 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
00872 {
00873   /* Process Locked */
00874   __HAL_LOCK(hirda);
00875   
00876   if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
00877   {
00878     /* Enable the IRDA DMA Tx request */
00879     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00880   }
00881   else if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
00882   {
00883     /* Clear the Overrun flag before resuming the Rx transfer*/
00884     __HAL_IRDA_CLEAR_OREFLAG(hirda);
00885     /* Enable the IRDA DMA Rx request */
00886     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00887   }
00888   else if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
00889   {
00890     /* Clear the Overrun flag before resuming the Rx transfer*/
00891     __HAL_IRDA_CLEAR_OREFLAG(hirda);
00892     /* Enable the IRDA DMA Tx & Rx request */
00893     SET_BIT(hirda->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
00894   }
00895   else
00896   {
00897     /* Process Unlocked */
00898     __HAL_UNLOCK(hirda);
00899   
00900     return HAL_ERROR; 
00901   }
00902   
00903   /* Process Unlocked */
00904   __HAL_UNLOCK(hirda);
00905   
00906   return HAL_OK;
00907 }
00908 
00909 /**
00910   * @brief Stop the DMA Transfer.
00911   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00912   *                the configuration information for the specified UART module.
00913   * @retval HAL status
00914   */
00915 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
00916 {
00917   /* The Lock is not implemented on this API to allow the user application
00918      to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
00919      HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: 
00920      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete  
00921      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 
00922      the stream and the corresponding call back is executed. */
00923 
00924   /* Disable the IRDA Tx/Rx DMA requests */
00925   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00926   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00927   
00928   /* Abort the IRDA DMA tx channel */
00929   if(hirda->hdmatx != NULL)
00930   {
00931     HAL_DMA_Abort(hirda->hdmatx);
00932   }
00933   /* Abort the IRDA DMA rx channel */
00934   if(hirda->hdmarx != NULL)
00935   {
00936     HAL_DMA_Abort(hirda->hdmarx);
00937   }
00938   
00939   hirda->State = HAL_IRDA_STATE_READY;
00940 
00941   return HAL_OK;
00942 }
00943 
00944 
00945 /**
00946   * @brief Handle IRDA interrupt request.
00947   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00948   *               the configuration information for the specified IRDA module.
00949   * @retval None
00950   */
00951 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
00952 {
00953   /* IRDA parity error interrupt occurred -------------------------------------*/
00954   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET))
00955   {
00956     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
00957 
00958     hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
00959     /* Set the IRDA state ready to be able to start again the process */
00960     hirda->State = HAL_IRDA_STATE_READY;
00961   }
00962 
00963   /* IRDA frame error interrupt occurred --------------------------------------*/
00964   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00965   {
00966     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
00967 
00968     hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
00969     /* Set the IRDA state ready to be able to start again the process */
00970     hirda->State = HAL_IRDA_STATE_READY;
00971   }
00972 
00973   /* IRDA noise error interrupt occurred --------------------------------------*/
00974   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00975   {
00976     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
00977 
00978     hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
00979     /* Set the IRDA state ready to be able to start again the process */
00980     hirda->State = HAL_IRDA_STATE_READY;
00981   }
00982 
00983   /* IRDA Over-Run interrupt occurred -----------------------------------------*/
00984   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00985   {
00986     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
00987 
00988     hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
00989     /* Set the IRDA state ready to be able to start again the process */
00990     hirda->State = HAL_IRDA_STATE_READY;
00991   }
00992 
00993   /* Call IRDA Error Call back function if need be --------------------------*/
00994   if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
00995   {
00996     HAL_IRDA_ErrorCallback(hirda);
00997   }
00998 
00999   /* IRDA in mode Receiver ---------------------------------------------------*/
01000   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET))
01001   {
01002     IRDA_Receive_IT(hirda);
01003     /* Clear RXNE interrupt flag */
01004     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
01005   }
01006 
01007 
01008   /* IRDA in mode Transmitter ------------------------------------------------*/
01009  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET))
01010   {
01011     IRDA_Transmit_IT(hirda);
01012   }
01013 
01014   /* IRDA in mode Transmitter (transmission end) -----------------------------*/
01015  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET))
01016   {
01017     IRDA_EndTransmit_IT(hirda);
01018   }
01019 
01020 }
01021 
01022 /**
01023   * @brief  Tx Transfer completed callback.
01024   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01025   *                the configuration information for the specified IRDA module.
01026   * @retval None
01027   */
01028  __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
01029 {
01030   /* NOTE: This function should not be modified, when the callback is needed,
01031            the HAL_IRDA_TxCpltCallback can be implemented in the user file.
01032    */
01033 }
01034 
01035 /**
01036   * @brief  Tx Half Transfer completed callback.
01037   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01038   *                the configuration information for the specified USART module.
01039   * @retval None
01040   */
01041  __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
01042 {
01043   /* NOTE: This function should not be modified, when the callback is needed,
01044            the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
01045    */
01046 }
01047 
01048 /**
01049   * @brief  Rx Transfer completed callback.
01050   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01051   *                the configuration information for the specified IRDA module.
01052   * @retval None
01053   */
01054 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
01055 {
01056   /* NOTE: This function should not be modified, when the callback is needed,
01057            the HAL_IRDA_RxCpltCallback can be implemented in the user file.
01058    */
01059 }
01060 
01061 /**
01062   * @brief  Rx Half Transfer complete callback.
01063   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01064   *                the configuration information for the specified IRDA module.
01065   * @retval None
01066   */
01067 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
01068 {
01069   /* NOTE : This function should not be modified, when the callback is needed,
01070             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
01071    */
01072 }
01073 
01074 /**
01075   * @brief  IRDA error callback.
01076   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01077   *                the configuration information for the specified IRDA module.
01078   * @retval None
01079   */
01080  __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
01081 {
01082   /* NOTE: This function should not be modified, when the callback is needed,
01083            the HAL_IRDA_ErrorCallback can be implemented in the user file.
01084    */
01085 }
01086 
01087 /**
01088   * @}
01089   */
01090 
01091 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
01092   *  @brief   IRDA State and Errors functions
01093   *
01094 @verbatim
01095   ==============================================================================
01096                   ##### Peripheral State and Errors functions #####
01097   ==============================================================================
01098   [..]
01099     This subsection provides a set of functions allowing to return the State of IrDA
01100     communication process and also return Peripheral Errors occurred during communication process
01101      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
01102          of the IRDA peripheral handle.
01103      (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
01104          communication.
01105 
01106 @endverbatim
01107   * @{
01108   */
01109 
01110 /**
01111   * @brief Return the IRDA handle state.
01112   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01113   *                the configuration information for the specified IRDA module.
01114   * @retval HAL state
01115   */
01116 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
01117 {
01118   /* Return IRDA handle state */
01119   return hirda->State;
01120 }
01121 
01122 /**
01123   * @brief Return the IRDA handle error code.
01124   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01125   *               the configuration information for the specified IRDA module.
01126   * @retval IRDA Error Code
01127   */
01128 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
01129 {
01130   return hirda->ErrorCode;
01131 }
01132 
01133 /**
01134   * @}
01135   */
01136 
01137 /**
01138   * @}
01139   */
01140 
01141 /** @defgroup IRDA_Private_Functions IRDA Private Functions
01142   * @{
01143   */
01144 
01145 /**
01146   * @brief  DMA IRDA transmit process complete callback.
01147   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01148   *               the configuration information for the specified DMA module.
01149   * @retval None
01150   */
01151 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
01152 {
01153   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01154 
01155   /* DMA Normal mode */
01156   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01157   {
01158     hirda->TxXferCount = 0;
01159 
01160     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
01161        in the IRDA CR3 register */
01162     hirda->Instance->CR3 &= ~(USART_CR3_DMAT);
01163 
01164     /* Enable the IRDA Transmit Complete Interrupt */
01165     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
01166   }
01167   /* DMA Circular mode */
01168   else
01169   {
01170     HAL_IRDA_TxCpltCallback(hirda);
01171   }
01172 }
01173 
01174 /**
01175   * @brief DMA IRDA receive process half complete callback.
01176   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01177   *               the configuration information for the specified DMA module.
01178   * @retval None
01179   */
01180 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
01181 {
01182   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01183 
01184   HAL_IRDA_TxHalfCpltCallback(hirda);
01185 }
01186 
01187 /**
01188   * @brief  DMA IRDA receive process complete callback.
01189   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01190   *               the configuration information for the specified DMA module.
01191   * @retval None
01192   */
01193 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
01194 {
01195   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01196 
01197   /* DMA Normal mode */
01198   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01199   {
01200     hirda->RxXferCount = 0;
01201 
01202     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
01203        in the IRDA CR3 register */
01204     hirda->Instance->CR3 &= ~(USART_CR3_DMAR);
01205 
01206     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
01207     {
01208       hirda->State = HAL_IRDA_STATE_BUSY_TX;
01209     }
01210     else
01211     {
01212       hirda->State = HAL_IRDA_STATE_READY;
01213     }
01214   }
01215 
01216   HAL_IRDA_RxCpltCallback(hirda);
01217 }
01218 
01219 /**
01220   * @brief DMA IRDA receive process half complete callback.
01221   * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
01222   *              the configuration information for the specified DMA module.
01223   * @retval None
01224   */
01225 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
01226 {
01227   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01228 
01229   HAL_IRDA_RxHalfCpltCallback(hirda);
01230 }
01231 
01232 /**
01233   * @brief DMA IRDA communication error callback.
01234   * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
01235   *              the configuration information for the specified DMA module.
01236   * @retval None
01237   */
01238 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
01239 {
01240   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01241 
01242   hirda->RxXferCount = 0;
01243   hirda->TxXferCount = 0;
01244   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
01245   hirda->State= HAL_IRDA_STATE_READY;
01246 
01247   HAL_IRDA_ErrorCallback(hirda);
01248 }
01249 
01250 /**
01251   * @brief  Handle IRDA Communication Timeout.
01252   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01253   *                the configuration information for the specified IRDA module.
01254   * @param  Flag: specifies the IRDA flag to check.
01255   * @param  Status: the new flag status (SET or RESET). The function is locked in a while loop as long as the flag remains set to Status.
01256   * @param  Timeout: Timeout duration
01257   * @retval HAL status
01258   */
01259 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
01260 {
01261   uint32_t tickstart = HAL_GetTick();
01262 
01263   /* Wait until flag is set */
01264   if(Status == RESET)
01265   {
01266     while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET)
01267     {
01268       /* Check for the Timeout */
01269       if(Timeout != HAL_MAX_DELAY)
01270       {
01271         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
01272         {
01273           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
01274           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
01275           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
01276           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
01277           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
01278 
01279           hirda->State= HAL_IRDA_STATE_READY;
01280 
01281           /* Process Unlocked */
01282           __HAL_UNLOCK(hirda);
01283 
01284           return HAL_TIMEOUT;
01285         }
01286       }
01287     }
01288   }
01289   else
01290   {
01291     while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET)
01292     {
01293       /* Check for the Timeout */
01294       if(Timeout != HAL_MAX_DELAY)
01295       {
01296         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
01297         {
01298           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
01299           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
01300           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
01301           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
01302           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
01303 
01304           hirda->State= HAL_IRDA_STATE_READY;
01305 
01306           /* Process Unlocked */
01307           __HAL_UNLOCK(hirda);
01308 
01309           return HAL_TIMEOUT;
01310         }
01311       }
01312     }
01313   }
01314   return HAL_OK;
01315 }
01316 
01317 /**
01318   * @brief  Send an amount of data in non-blocking mode.
01319   * @note   Function is called under interruption only, once
01320   *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
01321   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01322   *                the configuration information for the specified IRDA module.
01323   * @retval HAL status
01324   */
01325 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
01326 {
01327   uint16_t* tmp;
01328 
01329   if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
01330   {
01331     if(hirda->TxXferCount == 0)
01332     {
01333       /* Disable the IRDA Transmit Data Register Empty Interrupt */
01334       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
01335 
01336       /* Enable the IRDA Transmit Complete Interrupt */
01337       __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
01338 
01339       return HAL_OK;
01340     }
01341     else
01342     {
01343       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
01344       {
01345         tmp = (uint16_t*) hirda->pTxBuffPtr;
01346         hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
01347         hirda->pTxBuffPtr += 2;
01348       }
01349       else
01350       {
01351         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF);
01352       }
01353       hirda->TxXferCount--;
01354 
01355       return HAL_OK;
01356     }
01357   }
01358   else
01359   {
01360     return HAL_BUSY;
01361   }
01362 }
01363 
01364 /**
01365   * @brief  Wrap up transmission in non-blocking mode.
01366   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
01367   *                the configuration information for the specified IRDA module.
01368   * @retval HAL status
01369   */
01370 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
01371 {
01372   /* Disable the IRDA Transmit Complete Interrupt */
01373   __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC);
01374 
01375   /* Check if a receive process is ongoing or not */
01376   if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
01377   {
01378     hirda->State = HAL_IRDA_STATE_BUSY_RX;
01379   }
01380   else
01381   {
01382     /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
01383     __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
01384 
01385     hirda->State = HAL_IRDA_STATE_READY;
01386   }
01387 
01388   HAL_IRDA_TxCpltCallback(hirda);
01389 
01390   return HAL_OK;
01391 }
01392 
01393 
01394 /**
01395   * @brief Receive an amount of data in non-blocking mode.
01396   *         Function is called under interruption only, once
01397   *         interruptions have been enabled by HAL_IRDA_Receive_IT().
01398   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01399   *                the configuration information for the specified IRDA module.
01400   * @retval HAL status
01401   */
01402 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
01403 {
01404   uint16_t* tmp;
01405   uint16_t uhMask = hirda->Mask;
01406 
01407   if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
01408   {
01409 
01410     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
01411     {
01412       tmp = (uint16_t*) hirda->pRxBuffPtr ;
01413       *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
01414       hirda->pRxBuffPtr  +=2;
01415     }
01416     else
01417     {
01418       *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
01419     }
01420 
01421     if(--hirda->RxXferCount == 0)
01422     {
01423       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
01424 
01425       if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
01426       {
01427         hirda->State = HAL_IRDA_STATE_BUSY_TX;
01428       }
01429       else
01430       {
01431         /* Disable the IRDA Parity Error Interrupt */
01432         __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
01433 
01434         /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
01435         __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
01436 
01437         hirda->State = HAL_IRDA_STATE_READY;
01438       }
01439 
01440       HAL_IRDA_RxCpltCallback(hirda);
01441 
01442       return HAL_OK;
01443     }
01444 
01445     return HAL_OK;
01446   }
01447   else
01448   {
01449     return HAL_BUSY;
01450   }
01451 }
01452 
01453 /**
01454   * @brief Configure the IRDA peripheral.
01455   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01456   *               the configuration information for the specified IRDA module.
01457   * @retval None
01458   */
01459 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
01460 {
01461   uint32_t tmpreg                     = 0x00000000;
01462   IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED;
01463   HAL_StatusTypeDef ret               = HAL_OK;
01464 
01465   /* Check the communication parameters */
01466   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
01467   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
01468   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
01469   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
01470   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
01471   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
01472 
01473   /*-------------------------- USART CR1 Configuration -----------------------*/
01474   /* Configure the IRDA Word Length, Parity and transfer Mode:
01475      Set the M bits according to hirda->Init.WordLength value
01476      Set PCE and PS bits according to hirda->Init.Parity value
01477      Set TE and RE bits according to hirda->Init.Mode value */
01478   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
01479 
01480   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
01481 
01482   /*-------------------------- USART CR3 Configuration -----------------------*/
01483   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
01484 
01485   /*-------------------------- USART GTPR Configuration ----------------------*/
01486   MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
01487 
01488   /*-------------------------- USART BRR Configuration -----------------------*/
01489   IRDA_GETCLOCKSOURCE(hirda, clocksource);
01490   switch (clocksource)
01491   {
01492     case IRDA_CLOCKSOURCE_PCLK1:
01493       hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hirda->Init.BaudRate);
01494       break;
01495     case IRDA_CLOCKSOURCE_PCLK2:
01496       hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hirda->Init.BaudRate);
01497       break;
01498     case IRDA_CLOCKSOURCE_HSI:
01499       hirda->Instance->BRR = (uint16_t)(HSI_VALUE / hirda->Init.BaudRate);
01500       break;
01501     case IRDA_CLOCKSOURCE_SYSCLK:
01502       hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hirda->Init.BaudRate);
01503       break;
01504     case IRDA_CLOCKSOURCE_LSE:
01505       hirda->Instance->BRR = (uint16_t)(LSE_VALUE / hirda->Init.BaudRate);
01506       break;
01507     case IRDA_CLOCKSOURCE_UNDEFINED:
01508     default:
01509       ret = HAL_ERROR;
01510       break;
01511   }
01512 
01513   return ret;
01514 }
01515 
01516 /**
01517   * @brief Check the IRDA Idle State.
01518   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01519   *               the configuration information for the specified IRDA module.
01520   * @retval HAL status
01521   */
01522 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
01523 {
01524 
01525   /* Initialize the IRDA ErrorCode */
01526   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01527 
01528   /* Check if the Transmitter is enabled */
01529   if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
01530   {
01531     /* Wait until TEACK flag is set */
01532     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
01533     {
01534       /* Timeout occurred */
01535       return HAL_TIMEOUT;
01536     }
01537   }
01538   /* Check if the Receiver is enabled */
01539   if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
01540   {
01541     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
01542     {
01543       /* Timeout occurred */
01544       return HAL_TIMEOUT;
01545     }
01546   }
01547 
01548   /* Initialize the IRDA state*/
01549   hirda->State= HAL_IRDA_STATE_READY;
01550   /* Process Unlocked */
01551   __HAL_UNLOCK(hirda);
01552 
01553   return HAL_OK;
01554 }
01555 
01556 /**
01557   * @}
01558   */
01559 
01560 #endif /* HAL_IRDA_MODULE_ENABLED */
01561 /**
01562   * @}
01563   */
01564 
01565 /**
01566   * @}
01567   */
01568 
01569 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01570