1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_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) 2021 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 "stm32u5xx_hal.h"
190 
191 /** @addtogroup STM32U5xx_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   uint32_t pclk;
2355 
2356   /* Check the communication parameters */
2357   assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2358   assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2359   assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2360   assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
2361   assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
2362   assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
2363   assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler));
2364 
2365   /*-------------------------- USART CR1 Configuration -----------------------*/
2366   /* Configure the IRDA Word Length, Parity and transfer Mode:
2367      Set the M bits according to hirda->Init.WordLength value
2368      Set PCE and PS bits according to hirda->Init.Parity value
2369      Set TE and RE bits according to hirda->Init.Mode value */
2370   tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
2371 
2372   MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
2373 
2374   /*-------------------------- USART CR3 Configuration -----------------------*/
2375   MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
2376 
2377   /*--------------------- USART clock PRESC Configuration ----------------*/
2378   /* Configure
2379   * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */
2380   MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler);
2381 
2382   /*-------------------------- USART GTPR Configuration ----------------------*/
2383   MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler);
2384 
2385   /*-------------------------- USART BRR Configuration -----------------------*/
2386   IRDA_GETCLOCKSOURCE(hirda, clocksource);
2387   tmpreg =   0U;
2388   switch (clocksource)
2389   {
2390     case IRDA_CLOCKSOURCE_PCLK1:
2391       pclk = HAL_RCC_GetPCLK1Freq();
2392       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2393       break;
2394     case IRDA_CLOCKSOURCE_PCLK2:
2395       pclk = HAL_RCC_GetPCLK2Freq();
2396       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2397       break;
2398     case IRDA_CLOCKSOURCE_HSI:
2399       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2400       break;
2401     case IRDA_CLOCKSOURCE_SYSCLK:
2402       pclk = HAL_RCC_GetSysClockFreq();
2403       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2404       break;
2405     case IRDA_CLOCKSOURCE_LSE:
2406       tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2407       break;
2408     default:
2409       ret = HAL_ERROR;
2410       break;
2411   }
2412 
2413   /* USARTDIV must be greater than or equal to 0d16 */
2414   if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX))
2415   {
2416     hirda->Instance->BRR = (uint16_t)tmpreg;
2417   }
2418   else
2419   {
2420     ret = HAL_ERROR;
2421   }
2422 
2423   return ret;
2424 }
2425 
2426 /**
2427   * @brief Check the IRDA Idle State.
2428   * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2429   *               the configuration information for the specified IRDA module.
2430   * @retval HAL status
2431   */
IRDA_CheckIdleState(IRDA_HandleTypeDef * hirda)2432 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
2433 {
2434   uint32_t tickstart;
2435 
2436   /* Initialize the IRDA ErrorCode */
2437   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2438 
2439   /* Init tickstart for timeout management */
2440   tickstart = HAL_GetTick();
2441 
2442   /* Check if the Transmitter is enabled */
2443   if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2444   {
2445     /* Wait until TEACK flag is set */
2446     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2447     {
2448       /* Timeout occurred */
2449       return HAL_TIMEOUT;
2450     }
2451   }
2452   /* Check if the Receiver is enabled */
2453   if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2454   {
2455     /* Wait until REACK flag is set */
2456     if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2457     {
2458       /* Timeout occurred */
2459       return HAL_TIMEOUT;
2460     }
2461   }
2462 
2463   /* Initialize the IRDA state*/
2464   hirda->gState  = HAL_IRDA_STATE_READY;
2465   hirda->RxState = HAL_IRDA_STATE_READY;
2466 
2467   /* Process Unlocked */
2468   __HAL_UNLOCK(hirda);
2469 
2470   return HAL_OK;
2471 }
2472 
2473 /**
2474   * @brief  Handle IRDA Communication Timeout. It waits
2475   *         until a flag is no longer in the specified status.
2476   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2477   *               the configuration information for the specified IRDA module.
2478   * @param  Flag Specifies the IRDA flag to check.
2479   * @param  Status The actual Flag status (SET or RESET)
2480   * @param  Tickstart Tick start value
2481   * @param  Timeout Timeout duration
2482   * @retval HAL status
2483   */
IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef * hirda,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)2484 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
2485                                                      uint32_t Tickstart, uint32_t Timeout)
2486 {
2487   /* Wait until flag is set */
2488   while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
2489   {
2490     /* Check for the Timeout */
2491     if (Timeout != HAL_MAX_DELAY)
2492     {
2493       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2494       {
2495         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
2496            interrupts for the interrupt process */
2497         CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
2498         CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2499 
2500         hirda->gState  = HAL_IRDA_STATE_READY;
2501         hirda->RxState = HAL_IRDA_STATE_READY;
2502 
2503         /* Process Unlocked */
2504         __HAL_UNLOCK(hirda);
2505         return HAL_TIMEOUT;
2506       }
2507     }
2508   }
2509   return HAL_OK;
2510 }
2511 
2512 
2513 #if defined(HAL_DMA_MODULE_ENABLED)
2514 /**
2515   * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
2516   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2517   *               the configuration information for the specified IRDA module.
2518   * @retval None
2519   */
IRDA_EndTxTransfer(IRDA_HandleTypeDef * hirda)2520 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
2521 {
2522   /* Disable TXEIE and TCIE interrupts */
2523   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
2524 
2525   /* At end of Tx process, restore hirda->gState to Ready */
2526   hirda->gState = HAL_IRDA_STATE_READY;
2527 }
2528 #endif /* HAL_DMA_MODULE_ENABLED */
2529 
2530 /**
2531   * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
2532   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2533   *               the configuration information for the specified IRDA module.
2534   * @retval None
2535   */
IRDA_EndRxTransfer(IRDA_HandleTypeDef * hirda)2536 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
2537 {
2538   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2539   CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2540   CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2541 
2542   /* At end of Rx process, restore hirda->RxState to Ready */
2543   hirda->RxState = HAL_IRDA_STATE_READY;
2544 }
2545 
2546 
2547 #if defined(HAL_DMA_MODULE_ENABLED)
2548 /**
2549   * @brief  DMA IRDA transmit process complete callback.
2550   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2551   *              the configuration information for the specified DMA module.
2552   * @retval None
2553   */
IRDA_DMATransmitCplt(DMA_HandleTypeDef * hdma)2554 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2555 {
2556   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2557 
2558   /* DMA Normal mode */
2559   if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2560   {
2561     hirda->TxXferCount = 0U;
2562 
2563     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2564        in the IRDA CR3 register */
2565     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
2566 
2567     /* Enable the IRDA Transmit Complete Interrupt */
2568     SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2569   }
2570   /* DMA Circular mode */
2571   else
2572   {
2573 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2574     /* Call registered Tx complete callback */
2575     hirda->TxCpltCallback(hirda);
2576 #else
2577     /* Call legacy weak Tx complete callback */
2578     HAL_IRDA_TxCpltCallback(hirda);
2579 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2580   }
2581 
2582 }
2583 
2584 /**
2585   * @brief  DMA IRDA transmit process half complete callback.
2586   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2587   *              the configuration information for the specified DMA module.
2588   * @retval None
2589   */
IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef * hdma)2590 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
2591 {
2592   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2593 
2594 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2595   /* Call registered Tx Half complete callback */
2596   hirda->TxHalfCpltCallback(hirda);
2597 #else
2598   /* Call legacy weak Tx complete callback */
2599   HAL_IRDA_TxHalfCpltCallback(hirda);
2600 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2601 }
2602 
2603 /**
2604   * @brief  DMA IRDA receive process complete callback.
2605   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2606   *               the configuration information for the specified DMA module.
2607   * @retval None
2608   */
IRDA_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2609 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2610 {
2611   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2612 
2613   /* DMA Normal mode */
2614   if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2615   {
2616     hirda->RxXferCount = 0U;
2617 
2618     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2619     CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2620     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2621 
2622     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2623        in the IRDA CR3 register */
2624     CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2625 
2626     /* At end of Rx process, restore hirda->RxState to Ready */
2627     hirda->RxState = HAL_IRDA_STATE_READY;
2628   }
2629 
2630 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2631   /* Call registered Rx complete callback */
2632   hirda->RxCpltCallback(hirda);
2633 #else
2634   /* Call legacy weak Rx complete callback */
2635   HAL_IRDA_RxCpltCallback(hirda);
2636 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2637 }
2638 
2639 /**
2640   * @brief DMA IRDA receive process half complete callback.
2641   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2642   *              the configuration information for the specified DMA module.
2643   * @retval None
2644   */
IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef * hdma)2645 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
2646 {
2647   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2648 
2649 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2650   /*Call registered Rx Half complete callback*/
2651   hirda->RxHalfCpltCallback(hirda);
2652 #else
2653   /* Call legacy weak Rx Half complete callback */
2654   HAL_IRDA_RxHalfCpltCallback(hirda);
2655 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2656 }
2657 
2658 /**
2659   * @brief DMA IRDA communication error callback.
2660   * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2661   *              the configuration information for the specified DMA module.
2662   * @retval None
2663   */
IRDA_DMAError(DMA_HandleTypeDef * hdma)2664 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
2665 {
2666   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2667 
2668   /* Stop IRDA DMA Tx request if ongoing */
2669   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2670   {
2671     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
2672     {
2673       hirda->TxXferCount = 0U;
2674       IRDA_EndTxTransfer(hirda);
2675     }
2676   }
2677 
2678   /* Stop IRDA DMA Rx request if ongoing */
2679   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2680   {
2681     if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2682     {
2683       hirda->RxXferCount = 0U;
2684       IRDA_EndRxTransfer(hirda);
2685     }
2686   }
2687 
2688   hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
2689 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2690   /* Call registered user error callback */
2691   hirda->ErrorCallback(hirda);
2692 #else
2693   /* Call legacy weak user error callback */
2694   HAL_IRDA_ErrorCallback(hirda);
2695 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2696 }
2697 
2698 /**
2699   * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
2700   *         (To be called at end of DMA Abort procedure following error occurrence).
2701   * @param  hdma DMA handle.
2702   * @retval None
2703   */
IRDA_DMAAbortOnError(DMA_HandleTypeDef * hdma)2704 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2705 {
2706   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2707   hirda->RxXferCount = 0U;
2708   hirda->TxXferCount = 0U;
2709 
2710 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2711   /* Call registered user error callback */
2712   hirda->ErrorCallback(hirda);
2713 #else
2714   /* Call legacy weak user error callback */
2715   HAL_IRDA_ErrorCallback(hirda);
2716 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2717 }
2718 
2719 /**
2720   * @brief  DMA IRDA Tx communication abort callback, when initiated by user
2721   *         (To be called at end of DMA Tx Abort procedure following user abort request).
2722   * @note   When this callback is executed, User Abort complete call back is called only if no
2723   *         Abort still ongoing for Rx DMA Handle.
2724   * @param  hdma DMA handle.
2725   * @retval None
2726   */
IRDA_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2727 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2728 {
2729   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2730 
2731   hirda->hdmatx->XferAbortCallback = NULL;
2732 
2733   /* Check if an Abort process is still ongoing */
2734   if (hirda->hdmarx != NULL)
2735   {
2736     if (hirda->hdmarx->XferAbortCallback != NULL)
2737     {
2738       return;
2739     }
2740   }
2741 
2742   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2743   hirda->TxXferCount = 0U;
2744   hirda->RxXferCount = 0U;
2745 
2746   /* Reset errorCode */
2747   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2748 
2749   /* Clear the Error flags in the ICR register */
2750   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2751 
2752   /* Restore hirda->gState and hirda->RxState to Ready */
2753   hirda->gState  = HAL_IRDA_STATE_READY;
2754   hirda->RxState = HAL_IRDA_STATE_READY;
2755 
2756   /* Call user Abort complete callback */
2757 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2758   /* Call registered Abort complete callback */
2759   hirda->AbortCpltCallback(hirda);
2760 #else
2761   /* Call legacy weak Abort complete callback */
2762   HAL_IRDA_AbortCpltCallback(hirda);
2763 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2764 }
2765 
2766 
2767 /**
2768   * @brief  DMA IRDA Rx communication abort callback, when initiated by user
2769   *         (To be called at end of DMA Rx Abort procedure following user abort request).
2770   * @note   When this callback is executed, User Abort complete call back is called only if no
2771   *         Abort still ongoing for Tx DMA Handle.
2772   * @param  hdma DMA handle.
2773   * @retval None
2774   */
IRDA_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2775 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2776 {
2777   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2778 
2779   hirda->hdmarx->XferAbortCallback = NULL;
2780 
2781   /* Check if an Abort process is still ongoing */
2782   if (hirda->hdmatx != NULL)
2783   {
2784     if (hirda->hdmatx->XferAbortCallback != NULL)
2785     {
2786       return;
2787     }
2788   }
2789 
2790   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2791   hirda->TxXferCount = 0U;
2792   hirda->RxXferCount = 0U;
2793 
2794   /* Reset errorCode */
2795   hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2796 
2797   /* Clear the Error flags in the ICR register */
2798   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2799 
2800   /* Restore hirda->gState and hirda->RxState to Ready */
2801   hirda->gState  = HAL_IRDA_STATE_READY;
2802   hirda->RxState = HAL_IRDA_STATE_READY;
2803 
2804   /* Call user Abort complete callback */
2805 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2806   /* Call registered Abort complete callback */
2807   hirda->AbortCpltCallback(hirda);
2808 #else
2809   /* Call legacy weak Abort complete callback */
2810   HAL_IRDA_AbortCpltCallback(hirda);
2811 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2812 }
2813 
2814 
2815 /**
2816   * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
2817   *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
2818   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2819   *         and leads to user Tx Abort Complete callback execution).
2820   * @param  hdma DMA handle.
2821   * @retval None
2822   */
IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2823 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2824 {
2825   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2826 
2827   hirda->TxXferCount = 0U;
2828 
2829   /* Restore hirda->gState to Ready */
2830   hirda->gState = HAL_IRDA_STATE_READY;
2831 
2832   /* Call user Abort complete callback */
2833 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2834   /* Call registered Abort Transmit Complete Callback */
2835   hirda->AbortTransmitCpltCallback(hirda);
2836 #else
2837   /* Call legacy weak Abort Transmit Complete Callback */
2838   HAL_IRDA_AbortTransmitCpltCallback(hirda);
2839 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2840 }
2841 
2842 /**
2843   * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
2844   *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
2845   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2846   *         and leads to user Rx Abort Complete callback execution).
2847   * @param  hdma DMA handle.
2848   * @retval None
2849   */
IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2850 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2851 {
2852   IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2853 
2854   hirda->RxXferCount = 0U;
2855 
2856   /* Clear the Error flags in the ICR register */
2857   __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2858 
2859   /* Restore hirda->RxState to Ready */
2860   hirda->RxState = HAL_IRDA_STATE_READY;
2861 
2862   /* Call user Abort complete callback */
2863 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2864   /* Call registered Abort Receive Complete Callback */
2865   hirda->AbortReceiveCpltCallback(hirda);
2866 #else
2867   /* Call legacy weak Abort Receive Complete Callback */
2868   HAL_IRDA_AbortReceiveCpltCallback(hirda);
2869 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2870 }
2871 #endif /* HAL_DMA_MODULE_ENABLED */
2872 
2873 /**
2874   * @brief  Send an amount of data in interrupt mode.
2875   * @note   Function is called under interruption only, once
2876   *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
2877   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2878   *               the configuration information for the specified IRDA module.
2879   * @retval None
2880   */
IRDA_Transmit_IT(IRDA_HandleTypeDef * hirda)2881 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
2882 {
2883   const uint16_t *tmp;
2884 
2885   /* Check that a Tx process is ongoing */
2886   if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2887   {
2888     if (hirda->TxXferCount == 0U)
2889     {
2890       /* Disable the IRDA Transmit Data Register Empty Interrupt */
2891       CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
2892 
2893       /* Enable the IRDA Transmit Complete Interrupt */
2894       SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2895     }
2896     else
2897     {
2898       if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2899       {
2900         tmp = (const uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */
2901         hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
2902         hirda->pTxBuffPtr += 2U;
2903       }
2904       else
2905       {
2906         hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU);
2907         hirda->pTxBuffPtr++;
2908       }
2909       hirda->TxXferCount--;
2910     }
2911   }
2912 }
2913 
2914 /**
2915   * @brief  Wrap up transmission in non-blocking mode.
2916   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2917   *               the configuration information for the specified IRDA module.
2918   * @retval None
2919   */
IRDA_EndTransmit_IT(IRDA_HandleTypeDef * hirda)2920 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
2921 {
2922   /* Disable the IRDA Transmit Complete Interrupt */
2923   CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2924 
2925   /* Tx process is ended, restore hirda->gState to Ready */
2926   hirda->gState = HAL_IRDA_STATE_READY;
2927 
2928 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2929   /* Call registered Tx complete callback */
2930   hirda->TxCpltCallback(hirda);
2931 #else
2932   /* Call legacy weak Tx complete callback */
2933   HAL_IRDA_TxCpltCallback(hirda);
2934 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2935 }
2936 
2937 /**
2938   * @brief  Receive an amount of data in interrupt mode.
2939   * @note   Function is called under interruption only, once
2940   *         interruptions have been enabled by HAL_IRDA_Receive_IT()
2941   * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2942   *               the configuration information for the specified IRDA module.
2943   * @retval None
2944   */
IRDA_Receive_IT(IRDA_HandleTypeDef * hirda)2945 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
2946 {
2947   uint16_t *tmp;
2948   uint16_t  uhMask = hirda->Mask;
2949   uint16_t  uhdata;
2950 
2951   /* Check that a Rx process is ongoing */
2952   if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2953   {
2954     uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
2955     if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2956     {
2957       tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */
2958       *tmp = (uint16_t)(uhdata & uhMask);
2959       hirda->pRxBuffPtr  += 2U;
2960     }
2961     else
2962     {
2963       *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
2964       hirda->pRxBuffPtr++;
2965     }
2966 
2967     hirda->RxXferCount--;
2968     if (hirda->RxXferCount == 0U)
2969     {
2970       /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */
2971       CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2972 
2973       /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2974       CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2975 
2976       /* Rx process is completed, restore hirda->RxState to Ready */
2977       hirda->RxState = HAL_IRDA_STATE_READY;
2978 
2979 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2980       /* Call registered Rx complete callback */
2981       hirda->RxCpltCallback(hirda);
2982 #else
2983       /* Call legacy weak Rx complete callback */
2984       HAL_IRDA_RxCpltCallback(hirda);
2985 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2986     }
2987   }
2988   else
2989   {
2990     /* Clear RXNE interrupt flag */
2991     __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
2992   }
2993 }
2994 
2995 /**
2996   * @}
2997   */
2998 
2999 #endif /* HAL_IRDA_MODULE_ENABLED */
3000 /**
3001   * @}
3002   */
3003 
3004 /**
3005   * @}
3006   */
3007 
3008