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