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