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