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