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