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