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