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