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