]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32L0/stm32l0xx_hal_irda.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32L0 / stm32l0xx_hal_irda.c
1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_hal_irda.c
4   * @author  MCD Application Team
5   * @version V1.2.0
6   * @date    06-February-2015
7   * @brief   IRDA HAL module driver.
8   * 
9   *          This file provides firmware functions to manage the following 
10   *          functionalities of the IrDA (Infrared Data Association) Peripheral 
11   *          (IRDA)
12   *           + Initialization and de-initialization functions
13   *           + IO operation functions
14   *           + Peripheral Control functions
15   *
16   *           
17   @verbatim       
18  ===============================================================================
19                         ##### How to use this driver #####
20  ===============================================================================
21  [..]
22     The IRDA HAL driver can be used as follows:
23
24     
25     (#) Declare a IRDA_HandleTypeDef handle structure.
26     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
27         (##) Enable the USARTx interface clock.
28         (##) IRDA pins configuration:
29             (+) Enable the clock for the IRDA GPIOs.
30             (+) Configure these IRDA pins as alternate function pull-up.
31         (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
32              and HAL_IRDA_Receive_IT() APIs):
33             (+) Configure the USARTx interrupt priority.
34             (+) Enable the NVIC USART IRQ handle.
35         (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
36              and HAL_IRDA_Receive_DMA() APIs):
37             (+) Declare a DMA handle structure for the Tx/Rx channel.
38             (+) Enable the DMAx interface clock.
39             (+) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40             (+) Configure the DMA Tx/Rx channel.
41             (+) Associate the initilalized DMA handle to the IRDA DMA Tx/Rx handle.
42             (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
43
44     (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler 
45         and Mode(Receiver/Transmitter) in the hirda Init structure.
46
47     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
48         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49             by calling the customed HAL_IRDA_MspInit() API.
50     -@@- The specific IRDA interrupts (Transmission complete interrupt, 
51         RXNE interrupt and Error Interrupts) will be managed using the macros
52         __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
53         
54     (#) Three operation modes are available within this driver :
55              
56     *** Polling mode IO operation ***
57     =================================
58     [..]    
59       (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() 
60       (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
61        
62     *** Interrupt mode IO operation ***    
63     ===================================
64     [..]    
65       (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT() 
66       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can 
67            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
68       (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT() 
69       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can 
70            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
71       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 
72            add his own code by customization of function pointer HAL_IRDA_ErrorCallback
73
74     *** DMA mode IO operation ***    
75     =============================
76     [..]
77       (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA() 
78       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can 
79            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
80       (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA() 
81       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can 
82            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
83       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 
84            add his own code by customization of function pointer HAL_IRDA_ErrorCallback    
85
86     *** IRDA HAL driver macros list ***
87     ===================================
88     [..]
89       Below the list of most used macros in IRDA HAL driver.
90        
91      (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral 
92      (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral     
93      (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not
94      (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag
95      (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt
96      (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt
97       
98      (@) You can refer to the IRDA HAL driver header file for more useful macros
99
100   @endverbatim
101   ******************************************************************************
102   * @attention
103   *
104   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
105   *
106   * Redistribution and use in source and binary forms, with or without modification,
107   * are permitted provided that the following conditions are met:
108   *   1. Redistributions of source code must retain the above copyright notice,
109   *      this list of conditions and the following disclaimer.
110   *   2. Redistributions in binary form must reproduce the above copyright notice,
111   *      this list of conditions and the following disclaimer in the documentation
112   *      and/or other materials provided with the distribution.
113   *   3. Neither the name of STMicroelectronics nor the names of its contributors
114   *      may be used to endorse or promote products derived from this software
115   *      without specific prior written permission.
116   *
117   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
118   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
119   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
121   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
122   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
123   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
124   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
125   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
126   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127   *
128   ******************************************************************************  
129   */ 
130
131 /* Includes ------------------------------------------------------------------*/
132 #include "stm32l0xx_hal.h"
133
134 /** @addtogroup STM32L0xx_HAL_Driver
135   * @{
136   */
137
138 /** @addtogroup IRDA
139   * @brief IRDA HAL module driver
140   * @{
141   */
142 #ifdef HAL_IRDA_MODULE_ENABLED
143     
144 /* Private typedef -----------------------------------------------------------*/
145 /* Private define ------------------------------------------------------------*/
146 #define TEACK_REACK_TIMEOUT            1000
147 #define HAL_IRDA_TXDMA_TIMEOUTVALUE    22000
148 #define IRDA_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
149                                    | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))
150 /* Private macro -------------------------------------------------------------*/
151 /* Private variables ---------------------------------------------------------*/
152 /* Private function prototypes -----------------------------------------------*/
153 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
154 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
155 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
156 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
157 static void IRDA_DMAError(DMA_HandleTypeDef *hdma); 
158 static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
159 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
160 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
161 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
162 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
163 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
164 /* Private functions ---------------------------------------------------------*/
165
166 /** @addtogroup IRDA_Exported_Functions
167   * @{
168   */
169
170 /** @addtogroup IRDA_Exported_Functions_Group1
171   *  @brief   Initialization and Configuration functions 
172   *
173 @verbatim    
174 ===============================================================================
175             ##### Initialization and Configuration functions #####
176  ===============================================================================  
177     [..]
178     This subsection provides a set of functions allowing to initialize the USARTx 
179     in asynchronous IRDA mode.
180       (+) For the asynchronous mode only these parameters can be configured: 
181         (++) Baud Rate
182         (++) Word Length 
183         (++) Parity: If the parity is enabled, then the MSB bit of the data written
184              in the data register is transmitted but is changed by the parity bit.
185              Depending on the frame length defined by the M bit (8-bits or 9-bits)
186              or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
187              the possible IRDA frame formats are as listed in the following table:
188    +---------------------------------------------------------------+
189    | M1M0 bits |  PCE bit  |            IRDA frame                 |
190    |-----------|-----------|---------------------------------------|
191    |     00    |     0     |    | SB | 8-bit data | STB |          |
192    |-----------|-----------|---------------------------------------|
193    |     00    |     1     |    | SB | 7-bit data | PB | STB |     |
194    |-----------|-----------|---------------------------------------|
195    |     01    |     0     |    | SB | 9-bit data | STB |          |
196    |-----------|-----------|---------------------------------------|
197    |     01    |     1     |    | SB | 8-bit data | PB | STB |     |
198    |-----------------------|---------------------------------------|
199    |     10    |     0     |    | SB | 7-bit data | STB |          |
200    |-----------|-----------|---------------------------------------|
201    |     10    |     1     |    | SB | 6-bit data | PB | STB |     |
202    +---------------------------------------------------------------+
203           
204         (++) Power mode
205         (++) Prescaler setting       
206         (++) Receiver/transmitter modes
207
208     [..]
209     The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures 
210     (details for the procedures are available in reference manual).
211
212 @endverbatim
213   * @{
214   */
215
216 /**
217   * @brief Initializes the IRDA mode according to the specified
218   *         parameters in the IRDA_InitTypeDef and creates the associated handle .
219   * @param hirda: IRDA handle
220   * @retval HAL status
221   */
222 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
223 {
224   /* Check the IRDA handle allocation */
225   if(hirda == NULL)
226   {
227     return HAL_ERROR;
228   }
229
230   /* Check the USART/UART associated to the IRDA handle */
231   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
232
233   if(hirda->State == HAL_IRDA_STATE_RESET)
234   {
235     /* Init the low level hardware : GPIO, CLOCK, CORTEX */
236     HAL_IRDA_MspInit(hirda);
237   }
238
239   hirda->State = HAL_IRDA_STATE_BUSY;
240
241   /* Disable the Peripheral to update the configuration registers */
242   __HAL_IRDA_DISABLE(hirda);
243
244   /* Set the IRDA Communication parameters */
245   IRDA_SetConfig(hirda);
246
247   /* In IRDA mode, the following bits must be kept cleared: 
248   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
249   - SCEN and HDSEL bits in the USART_CR3 register.*/
250   hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP); 
251   hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL); 
252
253   /* set the UART/USART in IRDA mode */
254   hirda->Instance->CR3 |= USART_CR3_IREN; 
255
256   /* Enable the Peripheral */
257   __HAL_IRDA_ENABLE(hirda);
258
259   /* TEACK and/or REACK to check before moving hirda->State to Ready */
260   return (IRDA_CheckIdleState(hirda));
261 }
262
263 /**
264   * @brief DeInitializes the IRDA peripheral 
265   * @param hirda: IRDA handle
266   * @retval HAL status
267   */
268 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
269 {
270   /* Check the IRDA handle allocation */
271   if(hirda == NULL)
272   {
273     return HAL_ERROR;
274   }
275
276   /* Check the USART/UART associated to the IRDA handle */
277   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
278
279   hirda->State = HAL_IRDA_STATE_BUSY;
280
281   /* DeInit the low level hardware */
282   HAL_IRDA_MspDeInit(hirda);
283   /* Disable the Peripheral */
284   __HAL_IRDA_DISABLE(hirda);
285
286   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
287   hirda->State = HAL_IRDA_STATE_RESET;
288
289   /* Release Lock */
290   __HAL_UNLOCK(hirda);
291
292   return HAL_OK;
293 }
294
295 /**
296   * @brief IRDA MSP Init
297   * @param hirda: IRDA handle
298   * @retval None
299   */
300  __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
301 {
302   /* NOTE : This function Should not be modified, when the callback is needed,
303             the HAL_IRDA_MspInit could be implented in the user file
304    */ 
305 }
306
307 /**
308   * @brief IRDA MSP DeInit
309   * @param hirda: IRDA handle
310   * @retval None
311   */
312  __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
313 {
314   /* NOTE : This function Should not be modified, when the callback is needed,
315             the HAL_IRDA_MspDeInit could be implented in the user file
316    */ 
317 }
318
319 /**
320   * @}
321   */
322
323 /** @addtogroup IRDA_Exported_Functions_Group2
324   *  @brief   IRDA Transmit-Receive functions  
325   *
326 @verbatim    
327 ===============================================================================
328                       ##### IO operation functions #####
329 ===============================================================================  
330     [..]
331     This subsection provides a set of functions allowing to manage the IRDA asynchronous
332     data transfers.
333
334     (#) There are two modes of transfer:
335        (++) Blocking mode: the communication is performed in polling mode. 
336             The HAL status of all data processing is returned by the same function 
337             after finishing transfer.  
338        (++) No-Blocking mode: the communication is performed using Interrupts 
339            or DMA, these API's return the HAL status.
340            The end of the data processing will be indicated through the 
341            dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when 
342            using DMA mode.
343            The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks 
344            will be executed respectivelly at the end of the Transmit or Receive process
345            The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
346
347     (#) Blocking mode API's are :
348         (++) HAL_IRDA_Transmit()
349         (++) HAL_IRDA_Receive() 
350         
351     (#) Non-Blocking mode API's with Interrupt are :
352         (++) HAL_IRDA_Transmit_IT()
353         (++) HAL_IRDA_Receive_IT()
354         (++) HAL_IRDA_IRQHandler()
355         (++) IRDA_Transmit_IT()
356         (++) IRDA_Receive_IT()
357
358     (#) Non-Blocking mode functions with DMA are :
359         (++) HAL_IRDA_Transmit_DMA()
360         (++) HAL_IRDA_Receive_DMA()
361
362     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
363         (++) HAL_IRDA_TxCpltCallback()
364         (++) HAL_IRDA_RxCpltCallback()
365         (++) HAL_IRDA_ErrorCallback()
366       
367 @endverbatim
368   * @{
369   */
370
371 /**
372   * @brief Send an amount of data in blocking mode 
373   * @param hirda: IRDA handle
374   * @param pData: pointer to data buffer
375   * @param Size: amount of data to be sent
376   * @param Timeout: Duration of the timeout
377   * @retval HAL status
378   */
379 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
380 {
381    uint16_t* tmp;
382    
383   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) 
384   {
385     if((pData == NULL) || (Size == 0)) 
386     {
387       return  HAL_ERROR;                                    
388     }
389     
390     /* Process Locked */
391     __HAL_LOCK(hirda);
392     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
393
394     if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 
395     {
396       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
397     }
398     else
399     {
400       hirda->State = HAL_IRDA_STATE_BUSY_TX;
401     }    
402     
403     hirda->TxXferSize = Size;
404     hirda->TxXferCount = Size;
405     while(hirda->TxXferCount > 0)
406     {
407       hirda->TxXferCount--;
408
409         if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK)
410         { 
411           return HAL_TIMEOUT;
412         }
413       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
414         {
415           tmp = (uint16_t*) pData;
416           hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);   
417           pData +=2;
418         }
419         else
420         { 
421           hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF); 
422         }
423       } 
424
425     if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK)
426     { 
427       return HAL_TIMEOUT;
428     } 
429
430     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 
431     {
432       hirda->State = HAL_IRDA_STATE_BUSY_RX;
433     }
434     else
435     {
436       hirda->State = HAL_IRDA_STATE_READY;
437     }    
438     
439     /* Process Unlocked */
440     __HAL_UNLOCK(hirda);
441     
442     return HAL_OK;
443   }
444   else
445   {
446     return HAL_BUSY;   
447   }
448 }
449
450 /**
451   * @brief Receive an amount of data in blocking mode 
452   * @param hirda: IRDA handle
453   * @param pData: pointer to data buffer
454   * @param Size: amount of data to be received
455   * @param Timeout: Duration of the timeout
456   * @retval HAL status
457   */
458 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
459
460   uint16_t* tmp;
461   uint16_t uhMask;
462   
463   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
464   { 
465     if((pData == NULL) || (Size == 0)) 
466     {
467       return  HAL_ERROR;                                    
468     }
469     
470     /* Process Locked */
471     __HAL_LOCK(hirda);
472     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
473
474     if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 
475     {
476       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
477     }
478     else
479     {
480       hirda->State = HAL_IRDA_STATE_BUSY_RX;
481     }    
482     
483     hirda->RxXferSize = Size; 
484     hirda->RxXferCount = Size;
485
486     /* Computation of the mask to apply to the RDR register 
487        of the UART associated to the IRDA */
488     IRDA_MASK_COMPUTATION(hirda);
489     uhMask = hirda->Mask;
490
491     /* Check data remaining to be received */
492     while(hirda->RxXferCount > 0)
493     {
494       hirda->RxXferCount--;
495
496       if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK)
497       { 
498         return HAL_TIMEOUT;
499       }         
500       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
501       {
502         tmp = (uint16_t*) pData ;
503         *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
504         pData +=2;
505       }
506       else
507       {
508         *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 
509       }       
510     } 
511
512     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 
513     {
514       hirda->State = HAL_IRDA_STATE_BUSY_TX;
515     }
516     else
517     {
518       hirda->State = HAL_IRDA_STATE_READY;
519     }
520      
521     /* Process Unlocked */
522     __HAL_UNLOCK(hirda);
523     
524     return HAL_OK;
525   }
526   else
527   {
528     return HAL_BUSY;   
529   }
530 }
531
532 /**
533   * @brief Send an amount of data in interrupt mode 
534   * @param hirda: IRDA handle
535   * @param pData: pointer to data buffer
536   * @param Size: amount of data to be sent
537   * @retval HAL status
538   */
539 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
540 {
541   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
542   {
543     if((pData == NULL) || (Size == 0)) 
544     {
545       return HAL_ERROR;
546     }
547     
548     /* Process Locked */
549     __HAL_LOCK(hirda);
550     
551     hirda->pTxBuffPtr = pData;
552     hirda->TxXferSize = Size;
553     hirda->TxXferCount = Size;
554
555     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
556     if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 
557     {
558       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
559     }
560     else
561     {
562       hirda->State = HAL_IRDA_STATE_BUSY_TX;
563     }
564         
565     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
566     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
567     
568     /* Process Unlocked */
569     __HAL_UNLOCK(hirda);    
570     
571     /* Enable the IRDA Transmit Data Register Empty Interrupt */
572     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
573     
574     return HAL_OK;
575   }
576   else
577   {
578     return HAL_BUSY;   
579   }
580 }
581
582 /**
583   * @brief Receive an amount of data in interrupt mode 
584   * @param hirda: IRDA handle
585   * @param pData: pointer to data buffer
586   * @param Size: amount of data to be received
587   * @retval HAL status
588   */
589 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
590 {  
591   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
592   {
593     if((pData == NULL) || (Size == 0)) 
594     {
595       return HAL_ERROR;
596     }
597     
598     /* Process Locked */
599   __HAL_LOCK(hirda);
600   
601     hirda->pRxBuffPtr = pData;
602     hirda->RxXferSize = Size;
603     hirda->RxXferCount = Size;
604   
605     /* Computation of the mask to apply to the RDR register 
606        of the UART associated to the IRDA */
607     IRDA_MASK_COMPUTATION(hirda);
608   
609     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;  
610     if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 
611     {
612       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
613     }
614     else
615     {
616       hirda->State = HAL_IRDA_STATE_BUSY_RX;
617     }
618     
619     /* Enable the IRDA Parity Error Interrupt */
620     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
621     
622     /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
623     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
624     
625     /* Process Unlocked */
626     __HAL_UNLOCK(hirda);
627     
628     /* Enable the IRDA Data Register not empty Interrupt */
629     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
630     
631     return HAL_OK;
632   }
633   else
634   {
635     return HAL_BUSY; 
636   }
637 }
638
639 /**
640   * @brief Send an amount of data in DMA mode 
641   * @param hirda: IRDA handle
642   * @param pData: pointer to data buffer
643   * @param Size: amount of data to be sent
644   * @retval HAL status
645   */
646 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
647 {
648   uint32_t *tmp;
649   
650   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
651   {
652     if((pData == NULL) || (Size == 0)) 
653     {
654       return HAL_ERROR;
655     }
656     
657     /* Process Locked */
658     __HAL_LOCK(hirda);
659     
660     hirda->pTxBuffPtr = pData;
661     hirda->TxXferSize = Size;
662     hirda->TxXferCount = Size; 
663     
664     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
665     
666     if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 
667     {
668       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
669     }
670     else
671     {
672       hirda->State = HAL_IRDA_STATE_BUSY_TX;
673     }
674     
675     /* Set the IRDA DMA transfer complete callback */
676     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
677     
678     /* Set the IRDA DMA half transfer complete callback */
679     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
680
681     /* Set the DMA error callback */
682     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
683
684     /* Enable the IRDA transmit DMA channel */
685     tmp = (uint32_t*)&pData;
686     HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
687     
688     /* Clear the TC flag in the SR register by writing 0 to it */
689     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
690
691     /* Enable the DMA transfer for transmit request by setting the DMAT bit
692        in the IRDA CR3 register */
693     hirda->Instance->CR3 |= USART_CR3_DMAT;
694     
695     /* Process Unlocked */
696     __HAL_UNLOCK(hirda);
697     
698     return HAL_OK;
699   }
700   else
701   {
702     return HAL_BUSY;   
703   }
704 }
705
706 /**
707   * @brief Receive an amount of data in DMA mode 
708   * @param hirda: IRDA handle
709   * @param pData: pointer to data buffer
710   * @param Size: amount of data to be received
711   * @note   When the IRDA parity is enabled (PCE = 1), the received data contain 
712   *         the parity bit (MSB position)  
713   * @retval HAL status
714   */
715 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
716 {
717   uint32_t *tmp;
718   
719   if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
720   {
721     if((pData == NULL) || (Size == 0)) 
722     {
723       return HAL_ERROR;
724     }
725     
726     /* Process Locked */
727     __HAL_LOCK(hirda);
728     
729     hirda->pRxBuffPtr = pData;
730     hirda->RxXferSize = Size;
731
732     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
733     if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 
734     {
735       hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
736     }
737     else
738     {
739       hirda->State = HAL_IRDA_STATE_BUSY_RX;
740     }
741     
742     /* Set the IRDA DMA transfer complete callback */
743     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
744     
745     /* Set the IRDA DMA half transfer complete callback */
746     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
747     
748     /* Set the DMA error callback */
749     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
750
751     /* Enable the DMA channel */
752     tmp = (uint32_t*)&pData;
753     HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
754
755     /* Enable the DMA transfer for the receiver request by setting the DMAR bit 
756        in the IRDA CR3 register */
757      hirda->Instance->CR3 |= USART_CR3_DMAR;
758     
759      /* Process Unlocked */
760      __HAL_UNLOCK(hirda);
761      
762     return HAL_OK;
763   }
764   else
765   {
766     return HAL_BUSY; 
767   }
768 }
769
770 /**
771   * @brief Pauses the DMA Transfer.
772   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
773   *                the configuration information for the specified IRDA module.
774   * @retval HAL status
775   */
776 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
777 {
778   /* Process Locked */
779   __HAL_LOCK(hirda);
780   
781   if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
782   {
783     /* Disable the UART DMA Tx request */
784     hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
785   }
786   else if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
787   {
788     /* Disable the UART DMA Rx request */
789     hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
790   }
791   else if (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
792   {
793     /* Disable the UART DMA Tx & Rx requests */
794     hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
795     hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
796   }
797   
798   /* Process Unlocked */
799   __HAL_UNLOCK(hirda);
800   
801   return HAL_OK; 
802 }
803
804 /**
805   * @brief Resumes the DMA Transfer.
806   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
807   *                the configuration information for the specified UART module.
808   * @retval HAL status
809   */
810 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
811 {
812   /* Process Locked */
813   __HAL_LOCK(hirda);
814   
815   if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
816   {
817     /* Enable the UART DMA Tx request */
818     hirda->Instance->CR3 |= USART_CR3_DMAT;
819   }
820   else if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
821   {
822     /* Clear the Overrun flag before resumming the Rx transfer*/
823     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
824
825     /* Enable the UART DMA Rx request */
826     hirda->Instance->CR3 |= USART_CR3_DMAR;
827   }
828   else if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
829   {
830     /* Clear the Overrun flag before resumming the Rx transfer*/
831     __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
832     
833     /* Enable the UART DMA Tx & Rx request */
834     hirda->Instance->CR3 |= USART_CR3_DMAT;
835     hirda->Instance->CR3 |= USART_CR3_DMAR;
836   }
837   
838   /* Process Unlocked */
839   __HAL_UNLOCK(hirda);
840   
841   return HAL_OK;
842 }
843
844 /**
845   * @brief Stops the DMA Transfer.
846   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
847   *                the configuration information for the specified UART module.
848   * @retval HAL status
849   */
850 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
851 {
852   /* The Lock is not implemented on this API to allow the user application
853      to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
854      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
855      and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
856      */
857
858   /* Disable the UART Tx/Rx DMA requests */
859   hirda->Instance->CR3 &= ~USART_CR3_DMAT;
860   hirda->Instance->CR3 &= ~USART_CR3_DMAR;
861   
862   /* Abort the UART DMA tx channel */
863   if(hirda->hdmatx != NULL)
864   {
865     HAL_DMA_Abort(hirda->hdmatx);
866   }
867   /* Abort the UART DMA rx channel */
868   if(hirda->hdmarx != NULL)
869   {
870     HAL_DMA_Abort(hirda->hdmarx);
871   }
872   
873   hirda->State = HAL_IRDA_STATE_READY;
874
875   return HAL_OK;
876 }
877
878 /**
879   * @brief This function handles IRDA interrupt request.
880   * @param hirda: IRDA handle
881   * @retval None
882   */
883 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
884 {
885   /* IRDA parity error interrupt occurred -------------------------------------*/
886   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET))
887   { 
888     __HAL_IRDA_CLEAR_PEFLAG(hirda);
889
890     hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
891     /* Set the IRDA state ready to be able to start again the process */
892     hirda->State = HAL_IRDA_STATE_READY;
893   }
894   
895   /* IRDA frame error interrupt occured --------------------------------------*/
896   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
897   { 
898     __HAL_IRDA_CLEAR_FEFLAG(hirda);
899
900     hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
901     /* Set the IRDA state ready to be able to start again the process */
902     hirda->State = HAL_IRDA_STATE_READY;
903   }
904   
905   /* IRDA noise error interrupt occured --------------------------------------*/
906   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
907   { 
908     __HAL_IRDA_CLEAR_NEFLAG(hirda);
909
910     hirda->ErrorCode |= HAL_IRDA_ERROR_NE; 
911     /* Set the IRDA state ready to be able to start again the process */
912     hirda->State = HAL_IRDA_STATE_READY;
913   }
914   
915   /* IRDA Over-Run interrupt occured -----------------------------------------*/
916   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
917   { 
918     __HAL_IRDA_CLEAR_OREFLAG(hirda);
919
920     hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; 
921     /* Set the IRDA state ready to be able to start again the process */
922     hirda->State = HAL_IRDA_STATE_READY;
923   }
924   
925   /* Call IRDA Error Call back function if need be --------------------------*/
926   if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
927   {
928     HAL_IRDA_ErrorCallback(hirda);
929   } 
930
931   /* IRDA in mode Receiver ---------------------------------------------------*/
932   if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET))
933   { 
934     IRDA_Receive_IT(hirda);
935     /* Clear RXNE interrupt flag */
936     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
937   }
938   
939   /* IRDA in mode Transmitter ------------------------------------------------*/
940  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET))
941   {
942     IRDA_Transmit_IT(hirda);
943   } 
944
945  /* IRDA in mode Transmitter (transmission end) -----------------------------*/
946  if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET))
947   {
948     IRDA_EndTransmit_IT(hirda);
949   }   
950
951 }
952
953 /**
954   * @brief Tx Half Transfer completed callback
955   * @param hirda: irda handle
956   * @retval None
957   */
958  __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
959 {
960   /* NOTE : This function should not be modified, when the callback is needed,
961             the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file
962    */ 
963 }
964
965 /**
966   * @brief Tx Transfer completed callback
967   * @param hirda: irda handle
968   * @retval None
969   */
970  __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
971 {
972   /* NOTE : This function should not be modified, when the callback is needed,
973             the HAL_IRDA_TxCpltCallback can be implemented in the user file
974    */ 
975 }
976
977 /**
978   * @brief Rx Half Transfer completed callback
979   * @param hirda: irda handle
980   * @retval None
981   */
982 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
983 {
984   /* NOTE : This function should not be modified, when the callback is needed,
985             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file
986    */
987 }
988
989 /**
990   * @brief Rx Transfer completed callback
991   * @param hirda: irda handle
992   * @retval None
993   */
994 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
995 {
996   /* NOTE : This function should not be modified, when the callback is needed,
997             the HAL_IRDA_RxCpltCallback can be implemented in the user file
998    */
999 }
1000
1001 /**
1002   * @brief IRDA error callback
1003   * @param hirda: IRDA handle
1004   * @retval None
1005   */
1006  __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
1007 {
1008   /* NOTE : This function should not be modified, when the callback is needed,
1009             the HAL_IRDA_ErrorCallback can be implemented in the user file
1010    */ 
1011 }
1012
1013 /**
1014   * @}
1015   */
1016
1017 /** @addtogroup IRDA_Exported_Functions_Group3
1018   *  @brief   IRDA control functions 
1019   *
1020 @verbatim   
1021  ===============================================================================
1022                       ##### Peripheral Control functions #####
1023  ===============================================================================  
1024     [..]
1025     This subsection provides a set of functions allowing to control the IRDA.
1026      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IRDA peripheral. 
1027      (+) IRDA_SetConfig() API is used to configure the IRDA communications parameters.
1028 @endverbatim
1029   * @{
1030   */
1031
1032 /**
1033   * @brief return the IRDA state
1034   * @param hirda: irda handle
1035   * @retval HAL state
1036   */
1037 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
1038 {
1039   return hirda->State;
1040 }
1041
1042 /**
1043 * @brief  Return the IRDA error code
1044 * @param  hirda : pointer to a IRDA_HandleTypeDef structure that contains
1045   *              the configuration information for the specified IRDA.
1046 * @retval IRDA Error Code
1047 */
1048 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
1049 {
1050   return hirda->ErrorCode;
1051 }
1052
1053 /**
1054   * @}
1055   */
1056
1057 /**
1058   * @brief Configure the IRDA peripheral 
1059   * @param hirda: irda handle
1060   * @retval None
1061   */
1062 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
1063 {
1064   uint32_t tmpreg      = 0x00000000;
1065   uint32_t clocksource = 0x00000000;
1066   
1067   /* Check the communication parameters */ 
1068   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));  
1069   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
1070   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
1071   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
1072   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); 
1073   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); 
1074   /*-------------------------- USART CR1 Configuration -----------------------*/        
1075   /* Configure the IRDA Word Length, Parity and transfer Mode: 
1076   Set the M bits according to hirda->Init.WordLength value 
1077   Set PCE and PS bits according to hirda->Init.Parity value
1078   Set TE and RE bits according to hirda->Init.Mode value */
1079   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
1080   
1081   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
1082   
1083   /*-------------------------- USART CR3 Configuration -----------------------*/
1084   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
1085   
1086   /*-------------------------- USART GTPR Configuration ----------------------*/  
1087   MODIFY_REG(hirda->Instance->GTPR, (uint32_t)USART_GTPR_PSC, hirda->Init.Prescaler);
1088   
1089   /*-------------------------- USART BRR Configuration -----------------------*/ 
1090   IRDA_GETCLOCKSOURCE(hirda, clocksource);
1091   switch (clocksource)
1092   {
1093   case IRDA_CLOCKSOURCE_PCLK1: 
1094     hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hirda->Init.BaudRate);
1095     break;
1096   case IRDA_CLOCKSOURCE_PCLK2: 
1097     hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hirda->Init.BaudRate);
1098     break;
1099   case IRDA_CLOCKSOURCE_HSI: 
1100     hirda->Instance->BRR = (uint16_t)(HSI_VALUE / hirda->Init.BaudRate); 
1101     break; 
1102   case IRDA_CLOCKSOURCE_SYSCLK:  
1103     hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hirda->Init.BaudRate);
1104     break;  
1105   case IRDA_CLOCKSOURCE_LSE:                
1106     hirda->Instance->BRR = (uint16_t)(LSE_VALUE / hirda->Init.BaudRate); 
1107     break;
1108   default:
1109     break;
1110   } 
1111 }
1112
1113 /**
1114   * @brief Check the IRDA Idle State
1115   * @param hirda: IRDA handle
1116   * @retval HAL status
1117   */
1118 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
1119 {
1120   /* Initialize the IRDA ErrorCode */
1121   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1122   
1123   /* Check if the Transmitter is enabled */
1124   if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1125   {
1126     /* Wait until TEACK flag is set */
1127     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1128     { 
1129       hirda->State= HAL_IRDA_STATE_TIMEOUT;
1130       return HAL_TIMEOUT;
1131     }     
1132   }
1133   /* Check if the Receiver is enabled */
1134   if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1135   {
1136     if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1137     { 
1138       hirda->State= HAL_IRDA_STATE_TIMEOUT;
1139       return HAL_TIMEOUT;
1140     }       
1141   }
1142   /* Process Unlocked */
1143   __HAL_UNLOCK(hirda);
1144   
1145   /* Initialize the IRDA state*/
1146   hirda->State= HAL_IRDA_STATE_READY;
1147   
1148   return HAL_OK;
1149 }
1150
1151 /**
1152   * @brief  Handle IRDA Communication Timeout.
1153   * @param  hirda: IRDA handle
1154   * @param  Flag: specifies the IRDA flag to check.
1155   * @param  Status: the flag status (SET or RESET). The function is locked in a while loop as long as the flag remains set to Status.
1156   * @param  Timeout: Timeout duration
1157   * @retval HAL status
1158   */
1159 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout)  
1160 {
1161   uint32_t tickstart = 0x00;
1162   tickstart = HAL_GetTick();
1163   
1164   /* Wait until flag is set */
1165   if(Status == RESET)
1166   {
1167     while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET)
1168     {
1169       /* Check for the Timeout */
1170       if(Timeout != HAL_MAX_DELAY)
1171       {
1172         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1173         {
1174           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1175           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1176           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1177           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1178           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1179
1180           hirda->State= HAL_IRDA_STATE_READY;
1181
1182           /* Process Unlocked */
1183           __HAL_UNLOCK(hirda);
1184
1185           return HAL_TIMEOUT;
1186         }
1187       }
1188     }
1189   }
1190   else
1191   {
1192     while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET)
1193     {
1194       /* Check for the Timeout */
1195       if(Timeout != HAL_MAX_DELAY)
1196       {
1197         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1198         {
1199           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1200           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1201           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1202           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1203           __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1204
1205           hirda->State= HAL_IRDA_STATE_READY;
1206
1207           /* Process Unlocked */
1208           __HAL_UNLOCK(hirda);
1209
1210           return HAL_TIMEOUT;
1211         }
1212       }
1213     }
1214   }
1215   return HAL_OK;      
1216 }
1217
1218 /**
1219   * @brief Receive an amount of data in non blocking mode. 
1220   *         Function called under interruption only, once
1221   *         interruptions have been enabled by HAL_IRDA_Transmit_IT()
1222   * @param hirda: IRDA handle
1223   * @retval HAL status
1224   */
1225 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
1226 {
1227   uint16_t* tmp;
1228   
1229   if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
1230   {
1231
1232     if(hirda->TxXferCount == 0)
1233     {
1234       /* Disable the IRDA Transmit Data Register Empty Interrupt */
1235       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1236      
1237       /* Enable the IRDA Transmit Complete Interrupt */    
1238       __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);     
1239       
1240       return HAL_OK;
1241     }
1242     else
1243     {
1244       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1245       {
1246         tmp = (uint16_t*) hirda->pTxBuffPtr;
1247         hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1248         hirda->pTxBuffPtr += 2;
1249       }
1250       else
1251       {
1252         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF); 
1253       }
1254       hirda->TxXferCount--;
1255       return HAL_OK;
1256     }
1257   }
1258   else
1259   {
1260     return HAL_BUSY;
1261   }
1262 }
1263 /**
1264   * @brief  Wraps up transmission in non blocking mode.
1265   * @param  hirda: pointer to a IRDA_HandleTypeDef structure that contains
1266   *                the configuration information for the specified IRDA module.
1267   * @retval HAL status
1268   */
1269 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
1270 {
1271   /* Disable the IRDA Transmit Complete Interrupt */    
1272   __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC);
1273   
1274   /* Check if a receive process is ongoing or not */
1275   if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 
1276   {
1277     hirda->State = HAL_IRDA_STATE_BUSY_RX;
1278   }
1279   else
1280   {
1281     /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1282     __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1283     
1284     hirda->State = HAL_IRDA_STATE_READY;
1285   }
1286   
1287   HAL_IRDA_TxCpltCallback(hirda);
1288   
1289   return HAL_OK;
1290 }
1291
1292 /**
1293   * @brief Receive an amount of data in non blocking mode. 
1294   *         Function called under interruption only, once
1295   *         interruptions have been enabled by HAL_IRDA_Receive_IT()
1296   * @param hirda: IRDA handle
1297   * @retval HAL status
1298   */
1299 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
1300 {
1301   uint16_t* tmp;
1302   uint16_t uhMask = hirda->Mask;
1303   
1304   if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
1305   {
1306     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1307     {
1308       tmp = (uint16_t*) hirda->pRxBuffPtr ;
1309       *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
1310       hirda->pRxBuffPtr  +=2;
1311     }
1312     else
1313     {
1314       *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 
1315     }
1316     
1317     if(--hirda->RxXferCount == 0)
1318     {
1319       while(HAL_IS_BIT_SET(hirda->Instance->ISR, IRDA_FLAG_RXNE))
1320       {
1321       }
1322       __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1323       
1324       if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 
1325       {
1326         hirda->State = HAL_IRDA_STATE_BUSY_TX;
1327       }
1328       else
1329       {      
1330         /* Disable the IRDA Parity Error Interrupt */
1331         __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1332         
1333         /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1334         __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1335         
1336         hirda->State = HAL_IRDA_STATE_READY;
1337       }
1338       
1339       HAL_IRDA_RxCpltCallback(hirda);
1340       
1341       return HAL_OK;
1342     }
1343     
1344     return HAL_OK;
1345   }
1346   else
1347   {
1348     return HAL_BUSY; 
1349   }
1350 }
1351   
1352 /**
1353   * @brief DMA IRDA Tx transfer completed callback 
1354   * @param hdma: DMA handle
1355   * @retval None
1356   */
1357 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
1358 {
1359   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1360
1361   /* DMA Normal mode */
1362   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
1363   {
1364     hirda->TxXferCount = 0;
1365
1366     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1367        in the IRDA CR3 register */
1368     hirda->Instance->CR3 &= ~(USART_CR3_DMAT);
1369
1370     /* Enable the IRDA Transmit Complete Interrupt */
1371     __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
1372   }
1373   /* DMA Circular mode */
1374   else
1375   {
1376     HAL_IRDA_TxCpltCallback(hirda);
1377   }
1378 }
1379
1380 /**
1381   * @brief DMA IRDA receive process half complete callback 
1382   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1383   *                the configuration information for the specified DMA module.
1384   * @retval None
1385   */
1386 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
1387 {
1388   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1389
1390   HAL_IRDA_TxHalfCpltCallback(hirda); 
1391 }
1392
1393 /**
1394   * @brief DMA IRDA Rx Transfer completed callback 
1395   * @param hdma: DMA handle
1396   * @retval None
1397   */
1398 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  
1399 {
1400   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1401   /* DMA Normal mode */
1402   if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
1403   {
1404     hirda->RxXferCount = 0;
1405     
1406     /* Disable the DMA transfer for the receiver request by setting the DMAR bit 
1407     in the IRDA CR3 register */
1408     hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR);
1409     
1410     if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 
1411     {
1412       hirda->State = HAL_IRDA_STATE_BUSY_TX;
1413     }
1414     else
1415     {
1416       hirda->State = HAL_IRDA_STATE_READY;
1417     }
1418   }
1419   
1420   HAL_IRDA_RxCpltCallback(hirda);
1421 }
1422
1423 /**
1424   * @brief DMA IRDA receive process half complete callback 
1425   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1426   *                the configuration information for the specified DMA module.
1427   * @retval None
1428   */
1429 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
1430 {
1431   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1432
1433   HAL_IRDA_RxHalfCpltCallback(hirda); 
1434 }
1435
1436 /**
1437   * @brief DMA IRDA communication error callback 
1438   * @param hdma: DMA handle
1439   * @retval None
1440   */
1441 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)   
1442 {
1443   IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1444   hirda->RxXferCount = 0;
1445   hirda->TxXferCount = 0;
1446   hirda->State= HAL_IRDA_STATE_READY;
1447   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
1448   HAL_IRDA_ErrorCallback(hirda);
1449 }
1450
1451 /**
1452   * @}
1453   */
1454
1455 #endif /* HAL_IRDA_MODULE_ENABLED */
1456 /**
1457   * @}
1458   */
1459
1460 /**
1461   * @}
1462   */
1463
1464 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1465