source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_irda.c

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