1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_irda.c
4   * @author  MCD Application Team
5   * @brief   IRDA HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the IrDA SIR ENDEC block (IrDA):
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     The IRDA HAL driver can be used as follows:
30 
31     (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda).
32     (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
33         (##) Enable the USARTx interface clock.
34         (##) IRDA pins configuration:
35             (+++) Enable the clock for the IRDA GPIOs.
36             (+++) Configure IRDA pins as alternate function pull-up.
37         (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
38              and HAL_IRDA_Receive_IT() APIs):
39             (+++) Configure the USARTx interrupt priority.
40             (+++) Enable the NVIC USART IRQ handle.
41         (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
42              and HAL_IRDA_Receive_DMA() APIs):
43             (+++) Declare a DMA handle structure for the Tx/Rx stream.
44             (+++) Enable the DMAx interface clock.
45             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
46             (+++) Configure the DMA Tx/Rx stream.
47             (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
48             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx stream.
49             (+++) Configure the IRDAx interrupt priority and enable the NVIC USART IRQ handle
50                   (used for last byte sending completion detection in DMA non circular mode)
51 
52     (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
53         and Mode(Receiver/Transmitter) in the hirda Init structure.
54 
55     (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
56         (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
57              by calling the customized HAL_IRDA_MspInit() API.
58 
59          -@@- The specific IRDA interrupts (Transmission complete interrupt,
60              RXNE interrupt and Error Interrupts) will be managed using the macros
61              __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
62 
63     (#) Three operation modes are available within this driver :
64 
65     *** Polling mode IO operation ***
66     =================================
67     [..]
68       (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
69       (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
70 
71     *** Interrupt mode IO operation ***
72     ===================================
73     [..]
74       (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
75       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
76            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
77       (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
78       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
79            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
80       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
81            add his own code by customization of function pointer HAL_IRDA_ErrorCallback
82 
83     *** DMA mode IO operation ***
84     =============================
85     [..]
86       (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
87       (+) At transmission end of half transfer HAL_IRDA_TxHalfCpltCallback is executed and user can
88             add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback
89       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
90            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
91       (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
92       (+) At reception end of half transfer HAL_IRDA_RxHalfCpltCallback is executed and user can
93             add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback
94       (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
95            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
96       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
97            add his own code by customization of function pointer HAL_IRDA_ErrorCallback
98       (+) Pause the DMA Transfer using HAL_IRDA_DMAPause()
99       (+) Resume the DMA Transfer using HAL_IRDA_DMAResume()
100       (+) Stop the DMA Transfer using HAL_IRDA_DMAStop()
101 
102     *** IRDA HAL driver macros list ***
103     ===================================
104     [..]
105       Below the list of most used macros in IRDA HAL driver.
106 
107        (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
108        (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
109        (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
110        (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
111        (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
112        (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
113        (+) __HAL_IRDA_GET_IT_SOURCE: Check whether the specified IRDA interrupt has occurred or not
114 
115     [..]
116      (@) You can refer to the IRDA HAL driver header file for more useful macros
117 
118     ##### Callback registration #####
119     ==================================
120 
121     [..]
122       The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1
123       allows the user to configure dynamically the driver callbacks.
124 
125     [..]
126       Use Function HAL_IRDA_RegisterCallback() to register a user callback.
127       Function HAL_IRDA_RegisterCallback() allows to register following callbacks:
128        (+) TxHalfCpltCallback        : Tx Half Complete Callback.
129        (+) TxCpltCallback            : Tx Complete Callback.
130        (+) RxHalfCpltCallback        : Rx Half Complete Callback.
131        (+) RxCpltCallback            : Rx Complete Callback.
132        (+) ErrorCallback             : Error Callback.
133        (+) AbortCpltCallback         : Abort Complete Callback.
134        (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
135        (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
136        (+) MspInitCallback           : IRDA MspInit.
137        (+) MspDeInitCallback         : IRDA MspDeInit.
138       This function takes as parameters the HAL peripheral handle, the Callback ID
139       and a pointer to the user callback function.
140 
141     [..]
142       Use function HAL_IRDA_UnRegisterCallback() to reset a callback to the default
143       weak (surcharged) function.
144       HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle,
145       and the Callback ID.
146       This function allows to reset following callbacks:
147        (+) TxHalfCpltCallback        : Tx Half Complete Callback.
148        (+) TxCpltCallback            : Tx Complete Callback.
149        (+) RxHalfCpltCallback        : Rx Half Complete Callback.
150        (+) RxCpltCallback            : Rx Complete Callback.
151        (+) ErrorCallback             : Error Callback.
152        (+) AbortCpltCallback         : Abort Complete Callback.
153        (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
154        (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
155        (+) MspInitCallback           : IRDA MspInit.
156        (+) MspDeInitCallback         : IRDA MspDeInit.
157 
158     [..]
159       By default, after the HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET
160       all callbacks are set to the corresponding weak (surcharged) functions:
161       examples HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxHalfCpltCallback().
162       Exception done for MspInit and MspDeInit functions that are respectively
163       reset to the legacy weak (surcharged) functions in the HAL_IRDA_Init()
164       and HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand).
165       If not, MspInit or MspDeInit are not null, the HAL_IRDA_Init() and HAL_IRDA_DeInit()
166       keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
167 
168     [..]
169       Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only.
170       Exception done MspInit/MspDeInit that can be registered/unregistered
171       in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user)
172       MspInit/DeInit callbacks can be used during the Init/DeInit.
173       In that case first register the MspInit/MspDeInit user callbacks
174       using HAL_IRDA_RegisterCallback() before calling HAL_IRDA_DeInit()
175       or HAL_IRDA_Init() function.
176 
177     [..]
178       When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or
179       not defined, the callback registration feature is not available
180       and weak (surcharged) callbacks are used.
181 
182   @endverbatim
183      [..]
184        (@) Additional remark: If the parity is enabled, then the MSB bit of the data written
185            in the data register is transmitted but is changed by the parity bit.
186            Depending on the frame length defined by the M bit (8-bits or 9-bits),
187            the possible IRDA frame formats are as listed in the following table:
188     +-------------------------------------------------------------+
189     |   M bit |  PCE bit  |            IRDA frame                 |
190     |---------------------|---------------------------------------|
191     |    0    |    0      |    | SB | 8 bit data | 1 STB |        |
192     |---------|-----------|---------------------------------------|
193     |    0    |    1      |    | SB | 7 bit data | PB | 1 STB |   |
194     |---------|-----------|---------------------------------------|
195     |    1    |    0      |    | SB | 9 bit data | 1 STB |        |
196     |---------|-----------|---------------------------------------|
197     |    1    |    1      |    | SB | 8 bit data | PB | 1 STB |   |
198     +-------------------------------------------------------------+
199   ******************************************************************************
200   */
201 
202 /* Includes ------------------------------------------------------------------*/
203 #include "stm32f4xx_hal.h"
204 
205 /** @addtogroup STM32F4xx_HAL_Driver
206   * @{
207   */
208 
209 /** @defgroup IRDA IRDA
210   * @brief HAL IRDA module driver
211   * @{
212   */
213 
214 #ifdef HAL_IRDA_MODULE_ENABLED
215 
216 /* Private typedef -----------------------------------------------------------*/
217 /* Private define ------------------------------------------------------------*/
218 /* Private constants ---------------------------------------------------------*/
219 /* Private macro -------------------------------------------------------------*/
220 /* Private variables ---------------------------------------------------------*/
221 /* Private function prototypes -----------------------------------------------*/
222 /** @addtogroup IRDA_Private_Functions
223   * @{
224   */
225 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
226 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda);
227 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
228 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
229 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
230 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
231 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
232 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
233 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
234 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
235 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
236 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
237 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
238 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
239 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
240 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
241 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
242 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
243 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
244 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
245 /**
246   * @}
247   */
248 
249 /* Exported functions --------------------------------------------------------*/
250 /** @defgroup IRDA_Exported_Functions IrDA Exported Functions
251   * @{
252   */
253 
254 /** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
255   *  @brief    Initialization and Configuration functions
256   *
257 @verbatim
258 
259   ==============================================================================
260             ##### Initialization and Configuration functions #####
261   ==============================================================================
262     [..]
263     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
264     in asynchronous IrDA mode.
265       (+) For the asynchronous mode only these parameters can be configured:
266         (++) BaudRate
267         (++) WordLength
268         (++) Parity: If the parity is enabled, then the MSB bit of the data written
269              in the data register is transmitted but is changed by the parity bit.
270              Depending on the frame length defined by the M bit (8-bits or 9-bits),
271              please refer to Reference manual for possible IRDA frame formats.
272         (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
273              not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
274              specification specifies a minimum of 10 ms delay between transmission and
275              reception (IrDA is a half duplex protocol).
276         (++) Mode: Receiver/transmitter modes
277         (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
278     [..]
279     The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
280     are available in reference manual).
281 
282 @endverbatim
283   * @{
284   */
285 
286 /**
287   * @brief  Initializes the IRDA mode according to the specified
288   *         parameters in the IRDA_InitTypeDef and create the associated handle.
289   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
290   *                the configuration information for the specified IRDA module.
291   * @retval HAL status
292   */
HAL_IRDA_Init(IRDA_HandleTypeDef * hirda)293 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
294 {
295   /* Check the IRDA handle allocation */
296   if (hirda == NULL)
297   {
298     return HAL_ERROR;
299   }
300 
301   /* Check the IRDA instance parameters */
302   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
303   /* Check the IRDA mode parameter in the IRDA handle */
304   assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
305 
306   if (hirda->gState == HAL_IRDA_STATE_RESET)
307   {
308     /* Allocate lock resource and initialize it */
309     hirda->Lock = HAL_UNLOCKED;
310 
311 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
312     IRDA_InitCallbacksToDefault(hirda);
313 
314     if (hirda->MspInitCallback == NULL)
315     {
316       hirda->MspInitCallback = HAL_IRDA_MspInit;
317     }
318 
319     /* Init the low level hardware */
320     hirda->MspInitCallback(hirda);
321 #else
322     /* Init the low level hardware : GPIO, CLOCK */
323     HAL_IRDA_MspInit(hirda);
324 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
325   }
326 
327   hirda->gState = HAL_IRDA_STATE_BUSY;
328 
329   /* Disable the IRDA peripheral */
330   __HAL_IRDA_DISABLE(hirda);
331 
332   /* Set the IRDA communication parameters */
333   IRDA_SetConfig(hirda);
334 
335   /* In IrDA mode, the following bits must be kept cleared:
336   - LINEN, STOP and CLKEN bits in the USART_CR2 register,
337   - SCEN and HDSEL bits in the USART_CR3 register.*/
338   CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN));
339   CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
340 
341   /* Enable the IRDA peripheral */
342   __HAL_IRDA_ENABLE(hirda);
343 
344   /* Set the prescaler */
345   MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
346 
347   /* Configure the IrDA mode */
348   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
349 
350   /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
351   SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
352 
353   /* Initialize the IRDA state*/
354   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
355   hirda->gState = HAL_IRDA_STATE_READY;
356   hirda->RxState = HAL_IRDA_STATE_READY;
357 
358   return HAL_OK;
359 }
360 
361 /**
362   * @brief  DeInitializes the IRDA peripheral
363   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
364   *                the configuration information for the specified IRDA module.
365   * @retval HAL status
366   */
HAL_IRDA_DeInit(IRDA_HandleTypeDef * hirda)367 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
368 {
369   /* Check the IRDA handle allocation */
370   if (hirda == NULL)
371   {
372     return HAL_ERROR;
373   }
374 
375   /* Check the parameters */
376   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
377 
378   hirda->gState = HAL_IRDA_STATE_BUSY;
379 
380   /* Disable the Peripheral */
381   __HAL_IRDA_DISABLE(hirda);
382 
383   /* DeInit the low level hardware */
384 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
385   if (hirda->MspDeInitCallback == NULL)
386   {
387     hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
388   }
389   /* DeInit the low level hardware */
390   hirda->MspDeInitCallback(hirda);
391 #else
392   HAL_IRDA_MspDeInit(hirda);
393 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
394 
395   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
396 
397   hirda->gState = HAL_IRDA_STATE_RESET;
398   hirda->RxState = HAL_IRDA_STATE_RESET;
399 
400   /* Release Lock */
401   __HAL_UNLOCK(hirda);
402 
403   return HAL_OK;
404 }
405 
406 /**
407   * @brief  IRDA MSP Init.
408   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
409   *                the configuration information for the specified IRDA module.
410   * @retval None
411   */
HAL_IRDA_MspInit(IRDA_HandleTypeDef * hirda)412 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
413 {
414   /* Prevent unused argument(s) compilation warning */
415   UNUSED(hirda);
416 
417   /* NOTE: This function should not be modified, when the callback is needed,
418            the HAL_IRDA_MspInit can be implemented in the user file
419    */
420 }
421 
422 /**
423   * @brief  IRDA MSP DeInit.
424   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
425   *                the configuration information for the specified IRDA module.
426   * @retval None
427   */
HAL_IRDA_MspDeInit(IRDA_HandleTypeDef * hirda)428 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
429 {
430   /* Prevent unused argument(s) compilation warning */
431   UNUSED(hirda);
432 
433   /* NOTE: This function should not be modified, when the callback is needed,
434            the HAL_IRDA_MspDeInit can be implemented in the user file
435    */
436 }
437 
438 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
439 /**
440   * @brief  Register a User IRDA Callback
441   *         To be used instead of the weak predefined callback
442   * @param  hirda irda handle
443   * @param  CallbackID ID of the callback to be registered
444   *         This parameter can be one of the following values:
445   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
446   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
447   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
448   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
449   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
450   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
451   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
452   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
453   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
454   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
455   * @param  pCallback pointer to the Callback function
456   * @retval HAL status
457   */
HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef * hirda,HAL_IRDA_CallbackIDTypeDef CallbackID,pIRDA_CallbackTypeDef pCallback)458 HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID, pIRDA_CallbackTypeDef pCallback)
459 {
460   HAL_StatusTypeDef status = HAL_OK;
461 
462   if (pCallback == NULL)
463   {
464     /* Update the error code */
465     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
466 
467     return HAL_ERROR;
468   }
469   /* Process locked */
470   __HAL_LOCK(hirda);
471 
472   if (hirda->gState == HAL_IRDA_STATE_READY)
473   {
474     switch (CallbackID)
475     {
476       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
477         hirda->TxHalfCpltCallback = pCallback;
478         break;
479 
480       case HAL_IRDA_TX_COMPLETE_CB_ID :
481         hirda->TxCpltCallback = pCallback;
482         break;
483 
484       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
485         hirda->RxHalfCpltCallback = pCallback;
486         break;
487 
488       case HAL_IRDA_RX_COMPLETE_CB_ID :
489         hirda->RxCpltCallback = pCallback;
490         break;
491 
492       case HAL_IRDA_ERROR_CB_ID :
493         hirda->ErrorCallback = pCallback;
494         break;
495 
496       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
497         hirda->AbortCpltCallback = pCallback;
498         break;
499 
500       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
501         hirda->AbortTransmitCpltCallback = pCallback;
502         break;
503 
504       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
505         hirda->AbortReceiveCpltCallback = pCallback;
506         break;
507 
508       case HAL_IRDA_MSPINIT_CB_ID :
509         hirda->MspInitCallback = pCallback;
510         break;
511 
512       case HAL_IRDA_MSPDEINIT_CB_ID :
513         hirda->MspDeInitCallback = pCallback;
514         break;
515 
516       default :
517         /* Update the error code */
518         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
519 
520         /* Return error status */
521         status =  HAL_ERROR;
522         break;
523     }
524   }
525   else if (hirda->gState == HAL_IRDA_STATE_RESET)
526   {
527     switch (CallbackID)
528     {
529       case HAL_IRDA_MSPINIT_CB_ID :
530         hirda->MspInitCallback = pCallback;
531         break;
532 
533       case HAL_IRDA_MSPDEINIT_CB_ID :
534         hirda->MspDeInitCallback = pCallback;
535         break;
536 
537       default :
538         /* Update the error code */
539         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
540 
541         /* Return error status */
542         status =  HAL_ERROR;
543         break;
544     }
545   }
546   else
547   {
548     /* Update the error code */
549     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
550 
551     /* Return error status */
552     status =  HAL_ERROR;
553   }
554 
555   /* Release Lock */
556   __HAL_UNLOCK(hirda);
557 
558   return status;
559 }
560 
561 /**
562   * @brief  Unregister an IRDA callback
563   *         IRDA callback is redirected to the weak predefined callback
564   * @param  hirda irda handle
565   * @param  CallbackID ID of the callback to be unregistered
566   *         This parameter can be one of the following values:
567   *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
568   *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
569   *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
570   *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
571   *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
572   *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
573   *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
574   *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
575   *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
576   *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
577   * @retval HAL status
578   */
HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef * hirda,HAL_IRDA_CallbackIDTypeDef CallbackID)579 HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID)
580 {
581   HAL_StatusTypeDef status = HAL_OK;
582 
583   /* Process locked */
584   __HAL_LOCK(hirda);
585 
586   if (HAL_IRDA_STATE_READY == hirda->gState)
587   {
588     switch (CallbackID)
589     {
590       case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
591         hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback       */
592         break;
593 
594       case HAL_IRDA_TX_COMPLETE_CB_ID :
595         hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback;                       /* Legacy weak TxCpltCallback            */
596         break;
597 
598       case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
599         hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback        */
600         break;
601 
602       case HAL_IRDA_RX_COMPLETE_CB_ID :
603         hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback;                       /* Legacy weak RxCpltCallback            */
604         break;
605 
606       case HAL_IRDA_ERROR_CB_ID :
607         hirda->ErrorCallback = HAL_IRDA_ErrorCallback;                         /* Legacy weak ErrorCallback             */
608         break;
609 
610       case HAL_IRDA_ABORT_COMPLETE_CB_ID :
611         hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback         */
612         break;
613 
614       case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
615         hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
616         break;
617 
618       case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
619         hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback;   /* Legacy weak AbortReceiveCpltCallback  */
620         break;
621 
622       case HAL_IRDA_MSPINIT_CB_ID :
623         hirda->MspInitCallback = HAL_IRDA_MspInit;                             /* Legacy weak MspInitCallback           */
624         break;
625 
626       case HAL_IRDA_MSPDEINIT_CB_ID :
627         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;                         /* Legacy weak MspDeInitCallback         */
628         break;
629 
630       default :
631         /* Update the error code */
632         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
633 
634         /* Return error status */
635         status =  HAL_ERROR;
636         break;
637     }
638   }
639   else if (HAL_IRDA_STATE_RESET == hirda->gState)
640   {
641     switch (CallbackID)
642     {
643       case HAL_IRDA_MSPINIT_CB_ID :
644         hirda->MspInitCallback = HAL_IRDA_MspInit;
645         break;
646 
647       case HAL_IRDA_MSPDEINIT_CB_ID :
648         hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
649         break;
650 
651       default :
652         /* Update the error code */
653         hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
654 
655         /* Return error status */
656         status =  HAL_ERROR;
657         break;
658     }
659   }
660   else
661   {
662     /* Update the error code */
663     hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
664 
665     /* Return error status */
666     status =  HAL_ERROR;
667   }
668 
669   /* Release Lock */
670   __HAL_UNLOCK(hirda);
671 
672   return status;
673 }
674 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
675 
676 /**
677   * @}
678   */
679 
680 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
681   *  @brief   IRDA Transmit and Receive functions
682   *
683 @verbatim
684   ==============================================================================
685                       ##### IO operation functions #####
686   ==============================================================================
687     [..]
688     This subsection provides a set of functions allowing to manage the IRDA data transfers.
689     IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
690     on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
691     is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
692     While receiving data, transmission should be avoided as the data to be transmitted
693     could be corrupted.
694 
695     (#) There are two modes of transfer:
696        (++) Blocking mode: The communication is performed in polling mode.
697             The HAL status of all data processing is returned by the same function
698             after finishing transfer.
699        (++) Non-Blocking mode: The communication is performed using Interrupts
700            or DMA, these API's return the HAL status.
701            The end of the data processing will be indicated through the
702            dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
703            using DMA mode.
704            The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
705            will be executed respectively at the end of the Transmit or Receive process
706            The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
707 
708     (#) Blocking mode APIs are :
709         (++) HAL_IRDA_Transmit()
710         (++) HAL_IRDA_Receive()
711 
712     (#) Non Blocking mode APIs with Interrupt are :
713         (++) HAL_IRDA_Transmit_IT()
714         (++) HAL_IRDA_Receive_IT()
715         (++) HAL_IRDA_IRQHandler()
716 
717     (#) Non Blocking mode functions with DMA are :
718         (++) HAL_IRDA_Transmit_DMA()
719         (++) HAL_IRDA_Receive_DMA()
720         (++) HAL_IRDA_DMAPause()
721         (++) HAL_IRDA_DMAResume()
722         (++) HAL_IRDA_DMAStop()
723 
724     (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
725         (++) HAL_IRDA_TxHalfCpltCallback()
726         (++) HAL_IRDA_TxCpltCallback()
727         (++) HAL_IRDA_RxHalfCpltCallback()
728         (++) HAL_IRDA_RxCpltCallback()
729         (++) HAL_IRDA_ErrorCallback()
730 
731     (#) Non-Blocking mode transfers could be aborted using Abort API's :
732         (+) HAL_IRDA_Abort()
733         (+) HAL_IRDA_AbortTransmit()
734         (+) HAL_IRDA_AbortReceive()
735         (+) HAL_IRDA_Abort_IT()
736         (+) HAL_IRDA_AbortTransmit_IT()
737         (+) HAL_IRDA_AbortReceive_IT()
738 
739     (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
740         (+) HAL_IRDA_AbortCpltCallback()
741         (+) HAL_IRDA_AbortTransmitCpltCallback()
742         (+) HAL_IRDA_AbortReceiveCpltCallback()
743 
744     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
745         Errors are handled as follows :
746         (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
747             to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
748             Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
749             and HAL_IRDA_ErrorCallback() user callback is executed. Transfer is kept ongoing on IRDA side.
750             If user wants to abort it, Abort services should be called by user.
751         (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
752             This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
753             Error code is set to allow user to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed.
754 
755 @endverbatim
756   * @{
757   */
758 
759 /**
760   * @brief Sends an amount of data in blocking mode.
761   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
762   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
763   *        of u16 available through pData.
764   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
765   *              the configuration information for the specified IRDA module.
766   * @param pData Pointer to data buffer (u8 or u16 data elements).
767   * @param Size  Amount of data elements (u8 or u16) to be sent.
768   * @param Timeout Specify timeout value.
769   * @retval HAL status
770   */
HAL_IRDA_Transmit(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size,uint32_t Timeout)771 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
772 {
773   const uint16_t *tmp;
774   uint32_t tickstart = 0U;
775 
776   /* Check that a Tx process is not already ongoing */
777   if (hirda->gState == HAL_IRDA_STATE_READY)
778   {
779     if ((pData == NULL) || (Size == 0U))
780     {
781       return  HAL_ERROR;
782     }
783 
784     /* Process Locked */
785     __HAL_LOCK(hirda);
786 
787     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
788     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
789 
790     /* Init tickstart for timeout management*/
791     tickstart = HAL_GetTick();
792 
793     hirda->TxXferSize = Size;
794     hirda->TxXferCount = Size;
795     while (hirda->TxXferCount > 0U)
796     {
797       hirda->TxXferCount--;
798       if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
799       {
800         if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
801         {
802           return HAL_TIMEOUT;
803         }
804         tmp = (const uint16_t *) pData;
805         hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
806         if (hirda->Init.Parity == IRDA_PARITY_NONE)
807         {
808           pData += 2U;
809         }
810         else
811         {
812           pData += 1U;
813         }
814       }
815       else
816       {
817         if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
818         {
819           return HAL_TIMEOUT;
820         }
821         hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
822       }
823     }
824 
825     if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
826     {
827       return HAL_TIMEOUT;
828     }
829 
830     /* At end of Tx process, restore hirda->gState to Ready */
831     hirda->gState = HAL_IRDA_STATE_READY;
832 
833     /* Process Unlocked */
834     __HAL_UNLOCK(hirda);
835 
836     return HAL_OK;
837   }
838   else
839   {
840     return HAL_BUSY;
841   }
842 }
843 
844 /**
845   * @brief Receive an amount of data in blocking mode.
846   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
847   *        the received data is handled as a set of u16. In this case, Size must reflect the number
848   *        of u16 available through pData.
849   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
850   *              the configuration information for the specified IRDA module.
851   * @param pData Pointer to data buffer (u8 or u16 data elements).
852   * @param Size  Amount of data elements (u8 or u16) to be received.
853   * @param Timeout Specify timeout value
854   * @retval HAL status
855   */
HAL_IRDA_Receive(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size,uint32_t Timeout)856 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
857 {
858   uint16_t *tmp;
859   uint32_t tickstart = 0U;
860 
861   /* Check that a Rx process is not already ongoing */
862   if (hirda->RxState == HAL_IRDA_STATE_READY)
863   {
864     if ((pData == NULL) || (Size == 0U))
865     {
866       return  HAL_ERROR;
867     }
868 
869     /* Process Locked */
870     __HAL_LOCK(hirda);
871 
872     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
873     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
874 
875     /* Init tickstart for timeout management*/
876     tickstart = HAL_GetTick();
877 
878     hirda->RxXferSize = Size;
879     hirda->RxXferCount = Size;
880 
881     /* Check the remain data to be received */
882     while (hirda->RxXferCount > 0U)
883     {
884       hirda->RxXferCount--;
885 
886       if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
887       {
888         if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
889         {
890           return HAL_TIMEOUT;
891         }
892         tmp = (uint16_t *) pData ;
893         if (hirda->Init.Parity == IRDA_PARITY_NONE)
894         {
895           *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
896           pData += 2U;
897         }
898         else
899         {
900           *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
901           pData += 1U;
902         }
903       }
904       else
905       {
906         if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
907         {
908           return HAL_TIMEOUT;
909         }
910         if (hirda->Init.Parity == IRDA_PARITY_NONE)
911         {
912           *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
913         }
914         else
915         {
916           *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
917         }
918       }
919     }
920 
921     /* At end of Rx process, restore hirda->RxState to Ready */
922     hirda->RxState = HAL_IRDA_STATE_READY;
923 
924     /* Process Unlocked */
925     __HAL_UNLOCK(hirda);
926 
927     return HAL_OK;
928   }
929   else
930   {
931     return HAL_BUSY;
932   }
933 }
934 
935 /**
936   * @brief Send an amount of data in non blocking mode.
937   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
938   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
939   *        of u16 available through pData.
940   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
941   *              the configuration information for the specified IRDA module.
942   * @param pData Pointer to data buffer (u8 or u16 data elements).
943   * @param Size  Amount of data elements (u8 or u16) to be sent.
944   * @retval HAL status
945   */
HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size)946 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
947 {
948   /* Check that a Tx process is not already ongoing */
949   if (hirda->gState == HAL_IRDA_STATE_READY)
950   {
951     if ((pData == NULL) || (Size == 0U))
952     {
953       return HAL_ERROR;
954     }
955 
956     /* Process Locked */
957     __HAL_LOCK(hirda);
958 
959     hirda->pTxBuffPtr = pData;
960     hirda->TxXferSize = Size;
961     hirda->TxXferCount = Size;
962 
963     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
964     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
965 
966     /* Process Unlocked */
967     __HAL_UNLOCK(hirda);
968 
969     /* Enable the IRDA Transmit Data Register Empty Interrupt */
970     SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
971 
972     return HAL_OK;
973   }
974   else
975   {
976     return HAL_BUSY;
977   }
978 }
979 
980 /**
981   * @brief Receive an amount of data in non blocking mode.
982   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
983   *        the received data is handled as a set of u16. In this case, Size must reflect the number
984   *        of u16 available through pData.
985   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
986   *              the configuration information for the specified IRDA module.
987   * @param pData Pointer to data buffer (u8 or u16 data elements).
988   * @param Size  Amount of data elements (u8 or u16) to be received.
989   * @retval HAL status
990   */
HAL_IRDA_Receive_IT(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size)991 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
992 {
993   /* Check that a Rx process is not already ongoing */
994   if (hirda->RxState == HAL_IRDA_STATE_READY)
995   {
996     if ((pData == NULL) || (Size == 0U))
997     {
998       return HAL_ERROR;
999     }
1000 
1001     /* Process Locked */
1002     __HAL_LOCK(hirda);
1003 
1004     hirda->pRxBuffPtr = pData;
1005     hirda->RxXferSize = Size;
1006     hirda->RxXferCount = Size;
1007 
1008     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1009     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1010 
1011     /* Process Unlocked */
1012     __HAL_UNLOCK(hirda);
1013 
1014     if (hirda->Init.Parity != IRDA_PARITY_NONE)
1015     {
1016       /* Enable the IRDA Parity Error and Data Register Not Empty Interrupts */
1017       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1018     }
1019     else
1020     {
1021       /* Enable the IRDA Data Register Not Empty Interrupts */
1022        SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
1023     }
1024 
1025     /* Enable the IRDA Error Interrupt: (Frame error, Noise error, Overrun error) */
1026     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1027 
1028     return HAL_OK;
1029   }
1030   else
1031   {
1032     return HAL_BUSY;
1033   }
1034 }
1035 
1036 /**
1037   * @brief Send an amount of data in DMA mode.
1038   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1039   *        the sent data is handled as a set of u16. In this case, Size must reflect the number
1040   *        of u16 available through pData.
1041   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1042   *              the configuration information for the specified IRDA module.
1043   * @param pData Pointer to data buffer (u8 or u16 data elements).
1044   * @param Size  Amount of data elements (u8 or u16) to be sent.
1045   * @retval HAL status
1046   */
HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size)1047 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
1048 {
1049   const uint32_t *tmp;
1050 
1051   /* Check that a Tx process is not already ongoing */
1052   if (hirda->gState == HAL_IRDA_STATE_READY)
1053   {
1054     if ((pData == NULL) || (Size == 0U))
1055     {
1056       return HAL_ERROR;
1057     }
1058 
1059     /* Process Locked */
1060     __HAL_LOCK(hirda);
1061 
1062     hirda->pTxBuffPtr = pData;
1063     hirda->TxXferSize = Size;
1064     hirda->TxXferCount = Size;
1065 
1066     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1067     hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1068 
1069     /* Set the IRDA DMA transfer complete callback */
1070     hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
1071 
1072     /* Set the IRDA DMA half transfer complete callback */
1073     hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
1074 
1075     /* Set the DMA error callback */
1076     hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
1077 
1078     /* Set the DMA abort callback */
1079     hirda->hdmatx->XferAbortCallback = NULL;
1080 
1081     /* Enable the IRDA transmit DMA stream */
1082     tmp = (const uint32_t *)&pData;
1083     HAL_DMA_Start_IT(hirda->hdmatx, *(const uint32_t *)tmp, (uint32_t)&hirda->Instance->DR, Size);
1084 
1085     /* Clear the TC flag in the SR register by writing 0 to it */
1086     __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
1087 
1088     /* Process Unlocked */
1089     __HAL_UNLOCK(hirda);
1090 
1091     /* Enable the DMA transfer for transmit request by setting the DMAT bit
1092     in the USART CR3 register */
1093     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1094 
1095     return HAL_OK;
1096   }
1097   else
1098   {
1099     return HAL_BUSY;
1100   }
1101 }
1102 
1103 /**
1104   * @brief Receives an amount of data in DMA mode.
1105   * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1106   *        the received data is handled as a set of u16. In this case, Size must reflect the number
1107   *        of u16 available through pData.
1108   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1109   *              the configuration information for the specified IRDA module.
1110   * @param pData Pointer to data buffer (u8 or u16 data elements).
1111   * @param Size  Amount of data elements (u8 or u16) to be received.
1112   * @note   When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
1113   * @retval HAL status
1114   */
HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size)1115 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1116 {
1117   uint32_t *tmp;
1118 
1119   /* Check that a Rx process is not already ongoing */
1120   if (hirda->RxState == HAL_IRDA_STATE_READY)
1121   {
1122     if ((pData == NULL) || (Size == 0U))
1123     {
1124       return HAL_ERROR;
1125     }
1126 
1127     /* Process Locked */
1128     __HAL_LOCK(hirda);
1129 
1130     hirda->pRxBuffPtr = pData;
1131     hirda->RxXferSize = Size;
1132 
1133     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1134     hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1135 
1136     /* Set the IRDA DMA transfer complete callback */
1137     hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
1138 
1139     /* Set the IRDA DMA half transfer complete callback */
1140     hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
1141 
1142     /* Set the DMA error callback */
1143     hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
1144 
1145     /* Set the DMA abort callback */
1146     hirda->hdmarx->XferAbortCallback = NULL;
1147 
1148     /* Enable the DMA stream */
1149     tmp = (uint32_t *)&pData;
1150     HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t *)tmp, Size);
1151 
1152     /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
1153     __HAL_IRDA_CLEAR_OREFLAG(hirda);
1154 
1155     /* Process Unlocked */
1156     __HAL_UNLOCK(hirda);
1157 
1158     if (hirda->Init.Parity != IRDA_PARITY_NONE)
1159     {
1160       /* Enable the IRDA Parity Error Interrupt */
1161       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1162     }
1163 
1164     /* Enable the IRDA Error Interrupt: (Frame error, Noise error, Overrun error) */
1165     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1166 
1167     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1168     in the USART CR3 register */
1169     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1170 
1171     return HAL_OK;
1172   }
1173   else
1174   {
1175     return HAL_BUSY;
1176   }
1177 }
1178 
1179 /**
1180   * @brief Pauses the DMA Transfer.
1181   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1182   *                the configuration information for the specified IRDA module.
1183   * @retval HAL status
1184   */
HAL_IRDA_DMAPause(IRDA_HandleTypeDef * hirda)1185 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
1186 {
1187   uint32_t dmarequest = 0x00U;
1188 
1189   /* Process Locked */
1190   __HAL_LOCK(hirda);
1191 
1192   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
1193   if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
1194   {
1195     /* Disable the IRDA DMA Tx request */
1196     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1197   }
1198 
1199   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
1200   if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
1201   {
1202     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1203     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1204     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1205 
1206     /* Disable the IRDA DMA Rx request */
1207     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1208   }
1209 
1210   /* Process Unlocked */
1211   __HAL_UNLOCK(hirda);
1212 
1213   return HAL_OK;
1214 }
1215 
1216 /**
1217   * @brief Resumes the DMA Transfer.
1218   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1219   *                the configuration information for the specified IRDA module.
1220   * @retval HAL status
1221   */
HAL_IRDA_DMAResume(IRDA_HandleTypeDef * hirda)1222 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
1223 {
1224   /* Process Locked */
1225   __HAL_LOCK(hirda);
1226 
1227   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1228   {
1229     /* Enable the IRDA DMA Tx request */
1230     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1231   }
1232 
1233   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1234   {
1235     /* Clear the Overrun flag before resuming the Rx transfer */
1236     __HAL_IRDA_CLEAR_OREFLAG(hirda);
1237 
1238     /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1239     if (hirda->Init.Parity != IRDA_PARITY_NONE)
1240     {
1241       SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1242     }
1243     SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1244 
1245     /* Enable the IRDA DMA Rx request */
1246     SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1247   }
1248 
1249   /* Process Unlocked */
1250   __HAL_UNLOCK(hirda);
1251 
1252   return HAL_OK;
1253 }
1254 
1255 /**
1256   * @brief Stops the DMA Transfer.
1257   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1258   *                the configuration information for the specified IRDA module.
1259   * @retval HAL status
1260   */
HAL_IRDA_DMAStop(IRDA_HandleTypeDef * hirda)1261 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
1262 {
1263   uint32_t dmarequest = 0x00U;
1264   /* The Lock is not implemented on this API to allow the user application
1265      to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
1266      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1267      and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
1268   */
1269 
1270   /* Stop IRDA DMA Tx request if ongoing */
1271   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
1272   if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
1273   {
1274     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1275 
1276     /* Abort the IRDA DMA Tx channel */
1277     if (hirda->hdmatx != NULL)
1278     {
1279       HAL_DMA_Abort(hirda->hdmatx);
1280     }
1281     IRDA_EndTxTransfer(hirda);
1282   }
1283 
1284   /* Stop IRDA DMA Rx request if ongoing */
1285   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
1286   if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
1287   {
1288     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1289 
1290     /* Abort the IRDA DMA Rx channel */
1291     if (hirda->hdmarx != NULL)
1292     {
1293       HAL_DMA_Abort(hirda->hdmarx);
1294     }
1295     IRDA_EndRxTransfer(hirda);
1296   }
1297 
1298   return HAL_OK;
1299 }
1300 
1301 /**
1302   * @brief  Abort ongoing transfers (blocking mode).
1303   * @param  hirda IRDA handle.
1304   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1305   *         This procedure performs following operations :
1306   *           - Disable PPP Interrupts
1307   *           - Disable the DMA transfer in the peripheral register (if enabled)
1308   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1309   *           - Set handle State to READY
1310   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1311   * @retval HAL status
1312 */
HAL_IRDA_Abort(IRDA_HandleTypeDef * hirda)1313 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
1314 {
1315   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1316   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1317   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1318 
1319   /* Disable the IRDA DMA Tx request if enabled */
1320   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1321   {
1322     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1323 
1324     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1325     if (hirda->hdmatx != NULL)
1326     {
1327       /* Set the IRDA DMA Abort callback to Null.
1328          No call back execution at end of DMA abort procedure */
1329       hirda->hdmatx->XferAbortCallback = NULL;
1330 
1331       HAL_DMA_Abort(hirda->hdmatx);
1332     }
1333   }
1334 
1335   /* Disable the IRDA DMA Rx request if enabled */
1336   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1337   {
1338     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1339 
1340     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1341     if (hirda->hdmarx != NULL)
1342     {
1343       /* Set the IRDA DMA Abort callback to Null.
1344          No call back execution at end of DMA abort procedure */
1345       hirda->hdmarx->XferAbortCallback = NULL;
1346 
1347       HAL_DMA_Abort(hirda->hdmarx);
1348     }
1349   }
1350 
1351   /* Reset Tx and Rx transfer counters */
1352   hirda->TxXferCount = 0x00U;
1353   hirda->RxXferCount = 0x00U;
1354 
1355   /* Reset ErrorCode */
1356   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1357 
1358   /* Restore hirda->RxState and hirda->gState to Ready */
1359   hirda->RxState = HAL_IRDA_STATE_READY;
1360   hirda->gState = HAL_IRDA_STATE_READY;
1361 
1362   return HAL_OK;
1363 }
1364 
1365 /**
1366   * @brief  Abort ongoing Transmit transfer (blocking mode).
1367   * @param  hirda IRDA handle.
1368   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1369   *         This procedure performs following operations :
1370   *           - Disable PPP Interrupts
1371   *           - Disable the DMA transfer in the peripheral register (if enabled)
1372   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1373   *           - Set handle State to READY
1374   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1375   * @retval HAL status
1376 */
HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef * hirda)1377 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
1378 {
1379   /* Disable TXEIE and TCIE interrupts */
1380   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1381 
1382   /* Disable the IRDA DMA Tx request if enabled */
1383   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1384   {
1385     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1386 
1387     /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1388     if (hirda->hdmatx != NULL)
1389     {
1390       /* Set the IRDA DMA Abort callback to Null.
1391          No call back execution at end of DMA abort procedure */
1392       hirda->hdmatx->XferAbortCallback = NULL;
1393 
1394       HAL_DMA_Abort(hirda->hdmatx);
1395     }
1396   }
1397 
1398   /* Reset Tx transfer counter */
1399   hirda->TxXferCount = 0x00U;
1400 
1401   /* Restore hirda->gState to Ready */
1402   hirda->gState = HAL_IRDA_STATE_READY;
1403 
1404   return HAL_OK;
1405 }
1406 
1407 /**
1408   * @brief  Abort ongoing Receive transfer (blocking mode).
1409   * @param  hirda IRDA handle.
1410   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1411   *         This procedure performs following operations :
1412   *           - Disable PPP Interrupts
1413   *           - Disable the DMA transfer in the peripheral register (if enabled)
1414   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1415   *           - Set handle State to READY
1416   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1417   * @retval HAL status
1418 */
HAL_IRDA_AbortReceive(IRDA_HandleTypeDef * hirda)1419 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
1420 {
1421   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1422   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1423   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1424 
1425   /* Disable the IRDA DMA Rx request if enabled */
1426   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1427   {
1428     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1429 
1430     /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1431     if (hirda->hdmarx != NULL)
1432     {
1433       /* Set the IRDA DMA Abort callback to Null.
1434          No call back execution at end of DMA abort procedure */
1435       hirda->hdmarx->XferAbortCallback = NULL;
1436 
1437       HAL_DMA_Abort(hirda->hdmarx);
1438     }
1439   }
1440 
1441   /* Reset Rx transfer counter */
1442   hirda->RxXferCount = 0x00U;
1443 
1444   /* Restore hirda->RxState to Ready */
1445   hirda->RxState = HAL_IRDA_STATE_READY;
1446 
1447   return HAL_OK;
1448 }
1449 
1450 /**
1451   * @brief  Abort ongoing transfers (Interrupt mode).
1452   * @param  hirda IRDA handle.
1453   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1454   *         This procedure performs following operations :
1455   *           - Disable PPP Interrupts
1456   *           - Disable the DMA transfer in the peripheral register (if enabled)
1457   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1458   *           - Set handle State to READY
1459   *           - At abort completion, call user abort complete callback
1460   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1461   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1462   * @retval HAL status
1463 */
HAL_IRDA_Abort_IT(IRDA_HandleTypeDef * hirda)1464 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
1465 {
1466   uint32_t AbortCplt = 0x01U;
1467 
1468   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1469   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1470   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1471 
1472   /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
1473      before any call to DMA Abort functions */
1474   /* DMA Tx Handle is valid */
1475   if (hirda->hdmatx != NULL)
1476   {
1477     /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
1478        Otherwise, set it to NULL */
1479     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1480     {
1481       hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
1482     }
1483     else
1484     {
1485       hirda->hdmatx->XferAbortCallback = NULL;
1486     }
1487   }
1488   /* DMA Rx Handle is valid */
1489   if (hirda->hdmarx != NULL)
1490   {
1491     /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
1492        Otherwise, set it to NULL */
1493     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1494     {
1495       hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
1496     }
1497     else
1498     {
1499       hirda->hdmarx->XferAbortCallback = NULL;
1500     }
1501   }
1502 
1503   /* Disable the IRDA DMA Tx request if enabled */
1504   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1505   {
1506     /* Disable DMA Tx at IRDA level */
1507     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1508 
1509     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1510     if (hirda->hdmatx != NULL)
1511     {
1512       /* IRDA Tx DMA Abort callback has already been initialised :
1513          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1514 
1515       /* Abort DMA TX */
1516       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1517       {
1518         hirda->hdmatx->XferAbortCallback = NULL;
1519       }
1520       else
1521       {
1522         AbortCplt = 0x00U;
1523       }
1524     }
1525   }
1526 
1527   /* Disable the IRDA DMA Rx request if enabled */
1528   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1529   {
1530     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1531 
1532     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1533     if (hirda->hdmarx != NULL)
1534     {
1535       /* IRDA Rx DMA Abort callback has already been initialised :
1536          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1537 
1538       /* Abort DMA RX */
1539       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1540       {
1541         hirda->hdmarx->XferAbortCallback = NULL;
1542         AbortCplt = 0x01U;
1543       }
1544       else
1545       {
1546         AbortCplt = 0x00U;
1547       }
1548     }
1549   }
1550 
1551   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1552   if (AbortCplt == 0x01U)
1553   {
1554     /* Reset Tx and Rx transfer counters */
1555     hirda->TxXferCount = 0x00U;
1556     hirda->RxXferCount = 0x00U;
1557 
1558     /* Reset ErrorCode */
1559     hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1560 
1561     /* Restore hirda->gState and hirda->RxState to Ready */
1562     hirda->gState  = HAL_IRDA_STATE_READY;
1563     hirda->RxState = HAL_IRDA_STATE_READY;
1564 
1565     /* As no DMA to be aborted, call directly user Abort complete callback */
1566 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1567     /* Call registered Abort complete callback */
1568     hirda->AbortCpltCallback(hirda);
1569 #else
1570     /* Call legacy weak Abort complete callback */
1571     HAL_IRDA_AbortCpltCallback(hirda);
1572 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1573   }
1574 
1575   return HAL_OK;
1576 }
1577 
1578 /**
1579   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
1580   * @param  hirda IRDA handle.
1581   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1582   *         This procedure performs following operations :
1583   *           - Disable IRDA Interrupts (Tx)
1584   *           - Disable the DMA transfer in the peripheral register (if enabled)
1585   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1586   *           - Set handle State to READY
1587   *           - At abort completion, call user abort complete callback
1588   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1589   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1590   * @retval HAL status
1591 */
HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef * hirda)1592 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
1593 {
1594   /* Disable TXEIE and TCIE interrupts */
1595   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1596 
1597   /* Disable the IRDA DMA Tx request if enabled */
1598   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1599   {
1600     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1601 
1602     /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1603     if (hirda->hdmatx != NULL)
1604     {
1605       /* Set the IRDA DMA Abort callback :
1606          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1607       hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
1608 
1609       /* Abort DMA TX */
1610       if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1611       {
1612         /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
1613         hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
1614       }
1615     }
1616     else
1617     {
1618       /* Reset Tx transfer counter */
1619       hirda->TxXferCount = 0x00U;
1620 
1621       /* Restore hirda->gState to Ready */
1622       hirda->gState = HAL_IRDA_STATE_READY;
1623 
1624       /* As no DMA to be aborted, call directly user Abort complete callback */
1625 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1626       /* Call registered Abort Transmit Complete Callback */
1627       hirda->AbortTransmitCpltCallback(hirda);
1628 #else
1629       /* Call legacy weak Abort Transmit Complete Callback */
1630       HAL_IRDA_AbortTransmitCpltCallback(hirda);
1631 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1632     }
1633   }
1634   else
1635   {
1636     /* Reset Tx transfer counter */
1637     hirda->TxXferCount = 0x00U;
1638 
1639     /* Restore hirda->gState to Ready */
1640     hirda->gState = HAL_IRDA_STATE_READY;
1641 
1642     /* As no DMA to be aborted, call directly user Abort complete callback */
1643 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1644     /* Call registered Abort Transmit Complete Callback */
1645     hirda->AbortTransmitCpltCallback(hirda);
1646 #else
1647     /* Call legacy weak Abort Transmit Complete Callback */
1648     HAL_IRDA_AbortTransmitCpltCallback(hirda);
1649 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1650   }
1651 
1652   return HAL_OK;
1653 }
1654 
1655 /**
1656   * @brief  Abort ongoing Receive transfer (Interrupt mode).
1657   * @param  hirda IRDA handle.
1658   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1659   *         This procedure performs following operations :
1660   *           - Disable PPP Interrupts
1661   *           - Disable the DMA transfer in the peripheral register (if enabled)
1662   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1663   *           - Set handle State to READY
1664   *           - At abort completion, call user abort complete callback
1665   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1666   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1667   * @retval HAL status
1668 */
HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef * hirda)1669 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
1670 {
1671   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1672   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1673   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1674 
1675   /* Disable the IRDA DMA Rx request if enabled */
1676   if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1677   {
1678     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1679 
1680     /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1681     if (hirda->hdmarx != NULL)
1682     {
1683       /* Set the IRDA DMA Abort callback :
1684          will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1685       hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
1686 
1687       /* Abort DMA RX */
1688       if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1689       {
1690         /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1691         hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1692       }
1693     }
1694     else
1695     {
1696       /* Reset Rx transfer counter */
1697       hirda->RxXferCount = 0x00U;
1698 
1699       /* Restore hirda->RxState to Ready */
1700       hirda->RxState = HAL_IRDA_STATE_READY;
1701 
1702       /* As no DMA to be aborted, call directly user Abort complete callback */
1703 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1704       /* Call registered Abort Receive Complete Callback */
1705       hirda->AbortReceiveCpltCallback(hirda);
1706 #else
1707       /* Call legacy weak Abort Receive Complete Callback */
1708       HAL_IRDA_AbortReceiveCpltCallback(hirda);
1709 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1710     }
1711   }
1712   else
1713   {
1714     /* Reset Rx transfer counter */
1715     hirda->RxXferCount = 0x00U;
1716 
1717     /* Restore hirda->RxState to Ready */
1718     hirda->RxState = HAL_IRDA_STATE_READY;
1719 
1720     /* As no DMA to be aborted, call directly user Abort complete callback */
1721 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1722     /* Call registered Abort Receive Complete Callback */
1723     hirda->AbortReceiveCpltCallback(hirda);
1724 #else
1725     /* Call legacy weak Abort Receive Complete Callback */
1726     HAL_IRDA_AbortReceiveCpltCallback(hirda);
1727 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1728   }
1729 
1730   return HAL_OK;
1731 }
1732 
1733 /**
1734   * @brief  This function handles IRDA interrupt request.
1735   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1736   *                the configuration information for the specified IRDA module.
1737   * @retval None
1738   */
HAL_IRDA_IRQHandler(IRDA_HandleTypeDef * hirda)1739 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
1740 {
1741   uint32_t isrflags   = READ_REG(hirda->Instance->SR);
1742   uint32_t cr1its     = READ_REG(hirda->Instance->CR1);
1743   uint32_t cr3its     = READ_REG(hirda->Instance->CR3);
1744   uint32_t errorflags = 0x00U;
1745   uint32_t dmarequest = 0x00U;
1746 
1747   /* If no error occurs */
1748   errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
1749   if (errorflags == RESET)
1750   {
1751     /* IRDA in mode Receiver -----------------------------------------------*/
1752     if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1753     {
1754       IRDA_Receive_IT(hirda);
1755       return;
1756     }
1757   }
1758 
1759   /* If some errors occur */
1760   if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
1761   {
1762     /* IRDA parity error interrupt occurred -------------------------------*/
1763     if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
1764     {
1765       hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
1766     }
1767 
1768     /* IRDA noise error interrupt occurred --------------------------------*/
1769     if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1770     {
1771       hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
1772     }
1773 
1774     /* IRDA frame error interrupt occurred --------------------------------*/
1775     if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1776     {
1777       hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
1778     }
1779 
1780     /* IRDA Over-Run interrupt occurred -----------------------------------*/
1781     if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
1782     {
1783       hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
1784     }
1785     /* Call IRDA Error Call back function if need be -----------------------*/
1786     if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
1787     {
1788       /* IRDA in mode Receiver ---------------------------------------------*/
1789       if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1790       {
1791         IRDA_Receive_IT(hirda);
1792       }
1793 
1794       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1795          consider error as blocking */
1796       dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
1797       if (((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
1798       {
1799         /* Blocking error : transfer is aborted
1800            Set the IRDA state ready to be able to start again the process,
1801            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1802         IRDA_EndRxTransfer(hirda);
1803 
1804         /* Disable the IRDA DMA Rx request if enabled */
1805         if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1806         {
1807           CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1808 
1809           /* Abort the IRDA DMA Rx channel */
1810           if (hirda->hdmarx != NULL)
1811           {
1812             /* Set the IRDA DMA Abort callback :
1813             will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
1814             hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
1815 
1816             /* Abort DMA RX */
1817             if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1818             {
1819               /* Call Directly XferAbortCallback function in case of error */
1820               hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1821             }
1822           }
1823           else
1824           {
1825 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1826             /* Call registered user error callback */
1827             hirda->ErrorCallback(hirda);
1828 #else
1829             /* Call legacy weak user error callback */
1830             HAL_IRDA_ErrorCallback(hirda);
1831 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1832           }
1833         }
1834         else
1835         {
1836 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1837           /* Call registered user error callback */
1838           hirda->ErrorCallback(hirda);
1839 #else
1840           /* Call legacy weak user error callback */
1841           HAL_IRDA_ErrorCallback(hirda);
1842 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1843         }
1844       }
1845       else
1846       {
1847         /* Non Blocking error : transfer could go on.
1848            Error is notified to user through user error callback */
1849 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1850         /* Call registered user error callback */
1851         hirda->ErrorCallback(hirda);
1852 #else
1853         /* Call legacy weak user error callback */
1854         HAL_IRDA_ErrorCallback(hirda);
1855 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1856 
1857         hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1858       }
1859     }
1860     return;
1861   } /* End if some error occurs */
1862 
1863   /* IRDA in mode Transmitter ------------------------------------------------*/
1864   if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
1865   {
1866     IRDA_Transmit_IT(hirda);
1867     return;
1868   }
1869 
1870   /* IRDA in mode Transmitter end --------------------------------------------*/
1871   if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
1872   {
1873     IRDA_EndTransmit_IT(hirda);
1874     return;
1875   }
1876 }
1877 
1878 /**
1879   * @brief  Tx Transfer complete callback.
1880   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1881   *                the configuration information for the specified IRDA module.
1882   * @retval None
1883   */
HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef * hirda)1884 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
1885 {
1886   /* Prevent unused argument(s) compilation warning */
1887   UNUSED(hirda);
1888 
1889   /* NOTE : This function should not be modified, when the callback is needed,
1890             the HAL_IRDA_TxCpltCallback can be implemented in the user file.
1891    */
1892 }
1893 
1894 /**
1895   * @brief  Tx Half Transfer completed callback.
1896   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1897   *                the configuration information for the specified USART module.
1898   * @retval None
1899   */
HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef * hirda)1900 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1901 {
1902   /* Prevent unused argument(s) compilation warning */
1903   UNUSED(hirda);
1904 
1905   /* NOTE : This function should not be modified, when the callback is needed,
1906             the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
1907    */
1908 }
1909 
1910 /**
1911   * @brief  Rx Transfer complete callback.
1912   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1913   *                the configuration information for the specified IRDA module.
1914   * @retval None
1915   */
HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef * hirda)1916 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
1917 {
1918   /* Prevent unused argument(s) compilation warning */
1919   UNUSED(hirda);
1920 
1921   /* NOTE : This function should not be modified, when the callback is needed,
1922             the HAL_IRDA_RxCpltCallback can be implemented in the user file.
1923    */
1924 }
1925 
1926 /**
1927   * @brief  Rx Half Transfer complete callback.
1928   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1929   *                the configuration information for the specified IRDA module.
1930   * @retval None
1931   */
HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef * hirda)1932 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1933 {
1934   /* Prevent unused argument(s) compilation warning */
1935   UNUSED(hirda);
1936 
1937   /* NOTE : This function should not be modified, when the callback is needed,
1938             the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
1939    */
1940 }
1941 
1942 /**
1943   * @brief  IRDA error callback.
1944   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1945   *                the configuration information for the specified IRDA module.
1946   * @retval None
1947   */
HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef * hirda)1948 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
1949 {
1950   /* Prevent unused argument(s) compilation warning */
1951   UNUSED(hirda);
1952 
1953   /* NOTE : This function should not be modified, when the callback is needed,
1954             the HAL_IRDA_ErrorCallback can be implemented in the user file.
1955    */
1956 }
1957 
1958 /**
1959   * @brief  IRDA Abort Complete callback.
1960   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1961   *                the configuration information for the specified IRDA module.
1962   * @retval None
1963   */
HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef * hirda)1964 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
1965 {
1966   /* Prevent unused argument(s) compilation warning */
1967   UNUSED(hirda);
1968 
1969   /* NOTE : This function should not be modified, when the callback is needed,
1970             the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
1971    */
1972 }
1973 
1974 /**
1975   * @brief  IRDA Abort Transmit Complete callback.
1976   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1977   *                the configuration information for the specified IRDA module.
1978   * @retval None
1979   */
HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef * hirda)1980 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
1981 {
1982   /* Prevent unused argument(s) compilation warning */
1983   UNUSED(hirda);
1984 
1985   /* NOTE : This function should not be modified, when the callback is needed,
1986             the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
1987    */
1988 }
1989 
1990 /**
1991   * @brief  IRDA Abort Receive Complete callback.
1992   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1993   *                the configuration information for the specified IRDA module.
1994   * @retval None
1995   */
HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef * hirda)1996 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
1997 {
1998   /* Prevent unused argument(s) compilation warning */
1999   UNUSED(hirda);
2000 
2001   /* NOTE : This function should not be modified, when the callback is needed,
2002             the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
2003    */
2004 }
2005 
2006 /**
2007   * @}
2008   */
2009 
2010 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
2011   *  @brief   IRDA State and Errors functions
2012   *
2013 @verbatim
2014   ==============================================================================
2015                   ##### Peripheral State and Errors functions #####
2016   ==============================================================================
2017   [..]
2018     This subsection provides a set of functions allowing to return the State of IrDA
2019     communication process and also return Peripheral Errors occurred during communication process
2020      (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
2021      (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication.
2022 
2023 @endverbatim
2024   * @{
2025   */
2026 
2027 /**
2028   * @brief  Return the IRDA state.
2029   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2030   *                the configuration information for the specified IRDA.
2031   * @retval HAL state
2032   */
HAL_IRDA_GetState(IRDA_HandleTypeDef * hirda)2033 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
2034 {
2035   uint32_t temp1 = 0x00U, temp2 = 0x00U;
2036   temp1 = hirda->gState;
2037   temp2 = hirda->RxState;
2038 
2039   return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
2040 }
2041 
2042 /**
2043   * @brief  Return the IRDA error code
2044   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2045   *              the configuration information for the specified IRDA.
2046   * @retval IRDA Error Code
2047   */
HAL_IRDA_GetError(IRDA_HandleTypeDef * hirda)2048 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
2049 {
2050   return hirda->ErrorCode;
2051 }
2052 
2053 /**
2054   * @}
2055   */
2056 
2057 /**
2058   * @}
2059   */
2060 
2061 /** @defgroup IRDA_Private_Functions IRDA Private Functions
2062   * @{
2063   */
2064 
2065 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2066 /**
2067   * @brief  Initialize the callbacks to their default values.
2068   * @param  hirda IRDA handle.
2069   * @retval none
2070   */
IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef * hirda)2071 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
2072 {
2073   /* Init the IRDA Callback settings */
2074   hirda->TxHalfCpltCallback        = HAL_IRDA_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2075   hirda->TxCpltCallback            = HAL_IRDA_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2076   hirda->RxHalfCpltCallback        = HAL_IRDA_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2077   hirda->RxCpltCallback            = HAL_IRDA_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2078   hirda->ErrorCallback             = HAL_IRDA_ErrorCallback;             /* Legacy weak ErrorCallback             */
2079   hirda->AbortCpltCallback         = HAL_IRDA_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2080   hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2081   hirda->AbortReceiveCpltCallback  = HAL_IRDA_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
2082 
2083 }
2084 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2085 
2086 /**
2087   * @brief  DMA IRDA transmit process complete callback.
2088   * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
2089   *               the configuration information for the specified DMA.
2090   * @retval None
2091   */
IRDA_DMATransmitCplt(DMA_HandleTypeDef * hdma)2092 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2093 {
2094   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2095   /* DMA Normal mode */
2096   if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
2097   {
2098     hirda->TxXferCount = 0U;
2099 
2100     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2101        in the IRDA CR3 register */
2102     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
2103 
2104     /* Enable the IRDA Transmit Complete Interrupt */
2105     SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2106   }
2107   /* DMA Circular mode */
2108   else
2109   {
2110 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2111     /* Call registered Tx complete callback */
2112     hirda->TxCpltCallback(hirda);
2113 #else
2114     /* Call legacy weak Tx complete callback */
2115     HAL_IRDA_TxCpltCallback(hirda);
2116 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2117   }
2118 }
2119 
2120 /**
2121   * @brief DMA IRDA receive process half complete callback
2122   * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
2123   *               the configuration information for the specified DMA.
2124   * @retval None
2125   */
IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef * hdma)2126 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
2127 {
2128   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2129 
2130 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2131   /* Call registered Tx Half complete callback */
2132   hirda->TxHalfCpltCallback(hirda);
2133 #else
2134   /* Call legacy weak Tx complete callback */
2135   HAL_IRDA_TxHalfCpltCallback(hirda);
2136 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2137 }
2138 
2139 /**
2140   * @brief  DMA IRDA receive process complete callback.
2141   * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
2142   *               the configuration information for the specified DMA.
2143   * @retval None
2144   */
IRDA_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2145 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2146 {
2147   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2148 
2149   /* DMA Normal mode */
2150   if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
2151   {
2152     hirda->RxXferCount = 0U;
2153 
2154     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2155     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2156     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2157 
2158     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2159        in the IRDA CR3 register */
2160     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2161 
2162     /* At end of Rx process, restore hirda->RxState to Ready */
2163     hirda->RxState = HAL_IRDA_STATE_READY;
2164   }
2165 
2166 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2167   /* Call registered Rx complete callback */
2168   hirda->RxCpltCallback(hirda);
2169 #else
2170   /* Call legacy weak Rx complete callback */
2171   HAL_IRDA_RxCpltCallback(hirda);
2172 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2173 }
2174 
2175 /**
2176   * @brief DMA IRDA receive process half complete callback.
2177   * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
2178   *               the configuration information for the specified DMA.
2179   * @retval None
2180   */
IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef * hdma)2181 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
2182 {
2183   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2184 
2185 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2186   /*Call registered Rx Half complete callback*/
2187   hirda->RxHalfCpltCallback(hirda);
2188 #else
2189   /* Call legacy weak Rx Half complete callback */
2190   HAL_IRDA_RxHalfCpltCallback(hirda);
2191 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2192 }
2193 
2194 /**
2195   * @brief  DMA IRDA communication error callback.
2196   * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
2197   *               the configuration information for the specified DMA.
2198   * @retval None
2199   */
IRDA_DMAError(DMA_HandleTypeDef * hdma)2200 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
2201 {
2202   uint32_t dmarequest = 0x00U;
2203   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2204 
2205   /* Stop IRDA DMA Tx request if ongoing */
2206   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
2207   if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
2208   {
2209     hirda->TxXferCount = 0U;
2210     IRDA_EndTxTransfer(hirda);
2211   }
2212 
2213   /* Stop IRDA DMA Rx request if ongoing */
2214   dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
2215   if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
2216   {
2217     hirda->RxXferCount = 0U;
2218     IRDA_EndRxTransfer(hirda);
2219   }
2220 
2221   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
2222 
2223 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2224   /* Call registered user error callback */
2225   hirda->ErrorCallback(hirda);
2226 #else
2227   /* Call legacy weak user error callback */
2228   HAL_IRDA_ErrorCallback(hirda);
2229 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2230 }
2231 
2232 /**
2233   * @brief  This function handles IRDA Communication Timeout. It waits
2234   *         until a flag is no longer in the specified status.
2235   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2236   *                the configuration information for the specified IRDA.
2237   * @param  Flag specifies the IRDA flag to check.
2238   * @param  Status The actual Flag status (SET or RESET).
2239   * @param  Tickstart Tick start value
2240   * @param  Timeout Timeout duration
2241   * @retval HAL status
2242   */
IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef * hirda,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)2243 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
2244 {
2245   /* Wait until flag is set */
2246   while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
2247   {
2248     /* Check for the Timeout */
2249     if (Timeout != HAL_MAX_DELAY)
2250     {
2251       if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
2252       {
2253         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
2254         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
2255         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2256 
2257         hirda->gState  = HAL_IRDA_STATE_READY;
2258         hirda->RxState = HAL_IRDA_STATE_READY;
2259 
2260         /* Process Unlocked */
2261         __HAL_UNLOCK(hirda);
2262 
2263         return HAL_TIMEOUT;
2264       }
2265     }
2266   }
2267   return HAL_OK;
2268 }
2269 
2270 /**
2271   * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
2272   * @param  hirda IRDA handle.
2273   * @retval None
2274   */
IRDA_EndTxTransfer(IRDA_HandleTypeDef * hirda)2275 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
2276 {
2277   /* Disable TXEIE and TCIE interrupts */
2278   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2279 
2280   /* At end of Tx process, restore hirda->gState to Ready */
2281   hirda->gState = HAL_IRDA_STATE_READY;
2282 }
2283 
2284 /**
2285   * @brief  End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
2286   * @param  hirda IRDA handle.
2287   * @retval None
2288   */
IRDA_EndRxTransfer(IRDA_HandleTypeDef * hirda)2289 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
2290 {
2291   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2292   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2293   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2294 
2295   /* At end of Rx process, restore hirda->RxState to Ready */
2296   hirda->RxState = HAL_IRDA_STATE_READY;
2297 }
2298 
2299 /**
2300   * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
2301   *         (To be called at end of DMA Abort procedure following error occurrence).
2302   * @param  hdma DMA handle.
2303   * @retval None
2304   */
IRDA_DMAAbortOnError(DMA_HandleTypeDef * hdma)2305 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2306 {
2307   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2308   hirda->RxXferCount = 0x00U;
2309   hirda->TxXferCount = 0x00U;
2310 
2311 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2312   /* Call registered user error callback */
2313   hirda->ErrorCallback(hirda);
2314 #else
2315   /* Call legacy weak user error callback */
2316   HAL_IRDA_ErrorCallback(hirda);
2317 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2318 }
2319 
2320 /**
2321   * @brief  DMA IRDA Tx communication abort callback, when initiated by user
2322   *         (To be called at end of DMA Tx Abort procedure following user abort request).
2323   * @note   When this callback is executed, User Abort complete call back is called only if no
2324   *         Abort still ongoing for Rx DMA Handle.
2325   * @param  hdma DMA handle.
2326   * @retval None
2327   */
IRDA_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2328 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2329 {
2330   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2331 
2332   hirda->hdmatx->XferAbortCallback = NULL;
2333 
2334   /* Check if an Abort process is still ongoing */
2335   if (hirda->hdmarx != NULL)
2336   {
2337     if (hirda->hdmarx->XferAbortCallback != NULL)
2338     {
2339       return;
2340     }
2341   }
2342 
2343   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2344   hirda->TxXferCount = 0x00U;
2345   hirda->RxXferCount = 0x00U;
2346 
2347   /* Reset ErrorCode */
2348   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2349 
2350   /* Restore hirda->gState and hirda->RxState to Ready */
2351   hirda->gState  = HAL_IRDA_STATE_READY;
2352   hirda->RxState = HAL_IRDA_STATE_READY;
2353 
2354   /* Call user Abort complete callback */
2355 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2356   /* Call registered Abort complete callback */
2357   hirda->AbortCpltCallback(hirda);
2358 #else
2359   /* Call legacy weak Abort complete callback */
2360   HAL_IRDA_AbortCpltCallback(hirda);
2361 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2362 }
2363 
2364 /**
2365   * @brief  DMA IRDA Rx communication abort callback, when initiated by user
2366   *         (To be called at end of DMA Rx Abort procedure following user abort request).
2367   * @note   When this callback is executed, User Abort complete call back is called only if no
2368   *         Abort still ongoing for Tx DMA Handle.
2369   * @param  hdma DMA handle.
2370   * @retval None
2371   */
IRDA_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2372 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2373 {
2374   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2375 
2376   hirda->hdmarx->XferAbortCallback = NULL;
2377 
2378   /* Check if an Abort process is still ongoing */
2379   if (hirda->hdmatx != NULL)
2380   {
2381     if (hirda->hdmatx->XferAbortCallback != NULL)
2382     {
2383       return;
2384     }
2385   }
2386 
2387   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2388   hirda->TxXferCount = 0x00U;
2389   hirda->RxXferCount = 0x00U;
2390 
2391   /* Reset ErrorCode */
2392   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2393 
2394   /* Restore hirda->gState and hirda->RxState to Ready */
2395   hirda->gState  = HAL_IRDA_STATE_READY;
2396   hirda->RxState = HAL_IRDA_STATE_READY;
2397 
2398   /* Call user Abort complete callback */
2399 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2400   /* Call registered Abort complete callback */
2401   hirda->AbortCpltCallback(hirda);
2402 #else
2403   /* Call legacy weak Abort complete callback */
2404   HAL_IRDA_AbortCpltCallback(hirda);
2405 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2406 }
2407 
2408 /**
2409   * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
2410   *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
2411   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2412   *         and leads to user Tx Abort Complete callback execution).
2413   * @param  hdma DMA handle.
2414   * @retval None
2415   */
IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2416 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2417 {
2418   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2419 
2420   hirda->TxXferCount = 0x00U;
2421 
2422   /* Restore hirda->gState to Ready */
2423   hirda->gState = HAL_IRDA_STATE_READY;
2424 
2425   /* Call user Abort complete callback */
2426 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2427   /* Call registered Abort Transmit Complete Callback */
2428   hirda->AbortTransmitCpltCallback(hirda);
2429 #else
2430   /* Call legacy weak Abort Transmit Complete Callback */
2431   HAL_IRDA_AbortTransmitCpltCallback(hirda);
2432 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2433 }
2434 
2435 /**
2436   * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
2437   *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
2438   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2439   *         and leads to user Rx Abort Complete callback execution).
2440   * @param  hdma DMA handle.
2441   * @retval None
2442   */
IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2443 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2444 {
2445   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2446 
2447   hirda->RxXferCount = 0x00U;
2448 
2449   /* Restore hirda->RxState to Ready */
2450   hirda->RxState = HAL_IRDA_STATE_READY;
2451 
2452   /* Call user Abort complete callback */
2453 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2454   /* Call registered Abort Receive Complete Callback */
2455   hirda->AbortReceiveCpltCallback(hirda);
2456 #else
2457   /* Call legacy weak Abort Receive Complete Callback */
2458   HAL_IRDA_AbortReceiveCpltCallback(hirda);
2459 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2460 }
2461 
2462 /**
2463  * @brief  Send an amount of data in non blocking mode.
2464  * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2465  *                the configuration information for the specified IRDA module.
2466  * @retval HAL status
2467  */
IRDA_Transmit_IT(IRDA_HandleTypeDef * hirda)2468 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
2469 {
2470   const uint16_t *tmp;
2471 
2472   /* Check that a Tx process is ongoing */
2473   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2474   {
2475     if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
2476     {
2477       tmp = (const uint16_t *) hirda->pTxBuffPtr;
2478       hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
2479       if (hirda->Init.Parity == IRDA_PARITY_NONE)
2480       {
2481         hirda->pTxBuffPtr += 2U;
2482       }
2483       else
2484       {
2485         hirda->pTxBuffPtr += 1U;
2486       }
2487     }
2488     else
2489     {
2490       hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
2491     }
2492 
2493     if (--hirda->TxXferCount == 0U)
2494     {
2495       /* Disable the IRDA Transmit Data Register Empty Interrupt */
2496       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
2497 
2498       /* Enable the IRDA Transmit Complete Interrupt */
2499       SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2500     }
2501 
2502     return HAL_OK;
2503   }
2504   else
2505   {
2506     return HAL_BUSY;
2507   }
2508 }
2509 
2510 /**
2511   * @brief  Wraps up transmission in non blocking mode.
2512   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2513   *                the configuration information for the specified IRDA module.
2514   * @retval HAL status
2515   */
IRDA_EndTransmit_IT(IRDA_HandleTypeDef * hirda)2516 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
2517 {
2518   /* Disable the IRDA Transmit Complete Interrupt */
2519   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2520 
2521   /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2522   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2523 
2524   /* Tx process is ended, restore hirda->gState to Ready */
2525   hirda->gState = HAL_IRDA_STATE_READY;
2526 
2527 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2528   /* Call registered Tx complete callback */
2529   hirda->TxCpltCallback(hirda);
2530 #else
2531   /* Call legacy weak Tx complete callback */
2532   HAL_IRDA_TxCpltCallback(hirda);
2533 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2534 
2535   return HAL_OK;
2536 }
2537 
2538 /**
2539   * @brief  Receives an amount of data in non blocking mode.
2540   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2541   *                the configuration information for the specified IRDA module.
2542   * @retval HAL status
2543   */
IRDA_Receive_IT(IRDA_HandleTypeDef * hirda)2544 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
2545 {
2546   uint16_t *tmp;
2547   uint16_t  uhdata;
2548 
2549   /* Check that a Rx process is ongoing */
2550   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2551   {
2552     uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
2553     if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
2554     {
2555       tmp = (uint16_t *) hirda->pRxBuffPtr;
2556       if (hirda->Init.Parity == IRDA_PARITY_NONE)
2557       {
2558         *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
2559         hirda->pRxBuffPtr += 2U;
2560       }
2561       else
2562       {
2563         *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
2564         hirda->pRxBuffPtr += 1U;
2565       }
2566     }
2567     else
2568     {
2569       if (hirda->Init.Parity == IRDA_PARITY_NONE)
2570       {
2571         *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
2572       }
2573       else
2574       {
2575         *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
2576       }
2577     }
2578 
2579     if (--hirda->RxXferCount == 0U)
2580     {
2581       /* Disable the IRDA Data Register not empty Interrupt */
2582       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
2583 
2584       /* Disable the IRDA Parity Error Interrupt */
2585       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2586 
2587       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2588       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2589 
2590       /* Rx process is completed, restore hirda->RxState to Ready */
2591       hirda->RxState = HAL_IRDA_STATE_READY;
2592 
2593 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2594       /* Call registered Rx complete callback */
2595       hirda->RxCpltCallback(hirda);
2596 #else
2597       /* Call legacy weak Rx complete callback */
2598       HAL_IRDA_RxCpltCallback(hirda);
2599 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2600 
2601       return HAL_OK;
2602     }
2603     return HAL_OK;
2604   }
2605   else
2606   {
2607     return HAL_BUSY;
2608   }
2609 }
2610 
2611 /**
2612   * @brief  Configures the IRDA peripheral.
2613   * @param  hirda  Pointer to a IRDA_HandleTypeDef structure that contains
2614   *                the configuration information for the specified IRDA module.
2615   * @retval None
2616   */
IRDA_SetConfig(IRDA_HandleTypeDef * hirda)2617 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
2618 {
2619   uint32_t pclk;
2620 
2621   /* Check the parameters */
2622   assert_param(IS_IRDA_INSTANCE(hirda->Instance));
2623   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2624   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2625   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2626   assert_param(IS_IRDA_MODE(hirda->Init.Mode));
2627   assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
2628 
2629   /*-------------------------- USART CR2 Configuration ------------------------*/
2630   /* Clear STOP[13:12] bits */
2631   CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
2632 
2633   /*-------------------------- USART CR1 Configuration -----------------------*/
2634   /* Clear M, PCE, PS, TE and RE bits */
2635   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE));
2636 
2637   /* Configure the USART Word Length, Parity and mode:
2638      Set the M bits according to hirda->Init.WordLength value
2639      Set PCE and PS bits according to hirda->Init.Parity value
2640      Set TE and RE bits according to hirda->Init.Mode value */
2641   /* Write to USART CR1 */
2642   SET_BIT(hirda->Instance->CR1, (hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode));
2643 
2644   /*-------------------------- USART CR3 Configuration -----------------------*/
2645   /* Clear CTSE and RTSE bits */
2646   CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
2647 
2648   /*-------------------------- USART BRR Configuration -----------------------*/
2649 #if defined(USART6) && defined(UART9) && defined(UART10)
2650    if ((hirda->Instance == USART1) || (hirda->Instance == USART6) || (hirda->Instance == UART9) || (hirda->Instance == UART10))
2651    {
2652     pclk = HAL_RCC_GetPCLK2Freq();
2653     SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
2654    }
2655 #elif defined(USART6)
2656   if((hirda->Instance == USART1) || (hirda->Instance == USART6))
2657   {
2658     pclk = HAL_RCC_GetPCLK2Freq();
2659     SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
2660   }
2661 #else
2662   if(hirda->Instance == USART1)
2663   {
2664     pclk = HAL_RCC_GetPCLK2Freq();
2665     SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
2666   }
2667 #endif /* USART6 */
2668   else
2669   {
2670     pclk = HAL_RCC_GetPCLK1Freq();
2671     SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
2672   }
2673 }
2674 
2675 /**
2676   * @}
2677   */
2678 
2679 #endif /* HAL_IRDA_MODULE_ENABLED */
2680 /**
2681   * @}
2682   */
2683 
2684 /**
2685   * @}
2686   */
2687 
2688