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