source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_irda.c

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