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