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