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