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