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