TUKS MCU Introductory course / TUKS-COURSE-2-LED
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.5.1
00006   * @date    31-May-2016
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) 2016 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 Tickstart, 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       (++) Power mode
00210       (++) Prescaler setting
00211       (++) Receiver/transmitter modes
00212 
00213   [..]
00214   The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
00215   (details for the procedures are available in reference manual).
00216 
00217 @endverbatim
00218 
00219   Depending on the frame length defined by the M1 and M0 bits (7-bit, 
00220   8-bit or 9-bit), the possible IRDA frame formats are listed in the 
00221   following table.
00222   
00223     Table 1. IRDA frame format.
00224     +-----------------------------------------------------------------------+
00225     |  M1 bit |  M0 bit |  PCE bit  |             IRDA frame                |
00226     |---------|---------|-----------|---------------------------------------|
00227     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
00228     |---------|---------|-----------|---------------------------------------|
00229     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
00230     |---------|---------|-----------|---------------------------------------|
00231     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
00232     |---------|---------|-----------|---------------------------------------|
00233     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
00234     |---------|---------|-----------|---------------------------------------|
00235     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
00236     |---------|---------|-----------|---------------------------------------|
00237     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
00238     +-----------------------------------------------------------------------+
00239 
00240   * @{
00241   */
00242 
00243 /**
00244   * @brief Initialize the IRDA mode according to the specified
00245   *        parameters in the IRDA_InitTypeDef and initialize the associated handle.
00246   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00247   *               the configuration information for the specified IRDA module.
00248   * @retval HAL status
00249   */
00250 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
00251 {
00252   /* Check the IRDA handle allocation */
00253   if(hirda == NULL)
00254   {
00255     return HAL_ERROR;
00256   }
00257 
00258   /* Check the USART/UART associated to the IRDA handle */
00259   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00260 
00261   if(hirda->gState == HAL_IRDA_STATE_RESET)
00262   {
00263     /* Allocate lock resource and initialize it */
00264     hirda->Lock = HAL_UNLOCKED;
00265 
00266     /* Init the low level hardware : GPIO, CLOCK */
00267     HAL_IRDA_MspInit(hirda);
00268   }
00269 
00270   hirda->gState = HAL_IRDA_STATE_BUSY;
00271 
00272   /* Disable the Peripheral to update the configuration registers */
00273   __HAL_IRDA_DISABLE(hirda);
00274 
00275   /* Set the IRDA Communication parameters */
00276   if (IRDA_SetConfig(hirda) == HAL_ERROR)
00277   {
00278     return HAL_ERROR;
00279   }
00280 
00281   /* In IRDA mode, the following bits must be kept cleared:
00282   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
00283   - SCEN and HDSEL bits in the USART_CR3 register.*/
00284   hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP);
00285   hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL);
00286 
00287   /* set the UART/USART in IRDA mode */
00288   hirda->Instance->CR3 |= USART_CR3_IREN;
00289 
00290   /* Enable the Peripheral */
00291   __HAL_IRDA_ENABLE(hirda);
00292 
00293   /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */
00294   return (IRDA_CheckIdleState(hirda));
00295 }
00296 
00297 /**
00298   * @brief DeInitialize the IRDA peripheral.
00299   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00300   *               the configuration information for the specified IRDA module.
00301   * @retval HAL status
00302   */
00303 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
00304 {
00305   /* Check the IRDA handle allocation */
00306   if(hirda == NULL)
00307   {
00308     return HAL_ERROR;
00309   }
00310 
00311   /* Check the USART/UART associated to the IRDA handle */
00312   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
00313 
00314   hirda->gState = HAL_IRDA_STATE_BUSY;
00315 
00316   /* DeInit the low level hardware */
00317   HAL_IRDA_MspDeInit(hirda);
00318   /* Disable the Peripheral */
00319   __HAL_IRDA_DISABLE(hirda);
00320 
00321   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00322   hirda->gState    = HAL_IRDA_STATE_RESET;
00323   hirda->RxState   = HAL_IRDA_STATE_RESET;
00324 
00325   /* Process Unlock */
00326   __HAL_UNLOCK(hirda);
00327 
00328   return HAL_OK;
00329 }
00330 
00331 /**
00332   * @brief Initialize the IRDA MSP.
00333   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00334   *               the configuration information for the specified IRDA module.
00335   * @retval None
00336   */
00337 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
00338 {
00339   /* Prevent unused argument(s) compilation warning */
00340   UNUSED(hirda);
00341 
00342   /* NOTE: This function should not be modified, when the callback is needed,
00343            the HAL_IRDA_MspInit can be implemented in the user file
00344    */
00345 }
00346 
00347 /**
00348   * @brief DeInitialize the IRDA MSP.
00349   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00350   *               the configuration information for the specified IRDA module.
00351   * @retval None
00352   */
00353 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
00354 {
00355   /* Prevent unused argument(s) compilation warning */
00356   UNUSED(hirda);
00357 
00358   /* NOTE: This function should not be modified, when the callback is needed,
00359            the HAL_IRDA_MspDeInit can be implemented in the user file
00360    */
00361 }
00362 
00363 /**
00364   * @}
00365   */
00366 
00367 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
00368   *  @brief   IRDA Transmit and Receive functions
00369   *
00370 @verbatim
00371   ==============================================================================
00372                          ##### IO operation functions #####
00373   ==============================================================================
00374   [..]
00375     This subsection provides a set of functions allowing to manage the IRDA data transfers.
00376 
00377   [..]
00378     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
00379     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
00380     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
00381     While receiving data, transmission should be avoided as the data to be transmitted
00382     could be corrupted.
00383 
00384     (#) There are two modes of transfer:
00385         (++) Blocking mode: the communication is performed in polling mode.
00386              The HAL status of all data processing is returned by the same function
00387              after finishing transfer.
00388         (++) No-Blocking mode: the communication is performed using Interrupts
00389              or DMA, these API's return the HAL status.
00390              The end of the data processing will be indicated through the
00391              dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
00392              using DMA mode.
00393              The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
00394              will be executed respectively at the end of the Transmit or Receive process
00395              The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
00396 
00397     (#) Blocking mode APIs are :
00398         (++) HAL_IRDA_Transmit()
00399         (++) HAL_IRDA_Receive()
00400 
00401     (#) Non Blocking mode APIs with Interrupt are :
00402         (++) HAL_IRDA_Transmit_IT()
00403         (++) HAL_IRDA_Receive_IT()
00404         (++) HAL_IRDA_IRQHandler()
00405 
00406     (#) Non Blocking mode functions with DMA are :
00407         (++) HAL_IRDA_Transmit_DMA()
00408         (++) HAL_IRDA_Receive_DMA()
00409         (++) HAL_IRDA_DMAPause()
00410         (++) HAL_IRDA_DMAResume()
00411         (++) HAL_IRDA_DMAStop()
00412 
00413     (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
00414         (++) HAL_IRDA_TxHalfCpltCallback()
00415         (++) HAL_IRDA_TxCpltCallback()
00416         (++) HAL_IRDA_RxHalfCpltCallback()
00417         (++) HAL_IRDA_RxCpltCallback()
00418         (++) HAL_IRDA_ErrorCallback()
00419 
00420 @endverbatim
00421   * @{
00422   */
00423 
00424 /**
00425   * @brief Send an amount of data in blocking mode.
00426   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00427   *               the configuration information for the specified IRDA module.
00428   * @param pData: Pointer to data buffer.
00429   * @param Size: Amount of data to be sent.
00430   * @param  Timeout: Specify timeout value.
00431   * @retval HAL status
00432   */
00433 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00434 {
00435   uint16_t* tmp;
00436   uint32_t tickstart = 0;
00437 
00438   /* Check that a Tx process is not already ongoing */
00439   if(hirda->gState == HAL_IRDA_STATE_READY)
00440   {
00441     if((pData == NULL) || (Size == 0))
00442     {
00443       return  HAL_ERROR;
00444     }
00445 
00446     /* Process Locked */
00447     __HAL_LOCK(hirda);
00448 
00449     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00450 
00451     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00452 
00453     /* Init tickstart for timeout managment*/
00454     tickstart = HAL_GetTick();
00455 
00456     hirda->TxXferSize = Size;
00457     hirda->TxXferCount = Size;
00458     while(hirda->TxXferCount > 0)
00459     {
00460       hirda->TxXferCount--;
00461 
00462       if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
00463       {
00464         return HAL_TIMEOUT;
00465       }
00466       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00467       {
00468         tmp = (uint16_t*) pData;
00469         hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
00470         pData +=2;
00471       }
00472       else
00473       {
00474         hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF);
00475       }
00476     }
00477 
00478     if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00479     {
00480       return HAL_TIMEOUT;
00481     }
00482 
00483     /* At end of Tx process, restore hirda->gState to Ready */
00484     hirda->gState = HAL_IRDA_STATE_READY;
00485 
00486     /* Process Unlocked */
00487     __HAL_UNLOCK(hirda);
00488 
00489     return HAL_OK;
00490   }
00491   else
00492   {
00493     return HAL_BUSY;
00494   }
00495 }
00496 
00497 /**
00498   * @brief Receive an amount of data in blocking mode.
00499   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00500   *                the configuration information for the specified IRDA module.
00501   * @param pData: Pointer to data buffer.
00502   * @param Size: Amount of data to be received.
00503   * @param  Timeout: Specify timeout value.
00504   * @retval HAL status
00505   */
00506 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00507 {
00508   uint16_t* tmp;
00509   uint16_t uhMask;
00510   uint32_t tickstart = 0;
00511 
00512   /* Check that a Rx process is not already ongoing */
00513   if(hirda->RxState == HAL_IRDA_STATE_READY)
00514   {
00515     if((pData == NULL) || (Size == 0))
00516     {
00517       return  HAL_ERROR;
00518     }
00519 
00520     /* Process Locked */
00521     __HAL_LOCK(hirda);
00522 
00523     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00524 
00525     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00526 
00527     /* Init tickstart for timeout managment*/
00528     tickstart = HAL_GetTick();
00529 
00530     hirda->RxXferSize = Size;
00531     hirda->RxXferCount = Size;
00532 
00533     /* Computation of the mask to apply to the RDR register
00534        of the UART associated to the IRDA */
00535     IRDA_MASK_COMPUTATION(hirda);
00536     uhMask = hirda->Mask;
00537 
00538     /* Check data remaining to be received */
00539     while(hirda->RxXferCount > 0)
00540     {
00541       hirda->RxXferCount--;
00542 
00543       if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00544       {
00545         return HAL_TIMEOUT;
00546       }
00547       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
00548       {
00549         tmp = (uint16_t*) pData ;
00550         *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
00551         pData +=2;
00552       }
00553       else
00554       {
00555         *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
00556       }
00557     }
00558 
00559     /* At end of Rx process, restore hirda->RxState to Ready */
00560     hirda->RxState = HAL_IRDA_STATE_READY;
00561 
00562     /* Process Unlocked */
00563     __HAL_UNLOCK(hirda);
00564 
00565     return HAL_OK;
00566   }
00567   else
00568   {
00569     return HAL_BUSY;
00570   }
00571 }
00572 
00573 /**
00574   * @brief Send an amount of data in interrupt mode.
00575   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00576   *                the configuration information for the specified IRDA module.
00577   * @param pData: Pointer to data buffer.
00578   * @param Size: Amount of data to be sent.
00579   * @retval HAL status
00580   */
00581 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00582 {
00583   /* Check that a Tx process is not already ongoing */
00584   if(hirda->gState == HAL_IRDA_STATE_READY)
00585   {
00586     if((pData == NULL) || (Size == 0))
00587     {
00588       return HAL_ERROR;
00589     }
00590 
00591     /* Process Locked */
00592     __HAL_LOCK(hirda);
00593 
00594     hirda->pTxBuffPtr = pData;
00595     hirda->TxXferSize = Size;
00596     hirda->TxXferCount = Size;
00597 
00598     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00599 
00600     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00601 
00602     /* Process Unlocked */
00603     __HAL_UNLOCK(hirda);
00604 
00605     /* Enable the IRDA Transmit Data Register Empty Interrupt */
00606     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
00607 
00608     return HAL_OK;
00609   }
00610   else
00611   {
00612     return HAL_BUSY;
00613   }
00614 }
00615 
00616 /**
00617   * @brief Receive an amount of data in interrupt mode.
00618   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00619   *                the configuration information for the specified IRDA module.
00620   * @param pData: Pointer to data buffer.
00621   * @param Size: Amount of data to be received.
00622   * @retval HAL status
00623   */
00624 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00625 {
00626   /* Check that a Rx process is not already ongoing */
00627   if(hirda->RxState == HAL_IRDA_STATE_READY)
00628   {
00629     if((pData == NULL) || (Size == 0))
00630     {
00631       return HAL_ERROR;
00632     }
00633 
00634     /* Process Locked */
00635   __HAL_LOCK(hirda);
00636 
00637     hirda->pRxBuffPtr = pData;
00638     hirda->RxXferSize = Size;
00639     hirda->RxXferCount = Size;
00640 
00641     /* Computation of the mask to apply to the RDR register
00642        of the UART associated to the IRDA */
00643     IRDA_MASK_COMPUTATION(hirda);
00644 
00645     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00646 
00647     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00648 
00649     /* Process Unlocked */
00650     __HAL_UNLOCK(hirda);
00651 
00652     /* Enable the IRDA Data Register not empty Interrupt */
00653     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
00654 
00655     /* Enable the IRDA Parity Error Interrupt */
00656     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
00657 
00658     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
00659     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
00660 
00661     return HAL_OK;
00662   }
00663   else
00664   {
00665     return HAL_BUSY;
00666   }
00667 }
00668 
00669 /**
00670   * @brief Send an amount of data in DMA mode.
00671   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00672   *               the configuration information for the specified IRDA module.
00673   * @param pData: pointer to data buffer.
00674   * @param Size: amount of data to be sent.
00675   * @retval HAL status
00676   */
00677 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00678 {
00679   uint32_t *tmp;
00680 
00681   /* Check that a Tx process is not already ongoing */
00682   if(hirda->gState == HAL_IRDA_STATE_READY)
00683   {
00684     if((pData == NULL) || (Size == 0))
00685     {
00686       return HAL_ERROR;
00687     }
00688 
00689     /* Process Locked */
00690     __HAL_LOCK(hirda);
00691 
00692     hirda->pTxBuffPtr = pData;
00693     hirda->TxXferSize = Size;
00694     hirda->TxXferCount = Size;
00695 
00696     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00697 
00698     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
00699 
00700     /* Set the IRDA DMA transfer complete callback */
00701     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
00702 
00703     /* Set the IRDA DMA half transfer complete callback */
00704     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
00705 
00706     /* Set the DMA error callback */
00707     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
00708 
00709     /* Enable the IRDA transmit DMA channel */
00710     tmp = (uint32_t*)&pData;
00711     HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
00712 
00713     /* Clear the TC flag in the ICR register */
00714     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
00715 
00716     /* Enable the DMA transfer for transmit request by setting the DMAT bit
00717        in the USART CR3 register */
00718     hirda->Instance->CR3 |= USART_CR3_DMAT;
00719 
00720     /* Process Unlocked */
00721     __HAL_UNLOCK(hirda);
00722 
00723     return HAL_OK;
00724   }
00725   else
00726   {
00727     return HAL_BUSY;
00728   }
00729 }
00730 
00731 /**
00732   * @brief Receive an amount of data in DMA mode.
00733   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00734   *               the configuration information for the specified IRDA module.
00735   * @param pData: Pointer to data buffer.
00736   * @param Size: Amount of data to be received.
00737   * @note   When the IRDA parity is enabled (PCE = 1) the received data contains
00738   *         the parity bit (MSB position).
00739   * @retval HAL status
00740   */
00741 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
00742 {
00743   uint32_t *tmp;
00744 
00745   /* Check that a Rx process is not already ongoing */
00746   if(hirda->RxState == HAL_IRDA_STATE_READY)
00747   {
00748     if((pData == NULL) || (Size == 0))
00749     {
00750       return HAL_ERROR;
00751     }
00752 
00753     /* Process Locked */
00754     __HAL_LOCK(hirda);
00755 
00756     hirda->pRxBuffPtr = pData;
00757     hirda->RxXferSize = Size;
00758 
00759     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
00760 
00761     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
00762 
00763     /* Set the IRDA DMA transfer complete callback */
00764     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
00765 
00766     /* Set the IRDA DMA half transfer complete callback */
00767     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
00768 
00769     /* Set the DMA error callback */
00770     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
00771 
00772     /* Enable the DMA channel */
00773     tmp = (uint32_t*)&pData;
00774     HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
00775 
00776     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
00777        in the USART CR3 register */
00778      hirda->Instance->CR3 |= USART_CR3_DMAR;
00779 
00780      /* Process Unlocked */
00781      __HAL_UNLOCK(hirda);
00782 
00783     return HAL_OK;
00784   }
00785   else
00786   {
00787     return HAL_BUSY;
00788   }
00789 }
00790 
00791 
00792 /**
00793   * @brief Pause the DMA Transfer.
00794   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00795   *                the configuration information for the specified IRDA module.
00796   * @retval HAL status
00797   */
00798 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
00799 {
00800   /* Process Locked */
00801   __HAL_LOCK(hirda);
00802   
00803   if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
00804   {
00805     /* Disable the IRDA DMA Tx request */
00806     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00807   }
00808   if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
00809   {
00810     /* Disable the IRDA DMA Rx request */
00811     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00812   }
00813 
00814   /* Process Unlocked */
00815   __HAL_UNLOCK(hirda);
00816   
00817   return HAL_OK; 
00818 }
00819 
00820 /**
00821   * @brief Resume the DMA Transfer.
00822   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00823   *                the configuration information for the specified UART module.
00824   * @retval HAL status
00825   */
00826 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
00827 {
00828   /* Process Locked */
00829   __HAL_LOCK(hirda);
00830 
00831   if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
00832   {
00833     /* Enable the IRDA DMA Tx request */
00834     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00835   }
00836   if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
00837   {
00838     /* Clear the Overrun flag before resuming the Rx transfer*/
00839     __HAL_IRDA_CLEAR_OREFLAG(hirda);
00840     /* Enable the IRDA DMA Rx request */
00841     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00842   }
00843 
00844   /* Process Unlocked */
00845   __HAL_UNLOCK(hirda);
00846 
00847   return HAL_OK;
00848 }
00849 
00850 /**
00851   * @brief Stop the DMA Transfer.
00852   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00853   *                the configuration information for the specified UART module.
00854   * @retval HAL status
00855   */
00856 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
00857 {
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      HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: 
00861      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete  
00862      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 
00863      the stream and the corresponding call back is executed. */
00864 
00865   /* Disable the IRDA Tx/Rx DMA requests */
00866   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
00867   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
00868   
00869   /* Abort the IRDA DMA tx channel */
00870   if(hirda->hdmatx != NULL)
00871   {
00872     HAL_DMA_Abort(hirda->hdmatx);
00873   }
00874   /* Abort the IRDA DMA rx channel */
00875   if(hirda->hdmarx != NULL)
00876   {
00877     HAL_DMA_Abort(hirda->hdmarx);
00878   }
00879   
00880   hirda->gState = HAL_IRDA_STATE_READY;
00881   hirda->RxState = HAL_IRDA_STATE_READY;
00882 
00883   return HAL_OK;
00884 }
00885 
00886 
00887 /**
00888   * @brief Handle IRDA interrupt request.
00889   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00890   *               the configuration information for the specified IRDA module.
00891   * @retval None
00892   */
00893 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
00894 {
00895   /* IRDA parity error interrupt occurred -------------------------------------*/
00896   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET))
00897   {
00898     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
00899 
00900     hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
00901     /* Set the IRDA Rx state ready to be able to start again the process */
00902     hirda->RxState = HAL_IRDA_STATE_READY;
00903   }
00904 
00905   /* IRDA frame error interrupt occurred --------------------------------------*/
00906   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00907   {
00908     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
00909 
00910     hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
00911     /* Set the IRDA Rx state ready to be able to start again the process */
00912     hirda->RxState = HAL_IRDA_STATE_READY;
00913   }
00914 
00915   /* IRDA noise error interrupt occurred --------------------------------------*/
00916   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00917   {
00918     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
00919 
00920     hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
00921     /* Set the IRDA Rx state ready to be able to start again the process */
00922     hirda->RxState = HAL_IRDA_STATE_READY;
00923   }
00924 
00925   /* IRDA Over-Run interrupt occurred -----------------------------------------*/
00926   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
00927   {
00928     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
00929 
00930     hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
00931     /* Set the IRDA Rx state ready to be able to start again the process */
00932     hirda->RxState = HAL_IRDA_STATE_READY;
00933   }
00934 
00935   /* Call IRDA Error Call back function if need be --------------------------*/
00936   if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
00937   {
00938     HAL_IRDA_ErrorCallback(hirda);
00939   }
00940 
00941   /* IRDA in mode Receiver ---------------------------------------------------*/
00942   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET))
00943   {
00944     IRDA_Receive_IT(hirda);
00945   }
00946 
00947 
00948   /* IRDA in mode Transmitter ------------------------------------------------*/
00949  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET))
00950   {
00951     IRDA_Transmit_IT(hirda);
00952   }
00953 
00954   /* IRDA in mode Transmitter (transmission end) -----------------------------*/
00955  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET))
00956   {
00957     IRDA_EndTransmit_IT(hirda);
00958   }
00959 
00960 }
00961 
00962 /**
00963   * @brief  Tx Transfer completed callback.
00964   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00965   *                the configuration information for the specified IRDA module.
00966   * @retval None
00967   */
00968 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
00969 {
00970   /* Prevent unused argument(s) compilation warning */
00971   UNUSED(hirda);
00972 
00973   /* NOTE: This function should not be modified, when the callback is needed,
00974            the HAL_IRDA_TxCpltCallback can be implemented in the user file.
00975    */
00976 }
00977 
00978 /**
00979   * @brief  Tx Half Transfer completed callback.
00980   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00981   *                the configuration information for the specified USART module.
00982   * @retval None
00983   */
00984 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
00985 {
00986   /* Prevent unused argument(s) compilation warning */
00987   UNUSED(hirda);
00988 
00989   /* NOTE: This function should not be modified, when the callback is needed,
00990            the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
00991    */
00992 }
00993 
00994 /**
00995   * @brief  Rx Transfer completed callback.
00996   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
00997   *                the configuration information for the specified IRDA module.
00998   * @retval None
00999   */
01000 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
01001 {
01002   /* Prevent unused argument(s) compilation warning */
01003   UNUSED(hirda);
01004 
01005   /* NOTE: This function should not be modified, when the callback is needed,
01006            the HAL_IRDA_RxCpltCallback can be implemented in the user file.
01007    */
01008 }
01009 
01010 /**
01011   * @brief  Rx Half Transfer complete callback.
01012   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01013   *                the configuration information for the specified IRDA module.
01014   * @retval None
01015   */
01016 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
01017 {
01018   /* Prevent unused argument(s) compilation warning */
01019   UNUSED(hirda);
01020 
01021   /* NOTE : This function should not be modified, when the callback is needed,
01022             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
01023    */
01024 }
01025 
01026 /**
01027   * @brief  IRDA error callback.
01028   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01029   *                the configuration information for the specified IRDA module.
01030   * @retval None
01031   */
01032  __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
01033 {
01034   /* Prevent unused argument(s) compilation warning */
01035   UNUSED(hirda);
01036 
01037   /* NOTE: This function should not be modified, when the callback is needed,
01038            the HAL_IRDA_ErrorCallback can be implemented in the user file.
01039    */
01040 }
01041 
01042 /**
01043   * @}
01044   */
01045 
01046 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
01047   *  @brief   IRDA State and Errors functions
01048   *
01049 @verbatim
01050   ==============================================================================
01051                   ##### Peripheral State and Errors functions #####
01052   ==============================================================================
01053   [..]
01054     This subsection provides a set of functions allowing to return the State of IrDA
01055     communication process and also return Peripheral Errors occurred during communication process
01056      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
01057          of the IRDA peripheral handle.
01058      (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
01059          communication.
01060 
01061 @endverbatim
01062   * @{
01063   */
01064 
01065 /**
01066   * @brief  Return the IRDA handle state.
01067   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01068   *                the configuration information for the specified IRDA module.
01069   * @retval HAL state
01070   */
01071 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
01072 {
01073   /* Return IRDA handle state */
01074   uint32_t temp1= 0x00, temp2 = 0x00;
01075   temp1 = hirda->gState;
01076   temp2 = hirda->RxState;
01077   
01078   return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
01079 }
01080 
01081 /**
01082   * @brief Return the IRDA handle error code.
01083   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01084   *               the configuration information for the specified IRDA module.
01085   * @retval IRDA Error Code
01086   */
01087 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
01088 {
01089   return hirda->ErrorCode;
01090 }
01091 
01092 /**
01093   * @}
01094   */
01095 
01096 /**
01097   * @}
01098   */
01099 
01100 /** @defgroup IRDA_Private_Functions IRDA Private Functions
01101   * @{
01102   */
01103 
01104 /**
01105   * @brief  DMA IRDA transmit process complete callback.
01106   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01107   *               the configuration information for the specified DMA module.
01108   * @retval None
01109   */
01110 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
01111 {
01112   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01113 
01114   /* DMA Normal mode */
01115   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01116   {
01117     hirda->TxXferCount = 0;
01118 
01119     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
01120        in the IRDA CR3 register */
01121     hirda->Instance->CR3 &= ~(USART_CR3_DMAT);
01122 
01123     /* Enable the IRDA Transmit Complete Interrupt */
01124     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
01125   }
01126   /* DMA Circular mode */
01127   else
01128   {
01129     HAL_IRDA_TxCpltCallback(hirda);
01130   }
01131 }
01132 
01133 /**
01134   * @brief DMA IRDA receive process half complete callback.
01135   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01136   *               the configuration information for the specified DMA module.
01137   * @retval None
01138   */
01139 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
01140 {
01141   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01142 
01143   HAL_IRDA_TxHalfCpltCallback(hirda);
01144 }
01145 
01146 /**
01147   * @brief  DMA IRDA receive process complete callback.
01148   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
01149   *               the configuration information for the specified DMA module.
01150   * @retval None
01151   */
01152 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
01153 {
01154   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01155 
01156   /* DMA Normal mode */
01157   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01158   {
01159     hirda->RxXferCount = 0;
01160 
01161     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
01162        in the IRDA CR3 register */
01163     hirda->Instance->CR3 &= ~(USART_CR3_DMAR);
01164 
01165     /* At end of Rx process, restore hirda->RxState to Ready */
01166     hirda->RxState = HAL_IRDA_STATE_READY;
01167   }
01168 
01169   HAL_IRDA_RxCpltCallback(hirda);
01170 }
01171 
01172 /**
01173   * @brief DMA IRDA receive process half complete callback.
01174   * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
01175   *              the configuration information for the specified DMA module.
01176   * @retval None
01177   */
01178 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
01179 {
01180   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01181 
01182   HAL_IRDA_RxHalfCpltCallback(hirda);
01183 }
01184 
01185 /**
01186   * @brief DMA IRDA communication error callback.
01187   * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
01188   *              the configuration information for the specified DMA module.
01189   * @retval None
01190   */
01191 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
01192 {
01193   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01194 
01195   hirda->RxXferCount = 0;
01196   hirda->TxXferCount = 0;
01197   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
01198   hirda->gState     = HAL_IRDA_STATE_READY;
01199   hirda->RxState    = HAL_IRDA_STATE_READY;
01200 
01201   HAL_IRDA_ErrorCallback(hirda);
01202 }
01203 
01204 /**
01205   * @brief  Handle IRDA Communication Timeout.
01206   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
01207   *               the configuration information for the specified IRDA module.
01208   * @param  Flag Specifies the IRDA flag to check.
01209   * @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.
01210   * @param  Tickstart Tick start value
01211   * @param  Timeout Timeout duration
01212   * @retval HAL status
01213   */
01214 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
01215 {
01216   /* Wait until flag is set */
01217   while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
01218   {
01219     /* Check for the Timeout */
01220     if(Timeout != HAL_MAX_DELAY)
01221     {
01222       if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout))
01223       {
01224         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
01225         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
01226         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
01227 
01228         hirda->gState= HAL_IRDA_STATE_READY;
01229         hirda->RxState= HAL_IRDA_STATE_READY;
01230 
01231         /* Process Unlocked */
01232         __HAL_UNLOCK(hirda);
01233 
01234         return HAL_TIMEOUT;
01235       }
01236     }
01237   }
01238   return HAL_OK;
01239 }
01240 
01241 /**
01242   * @brief  Send an amount of data in non-blocking mode.
01243   * @note   Function is called under interruption only, once
01244   *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
01245   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01246   *                the configuration information for the specified IRDA module.
01247   * @retval HAL status
01248   */
01249 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
01250 {
01251   uint16_t* tmp;
01252 
01253   /* Check that a Tx process is ongoing */
01254   if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
01255   {
01256     if(hirda->TxXferCount == 0)
01257     {
01258       /* Disable the IRDA Transmit Data Register Empty Interrupt */
01259       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
01260 
01261       /* Enable the IRDA Transmit Complete Interrupt */
01262       __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
01263 
01264       return HAL_OK;
01265     }
01266     else
01267     {
01268       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
01269       {
01270         tmp = (uint16_t*) hirda->pTxBuffPtr;
01271         hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
01272         hirda->pTxBuffPtr += 2;
01273       }
01274       else
01275       {
01276         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF);
01277       }
01278       hirda->TxXferCount--;
01279 
01280       return HAL_OK;
01281     }
01282   }
01283   else
01284   {
01285     return HAL_BUSY;
01286   }
01287 }
01288 
01289 /**
01290   * @brief  Wrap up transmission in non-blocking mode.
01291   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
01292   *                the configuration information for the specified IRDA module.
01293   * @retval HAL status
01294   */
01295 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
01296 {
01297   /* Disable the IRDA Transmit Complete Interrupt */
01298   __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC);
01299 
01300   /* Tx process is ended, restore hirda->gState to Ready */
01301   hirda->gState = HAL_IRDA_STATE_READY;
01302 
01303   HAL_IRDA_TxCpltCallback(hirda);
01304 
01305   return HAL_OK;
01306 }
01307 
01308 
01309 /**
01310   * @brief  Receive an amount of data in non-blocking mode.
01311   *         Function is called under interruption only, once
01312   *         interruptions have been enabled by HAL_IRDA_Receive_IT().
01313   * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01314   *                the configuration information for the specified IRDA module.
01315   * @retval HAL status
01316   */
01317 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
01318 {
01319   uint16_t* tmp;
01320   uint16_t uhMask = hirda->Mask;
01321 
01322   /* Check that a Rx process is ongoing */
01323   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
01324   {
01325 
01326     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
01327     {
01328       tmp = (uint16_t*) hirda->pRxBuffPtr ;
01329       *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
01330       hirda->pRxBuffPtr  +=2;
01331     }
01332     else
01333     {
01334       *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
01335     }
01336 
01337     if(--hirda->RxXferCount == 0)
01338     {
01339       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
01340 
01341       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
01342       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
01343 
01344       /* Disable the IRDA Parity Error Interrupt */
01345       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
01346 
01347       /* Rx process is completed, restore hirda->RxState to Ready */
01348       hirda->RxState = HAL_IRDA_STATE_READY;
01349 
01350       HAL_IRDA_RxCpltCallback(hirda);
01351 
01352       return HAL_OK;
01353     }
01354 
01355     return HAL_OK;
01356   }
01357   else
01358   {
01359     /* Clear RXNE interrupt flag */
01360     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
01361 
01362     return HAL_BUSY;
01363   }
01364 }
01365 
01366 /**
01367   * @brief Configure the IRDA peripheral.
01368   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01369   *               the configuration information for the specified IRDA module.
01370   * @retval None
01371   */
01372 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
01373 {
01374   uint32_t tmpreg                     = 0x00000000;
01375   IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED;
01376   HAL_StatusTypeDef ret               = HAL_OK;
01377 
01378   /* Check the communication parameters */
01379   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
01380   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
01381   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
01382   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
01383   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
01384   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
01385 
01386   /*-------------------------- USART CR1 Configuration -----------------------*/
01387   /* Configure the IRDA Word Length, Parity and transfer Mode:
01388      Set the M bits according to hirda->Init.WordLength value
01389      Set PCE and PS bits according to hirda->Init.Parity value
01390      Set TE and RE bits according to hirda->Init.Mode value */
01391   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
01392 
01393   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
01394 
01395   /*-------------------------- USART CR3 Configuration -----------------------*/
01396   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
01397 
01398   /*-------------------------- USART GTPR Configuration ----------------------*/
01399   MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
01400 
01401   /*-------------------------- USART BRR Configuration -----------------------*/
01402   IRDA_GETCLOCKSOURCE(hirda, clocksource);
01403   switch (clocksource)
01404   {
01405     case IRDA_CLOCKSOURCE_PCLK1:
01406       hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate);
01407       break;
01408     case IRDA_CLOCKSOURCE_PCLK2:
01409       hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate);
01410       break;
01411     case IRDA_CLOCKSOURCE_HSI:
01412       hirda->Instance->BRR = (uint16_t)((HSI_VALUE + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate);
01413       break;
01414     case IRDA_CLOCKSOURCE_SYSCLK:
01415       hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate);
01416       break;
01417     case IRDA_CLOCKSOURCE_LSE:
01418       hirda->Instance->BRR = (uint16_t)((LSE_VALUE  + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate);
01419       break;
01420     case IRDA_CLOCKSOURCE_UNDEFINED:
01421     default:
01422       ret = HAL_ERROR;
01423       break;
01424   }
01425 
01426   return ret;
01427 }
01428 
01429 /**
01430   * @brief Check the IRDA Idle State.
01431   * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
01432   *               the configuration information for the specified IRDA module.
01433   * @retval HAL status
01434   */
01435 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
01436 {
01437   uint32_t tickstart = 0;
01438 
01439   /* Initialize the IRDA ErrorCode */
01440   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
01441 
01442   /* Init tickstart for timeout managment*/
01443   tickstart = HAL_GetTick();
01444 
01445   /* Check if the Transmitter is enabled */
01446   if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
01447   {
01448     /* Wait until TEACK flag is set */
01449     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
01450     {
01451       /* Timeout occurred */
01452       return HAL_TIMEOUT;
01453     }
01454   }
01455   /* Check if the Receiver is enabled */
01456   if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
01457   {
01458     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
01459     {
01460       /* Timeout occurred */
01461       return HAL_TIMEOUT;
01462     }
01463   }
01464 
01465   /* Initialize the IRDA state*/
01466   hirda->gState= HAL_IRDA_STATE_READY;
01467   hirda->RxState= HAL_IRDA_STATE_READY;
01468 
01469   /* Process Unlocked */
01470   __HAL_UNLOCK(hirda);
01471 
01472   return HAL_OK;
01473 }
01474 
01475 /**
01476   * @}
01477   */
01478 
01479 #endif /* HAL_IRDA_MODULE_ENABLED */
01480 /**
01481   * @}
01482   */
01483 
01484 /**
01485   * @}
01486   */
01487 
01488 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/