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