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