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