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