1 /**
2 ******************************************************************************
3 * @file stm32h5xx_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) 2023 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 "stm32h5xx_hal.h"
190
191 /** @addtogroup STM32H5xx_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 */
HAL_IRDA_Transmit(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size,uint32_t Timeout)801 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
802 {
803 const uint8_t *pdata8bits;
804 const uint16_t *pdata16bits;
805 uint32_t tickstart;
806
807 /* Check that a Tx process is not already ongoing */
808 if (hirda->gState == HAL_IRDA_STATE_READY)
809 {
810 if ((pData == NULL) || (Size == 0U))
811 {
812 return HAL_ERROR;
813 }
814
815 /* Process Locked */
816 __HAL_LOCK(hirda);
817
818 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
819 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
820
821 /* Init tickstart for timeout management */
822 tickstart = HAL_GetTick();
823
824 hirda->TxXferSize = Size;
825 hirda->TxXferCount = Size;
826
827 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
828 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
829 {
830 pdata8bits = NULL;
831 pdata16bits = (const uint16_t *) pData; /* Derogation R.11.3 */
832 }
833 else
834 {
835 pdata8bits = pData;
836 pdata16bits = NULL;
837 }
838
839 while (hirda->TxXferCount > 0U)
840 {
841 hirda->TxXferCount--;
842
843 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
844 {
845 return HAL_TIMEOUT;
846 }
847 if (pdata8bits == NULL)
848 {
849 hirda->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
850 pdata16bits++;
851 }
852 else
853 {
854 hirda->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
855 pdata8bits++;
856 }
857 }
858
859 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
860 {
861 return HAL_TIMEOUT;
862 }
863
864 /* At end of Tx process, restore hirda->gState to Ready */
865 hirda->gState = HAL_IRDA_STATE_READY;
866
867 /* Process Unlocked */
868 __HAL_UNLOCK(hirda);
869
870 return HAL_OK;
871 }
872 else
873 {
874 return HAL_BUSY;
875 }
876 }
877
878 /**
879 * @brief Receive an amount of data in blocking mode.
880 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
881 * the received data is handled as a set of u16. In this case, Size must reflect the number
882 * of u16 available through pData.
883 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
884 * the configuration information for the specified IRDA module.
885 * @param pData Pointer to data buffer (u8 or u16 data elements).
886 * @param Size Amount of data elements (u8 or u16) to be received.
887 * @param Timeout Specify timeout value.
888 * @retval HAL status
889 */
HAL_IRDA_Receive(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size,uint32_t Timeout)890 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
891 {
892 uint8_t *pdata8bits;
893 uint16_t *pdata16bits;
894 uint16_t uhMask;
895 uint32_t tickstart;
896
897 /* Check that a Rx process is not already ongoing */
898 if (hirda->RxState == HAL_IRDA_STATE_READY)
899 {
900 if ((pData == NULL) || (Size == 0U))
901 {
902 return HAL_ERROR;
903 }
904
905 /* Process Locked */
906 __HAL_LOCK(hirda);
907
908 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
909 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
910
911 /* Init tickstart for timeout management */
912 tickstart = HAL_GetTick();
913
914 hirda->RxXferSize = Size;
915 hirda->RxXferCount = Size;
916
917 /* Computation of the mask to apply to RDR register
918 of the UART associated to the IRDA */
919 IRDA_MASK_COMPUTATION(hirda);
920 uhMask = hirda->Mask;
921
922 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
923 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
924 {
925 pdata8bits = NULL;
926 pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */
927 }
928 else
929 {
930 pdata8bits = pData;
931 pdata16bits = NULL;
932 }
933
934 /* Check data remaining to be received */
935 while (hirda->RxXferCount > 0U)
936 {
937 hirda->RxXferCount--;
938
939 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
940 {
941 return HAL_TIMEOUT;
942 }
943 if (pdata8bits == NULL)
944 {
945 *pdata16bits = (uint16_t)(hirda->Instance->RDR & uhMask);
946 pdata16bits++;
947 }
948 else
949 {
950 *pdata8bits = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
951 pdata8bits++;
952 }
953 }
954
955 /* At end of Rx process, restore hirda->RxState to Ready */
956 hirda->RxState = HAL_IRDA_STATE_READY;
957
958 /* Process Unlocked */
959 __HAL_UNLOCK(hirda);
960
961 return HAL_OK;
962 }
963 else
964 {
965 return HAL_BUSY;
966 }
967 }
968
969 /**
970 * @brief Send an amount of data in interrupt mode.
971 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
972 * the sent data is handled as a set of u16. In this case, Size must reflect the number
973 * of u16 available through pData.
974 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
975 * the configuration information for the specified IRDA module.
976 * @param pData Pointer to data buffer (u8 or u16 data elements).
977 * @param Size Amount of data elements (u8 or u16) to be sent.
978 * @retval HAL status
979 */
HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size)980 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
981 {
982 /* Check that a Tx process is not already ongoing */
983 if (hirda->gState == HAL_IRDA_STATE_READY)
984 {
985 if ((pData == NULL) || (Size == 0U))
986 {
987 return HAL_ERROR;
988 }
989
990 /* Process Locked */
991 __HAL_LOCK(hirda);
992
993 hirda->pTxBuffPtr = pData;
994 hirda->TxXferSize = Size;
995 hirda->TxXferCount = Size;
996
997 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
998 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
999
1000 /* Process Unlocked */
1001 __HAL_UNLOCK(hirda);
1002
1003 /* Enable the IRDA Transmit Data Register Empty Interrupt */
1004 SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1005
1006 return HAL_OK;
1007 }
1008 else
1009 {
1010 return HAL_BUSY;
1011 }
1012 }
1013
1014 /**
1015 * @brief Receive an amount of data in interrupt mode.
1016 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1017 * the received data is handled as a set of u16. In this case, Size must reflect the number
1018 * of u16 available through pData.
1019 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1020 * the configuration information for the specified IRDA module.
1021 * @param pData Pointer to data buffer (u8 or u16 data elements).
1022 * @param Size Amount of data elements (u8 or u16) to be received.
1023 * @retval HAL status
1024 */
HAL_IRDA_Receive_IT(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size)1025 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1026 {
1027 /* Check that a Rx process is not already ongoing */
1028 if (hirda->RxState == HAL_IRDA_STATE_READY)
1029 {
1030 if ((pData == NULL) || (Size == 0U))
1031 {
1032 return HAL_ERROR;
1033 }
1034
1035 /* Process Locked */
1036 __HAL_LOCK(hirda);
1037
1038 hirda->pRxBuffPtr = pData;
1039 hirda->RxXferSize = Size;
1040 hirda->RxXferCount = Size;
1041
1042 /* Computation of the mask to apply to the RDR register
1043 of the UART associated to the IRDA */
1044 IRDA_MASK_COMPUTATION(hirda);
1045
1046 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1047 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1048
1049 /* Process Unlocked */
1050 __HAL_UNLOCK(hirda);
1051
1052 if (hirda->Init.Parity != IRDA_PARITY_NONE)
1053 {
1054 /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
1055 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1056 }
1057 else
1058 {
1059 /* Enable the IRDA Data Register not empty Interrupts */
1060 SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1061 }
1062
1063 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1064 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1065
1066 return HAL_OK;
1067 }
1068 else
1069 {
1070 return HAL_BUSY;
1071 }
1072 }
1073
1074 #if defined(HAL_DMA_MODULE_ENABLED)
1075 /**
1076 * @brief Send an amount of data in DMA mode.
1077 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1078 * the sent data is handled as a set of u16. In this case, Size must reflect the number
1079 * of u16 available through pData.
1080 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1081 * the configuration information for the specified IRDA module.
1082 * @param pData pointer to data buffer (u8 or u16 data elements).
1083 * @param Size Amount of data elements (u8 or u16) to be sent.
1084 * @retval HAL status
1085 */
HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef * hirda,const uint8_t * pData,uint16_t Size)1086 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size)
1087 {
1088 HAL_StatusTypeDef status;
1089 uint16_t nbByte = Size;
1090
1091 /* Check that a Tx process is not already ongoing */
1092 if (hirda->gState == HAL_IRDA_STATE_READY)
1093 {
1094 if ((pData == NULL) || (Size == 0U))
1095 {
1096 return HAL_ERROR;
1097 }
1098
1099 /* Process Locked */
1100 __HAL_LOCK(hirda);
1101
1102 hirda->pTxBuffPtr = pData;
1103 hirda->TxXferSize = Size;
1104 hirda->TxXferCount = Size;
1105
1106 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1107 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1108
1109 /* Set the IRDA DMA transfer complete callback */
1110 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
1111
1112 /* Set the IRDA DMA half transfer complete callback */
1113 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
1114
1115 /* Set the DMA error callback */
1116 hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
1117
1118 /* Set the DMA abort callback */
1119 hirda->hdmatx->XferAbortCallback = NULL;
1120
1121 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1122 should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */
1123 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1124 {
1125 nbByte = Size * 2U;
1126 }
1127
1128 /* Check linked list mode */
1129 if ((hirda->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1130 {
1131 if ((hirda->hdmatx->LinkedListQueue != NULL) && (hirda->hdmatx->LinkedListQueue->Head != NULL))
1132 {
1133 /* Set DMA data size */
1134 hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1135
1136 /* Set DMA source address */
1137 hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1138 (uint32_t)hirda->pTxBuffPtr;
1139
1140 /* Set DMA destination address */
1141 hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1142 (uint32_t)&hirda->Instance->TDR;
1143
1144 /* Enable the IRDA transmit DMA channel */
1145 status = HAL_DMAEx_List_Start_IT(hirda->hdmatx);
1146 }
1147 else
1148 {
1149 /* Update status */
1150 status = HAL_ERROR;
1151 }
1152 }
1153 else
1154 {
1155 /* Enable the IRDA transmit DMA channel */
1156 status = HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, nbByte);
1157 }
1158
1159 if (status == HAL_OK)
1160 {
1161 /* Clear the TC flag in the ICR register */
1162 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
1163
1164 /* Process Unlocked */
1165 __HAL_UNLOCK(hirda);
1166
1167 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1168 in the USART CR3 register */
1169 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1170
1171 return HAL_OK;
1172 }
1173 else
1174 {
1175 /* Set error code to DMA */
1176 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1177
1178 /* Process Unlocked */
1179 __HAL_UNLOCK(hirda);
1180
1181 /* Restore hirda->gState to ready */
1182 hirda->gState = HAL_IRDA_STATE_READY;
1183
1184 return HAL_ERROR;
1185 }
1186 }
1187 else
1188 {
1189 return HAL_BUSY;
1190 }
1191 }
1192
1193 /**
1194 * @brief Receive an amount of data in DMA mode.
1195 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1196 * the received data is handled as a set of u16. In this case, Size must reflect the number
1197 * of u16 available through pData.
1198 * @note When the IRDA parity is enabled (PCE = 1), the received data contains
1199 * the parity bit (MSB position).
1200 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1201 * the configuration information for the specified IRDA module.
1202 * @param pData Pointer to data buffer (u8 or u16 data elements).
1203 * @param Size Amount of data elements (u8 or u16) to be received.
1204 * @retval HAL status
1205 */
HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef * hirda,uint8_t * pData,uint16_t Size)1206 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1207 {
1208 HAL_StatusTypeDef status;
1209 uint16_t nbByte = Size;
1210
1211 /* Check that a Rx process is not already ongoing */
1212 if (hirda->RxState == HAL_IRDA_STATE_READY)
1213 {
1214 if ((pData == NULL) || (Size == 0U))
1215 {
1216 return HAL_ERROR;
1217 }
1218
1219 /* Process Locked */
1220 __HAL_LOCK(hirda);
1221
1222 hirda->pRxBuffPtr = pData;
1223 hirda->RxXferSize = Size;
1224
1225 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1226 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1227
1228 /* Set the IRDA DMA transfer complete callback */
1229 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
1230
1231 /* Set the IRDA DMA half transfer complete callback */
1232 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
1233
1234 /* Set the DMA error callback */
1235 hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
1236
1237 /* Set the DMA abort callback */
1238 hirda->hdmarx->XferAbortCallback = NULL;
1239
1240 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1241 should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */
1242 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1243 {
1244 nbByte = Size * 2U;
1245 }
1246
1247 /* Check linked list mode */
1248 if ((hirda->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1249 {
1250 if ((hirda->hdmarx->LinkedListQueue != NULL) && (hirda->hdmarx->LinkedListQueue->Head != NULL))
1251 {
1252 /* Set DMA data size */
1253 hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1254
1255 /* Set DMA source address */
1256 hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1257 (uint32_t)&hirda->Instance->RDR;
1258
1259 /* Set DMA destination address */
1260 hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hirda->pRxBuffPtr;
1261
1262 /* Enable the DMA channel */
1263 status = HAL_DMAEx_List_Start_IT(hirda->hdmarx);
1264 }
1265 else
1266 {
1267 /* Update status */
1268 status = HAL_ERROR;
1269 }
1270 }
1271 else
1272 {
1273 /* Enable the DMA channel */
1274 status = HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, nbByte);
1275 }
1276
1277 if (status == HAL_OK)
1278 {
1279 /* Process Unlocked */
1280 __HAL_UNLOCK(hirda);
1281
1282 if (hirda->Init.Parity != IRDA_PARITY_NONE)
1283 {
1284 /* Enable the UART Parity Error Interrupt */
1285 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1286 }
1287
1288 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1289 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1290
1291 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1292 in the USART CR3 register */
1293 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1294
1295 return HAL_OK;
1296 }
1297 else
1298 {
1299 /* Set error code to DMA */
1300 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1301
1302 /* Process Unlocked */
1303 __HAL_UNLOCK(hirda);
1304
1305 /* Restore hirda->RxState to ready */
1306 hirda->RxState = HAL_IRDA_STATE_READY;
1307
1308 return HAL_ERROR;
1309 }
1310 }
1311 else
1312 {
1313 return HAL_BUSY;
1314 }
1315 }
1316
1317
1318 /**
1319 * @brief Pause the DMA Transfer.
1320 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1321 * the configuration information for the specified IRDA module.
1322 * @retval HAL status
1323 */
HAL_IRDA_DMAPause(IRDA_HandleTypeDef * hirda)1324 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
1325 {
1326 /* Process Locked */
1327 __HAL_LOCK(hirda);
1328
1329 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1330 {
1331 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1332 {
1333 /* Disable the IRDA DMA Tx request */
1334 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1335 }
1336 }
1337 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1338 {
1339 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1340 {
1341 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1342 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1343 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1344
1345 /* Disable the IRDA DMA Rx request */
1346 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1347 }
1348 }
1349
1350 /* Process Unlocked */
1351 __HAL_UNLOCK(hirda);
1352
1353 return HAL_OK;
1354 }
1355
1356 /**
1357 * @brief Resume the DMA Transfer.
1358 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1359 * the configuration information for the specified UART module.
1360 * @retval HAL status
1361 */
HAL_IRDA_DMAResume(IRDA_HandleTypeDef * hirda)1362 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
1363 {
1364 /* Process Locked */
1365 __HAL_LOCK(hirda);
1366
1367 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1368 {
1369 /* Enable the IRDA DMA Tx request */
1370 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1371 }
1372 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1373 {
1374 /* Clear the Overrun flag before resuming the Rx transfer*/
1375 __HAL_IRDA_CLEAR_OREFLAG(hirda);
1376
1377 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1378 if (hirda->Init.Parity != IRDA_PARITY_NONE)
1379 {
1380 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1381 }
1382 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1383
1384 /* Enable the IRDA DMA Rx request */
1385 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1386 }
1387
1388 /* Process Unlocked */
1389 __HAL_UNLOCK(hirda);
1390
1391 return HAL_OK;
1392 }
1393
1394 /**
1395 * @brief Stop the DMA Transfer.
1396 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1397 * the configuration information for the specified UART module.
1398 * @retval HAL status
1399 */
HAL_IRDA_DMAStop(IRDA_HandleTypeDef * hirda)1400 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
1401 {
1402 /* The Lock is not implemented on this API to allow the user application
1403 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
1404 HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback:
1405 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1406 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1407 the stream and the corresponding call back is executed. */
1408
1409 /* Stop IRDA DMA Tx request if ongoing */
1410 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1411 {
1412 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1413 {
1414 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1415
1416 /* Abort the IRDA DMA Tx channel */
1417 if (hirda->hdmatx != NULL)
1418 {
1419 if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1420 {
1421 if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1422 {
1423 /* Set error code to DMA */
1424 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1425
1426 return HAL_TIMEOUT;
1427 }
1428 }
1429 }
1430
1431 IRDA_EndTxTransfer(hirda);
1432 }
1433 }
1434
1435 /* Stop IRDA DMA Rx request if ongoing */
1436 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1437 {
1438 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1439 {
1440 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1441
1442 /* Abort the IRDA DMA Rx channel */
1443 if (hirda->hdmarx != NULL)
1444 {
1445 if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1446 {
1447 if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1448 {
1449 /* Set error code to DMA */
1450 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1451
1452 return HAL_TIMEOUT;
1453 }
1454 }
1455 }
1456
1457 IRDA_EndRxTransfer(hirda);
1458 }
1459 }
1460
1461 return HAL_OK;
1462 }
1463 #endif /* HAL_DMA_MODULE_ENABLED */
1464
1465 /**
1466 * @brief Abort ongoing transfers (blocking mode).
1467 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1468 * the configuration information for the specified UART module.
1469 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1470 * This procedure performs following operations :
1471 * - Disable IRDA Interrupts (Tx and Rx)
1472 * - Disable the DMA transfer in the peripheral register (if enabled)
1473 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1474 * - Set handle State to READY
1475 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1476 * @retval HAL status
1477 */
HAL_IRDA_Abort(IRDA_HandleTypeDef * hirda)1478 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
1479 {
1480 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1481 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
1482 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1483 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1484
1485 #if defined(HAL_DMA_MODULE_ENABLED)
1486 /* Disable the IRDA DMA Tx request if enabled */
1487 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1488 {
1489 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1490
1491 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1492 if (hirda->hdmatx != NULL)
1493 {
1494 /* Set the IRDA DMA Abort callback to Null.
1495 No call back execution at end of DMA abort procedure */
1496 hirda->hdmatx->XferAbortCallback = NULL;
1497
1498 if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1499 {
1500 if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1501 {
1502 /* Set error code to DMA */
1503 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1504
1505 return HAL_TIMEOUT;
1506 }
1507 }
1508 }
1509 }
1510
1511 /* Disable the IRDA DMA Rx request if enabled */
1512 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1513 {
1514 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1515
1516 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1517 if (hirda->hdmarx != NULL)
1518 {
1519 /* Set the IRDA DMA Abort callback to Null.
1520 No call back execution at end of DMA abort procedure */
1521 hirda->hdmarx->XferAbortCallback = NULL;
1522
1523 if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1524 {
1525 if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1526 {
1527 /* Set error code to DMA */
1528 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1529
1530 return HAL_TIMEOUT;
1531 }
1532 }
1533 }
1534 }
1535 #endif /* HAL_DMA_MODULE_ENABLED */
1536
1537 /* Reset Tx and Rx transfer counters */
1538 hirda->TxXferCount = 0U;
1539 hirda->RxXferCount = 0U;
1540
1541 /* Clear the Error flags in the ICR register */
1542 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1543
1544 /* Restore hirda->gState and hirda->RxState to Ready */
1545 hirda->gState = HAL_IRDA_STATE_READY;
1546 hirda->RxState = HAL_IRDA_STATE_READY;
1547
1548 /* Reset Handle ErrorCode to No Error */
1549 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1550
1551 return HAL_OK;
1552 }
1553
1554 /**
1555 * @brief Abort ongoing Transmit transfer (blocking mode).
1556 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1557 * the configuration information for the specified UART module.
1558 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1559 * This procedure performs following operations :
1560 * - Disable IRDA Interrupts (Tx)
1561 * - Disable the DMA transfer in the peripheral register (if enabled)
1562 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1563 * - Set handle State to READY
1564 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1565 * @retval HAL status
1566 */
HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef * hirda)1567 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
1568 {
1569 /* Disable TXEIE and TCIE interrupts */
1570 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1571
1572 #if defined(HAL_DMA_MODULE_ENABLED)
1573 /* Disable the IRDA DMA Tx request if enabled */
1574 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1575 {
1576 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1577
1578 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1579 if (hirda->hdmatx != NULL)
1580 {
1581 /* Set the IRDA DMA Abort callback to Null.
1582 No call back execution at end of DMA abort procedure */
1583 hirda->hdmatx->XferAbortCallback = NULL;
1584
1585 if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1586 {
1587 if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1588 {
1589 /* Set error code to DMA */
1590 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1591
1592 return HAL_TIMEOUT;
1593 }
1594 }
1595 }
1596 }
1597 #endif /* HAL_DMA_MODULE_ENABLED */
1598
1599 /* Reset Tx transfer counter */
1600 hirda->TxXferCount = 0U;
1601
1602 /* Restore hirda->gState to Ready */
1603 hirda->gState = HAL_IRDA_STATE_READY;
1604
1605 return HAL_OK;
1606 }
1607
1608 /**
1609 * @brief Abort ongoing Receive transfer (blocking mode).
1610 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1611 * the configuration information for the specified UART module.
1612 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1613 * This procedure performs following operations :
1614 * - Disable IRDA Interrupts (Rx)
1615 * - Disable the DMA transfer in the peripheral register (if enabled)
1616 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1617 * - Set handle State to READY
1618 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1619 * @retval HAL status
1620 */
HAL_IRDA_AbortReceive(IRDA_HandleTypeDef * hirda)1621 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
1622 {
1623 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1624 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
1625 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1626
1627 #if defined(HAL_DMA_MODULE_ENABLED)
1628 /* Disable the IRDA DMA Rx request if enabled */
1629 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1630 {
1631 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1632
1633 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1634 if (hirda->hdmarx != NULL)
1635 {
1636 /* Set the IRDA DMA Abort callback to Null.
1637 No call back execution at end of DMA abort procedure */
1638 hirda->hdmarx->XferAbortCallback = NULL;
1639
1640 if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1641 {
1642 if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1643 {
1644 /* Set error code to DMA */
1645 hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1646
1647 return HAL_TIMEOUT;
1648 }
1649 }
1650 }
1651 }
1652 #endif /* HAL_DMA_MODULE_ENABLED */
1653
1654 /* Reset Rx transfer counter */
1655 hirda->RxXferCount = 0U;
1656
1657 /* Clear the Error flags in the ICR register */
1658 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1659
1660 /* Restore hirda->RxState to Ready */
1661 hirda->RxState = HAL_IRDA_STATE_READY;
1662
1663 return HAL_OK;
1664 }
1665
1666 /**
1667 * @brief Abort ongoing transfers (Interrupt mode).
1668 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1669 * the configuration information for the specified UART module.
1670 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1671 * This procedure performs following operations :
1672 * - Disable IRDA Interrupts (Tx and Rx)
1673 * - Disable the DMA transfer in the peripheral register (if enabled)
1674 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1675 * - Set handle State to READY
1676 * - At abort completion, call user abort complete callback
1677 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1678 * considered as completed only when user abort complete callback is executed (not when exiting function).
1679 * @retval HAL status
1680 */
HAL_IRDA_Abort_IT(IRDA_HandleTypeDef * hirda)1681 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
1682 {
1683 uint32_t abortcplt = 1U;
1684
1685 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1686 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \
1687 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1688 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1689
1690 #if defined(HAL_DMA_MODULE_ENABLED)
1691 /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
1692 before any call to DMA Abort functions */
1693 /* DMA Tx Handle is valid */
1694 if (hirda->hdmatx != NULL)
1695 {
1696 /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
1697 Otherwise, set it to NULL */
1698 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1699 {
1700 hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
1701 }
1702 else
1703 {
1704 hirda->hdmatx->XferAbortCallback = NULL;
1705 }
1706 }
1707 /* DMA Rx Handle is valid */
1708 if (hirda->hdmarx != NULL)
1709 {
1710 /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
1711 Otherwise, set it to NULL */
1712 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1713 {
1714 hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
1715 }
1716 else
1717 {
1718 hirda->hdmarx->XferAbortCallback = NULL;
1719 }
1720 }
1721
1722 /* Disable the IRDA DMA Tx request if enabled */
1723 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1724 {
1725 /* Disable DMA Tx at UART level */
1726 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1727
1728 /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1729 if (hirda->hdmatx != NULL)
1730 {
1731 /* IRDA Tx DMA Abort callback has already been initialised :
1732 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1733
1734 /* Abort DMA TX */
1735 if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1736 {
1737 hirda->hdmatx->XferAbortCallback = NULL;
1738 }
1739 else
1740 {
1741 abortcplt = 0U;
1742 }
1743 }
1744 }
1745
1746 /* Disable the IRDA DMA Rx request if enabled */
1747 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1748 {
1749 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1750
1751 /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1752 if (hirda->hdmarx != NULL)
1753 {
1754 /* IRDA Rx DMA Abort callback has already been initialised :
1755 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1756
1757 /* Abort DMA RX */
1758 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1759 {
1760 hirda->hdmarx->XferAbortCallback = NULL;
1761 abortcplt = 1U;
1762 }
1763 else
1764 {
1765 abortcplt = 0U;
1766 }
1767 }
1768 }
1769 #endif /* HAL_DMA_MODULE_ENABLED */
1770
1771 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1772 if (abortcplt == 1U)
1773 {
1774 /* Reset Tx and Rx transfer counters */
1775 hirda->TxXferCount = 0U;
1776 hirda->RxXferCount = 0U;
1777
1778 /* Reset errorCode */
1779 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1780
1781 /* Clear the Error flags in the ICR register */
1782 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1783
1784 /* Restore hirda->gState and hirda->RxState to Ready */
1785 hirda->gState = HAL_IRDA_STATE_READY;
1786 hirda->RxState = HAL_IRDA_STATE_READY;
1787
1788 /* As no DMA to be aborted, call directly user Abort complete callback */
1789 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1790 /* Call registered Abort complete callback */
1791 hirda->AbortCpltCallback(hirda);
1792 #else
1793 /* Call legacy weak Abort complete callback */
1794 HAL_IRDA_AbortCpltCallback(hirda);
1795 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1796 }
1797
1798 return HAL_OK;
1799 }
1800
1801 /**
1802 * @brief Abort ongoing Transmit transfer (Interrupt mode).
1803 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1804 * the configuration information for the specified UART module.
1805 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1806 * This procedure performs following operations :
1807 * - Disable IRDA Interrupts (Tx)
1808 * - Disable the DMA transfer in the peripheral register (if enabled)
1809 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1810 * - Set handle State to READY
1811 * - At abort completion, call user abort complete callback
1812 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1813 * considered as completed only when user abort complete callback is executed (not when exiting function).
1814 * @retval HAL status
1815 */
HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef * hirda)1816 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
1817 {
1818 /* Disable TXEIE and TCIE interrupts */
1819 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1820
1821 #if defined(HAL_DMA_MODULE_ENABLED)
1822 /* Disable the IRDA DMA Tx request if enabled */
1823 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1824 {
1825 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1826
1827 /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1828 if (hirda->hdmatx != NULL)
1829 {
1830 /* Set the IRDA DMA Abort callback :
1831 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1832 hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
1833
1834 /* Abort DMA TX */
1835 if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1836 {
1837 /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
1838 hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
1839 }
1840 }
1841 else
1842 {
1843 /* Reset Tx transfer counter */
1844 hirda->TxXferCount = 0U;
1845
1846 /* Restore hirda->gState to Ready */
1847 hirda->gState = HAL_IRDA_STATE_READY;
1848
1849 /* As no DMA to be aborted, call directly user Abort complete callback */
1850 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1851 /* Call registered Abort Transmit Complete Callback */
1852 hirda->AbortTransmitCpltCallback(hirda);
1853 #else
1854 /* Call legacy weak Abort Transmit Complete Callback */
1855 HAL_IRDA_AbortTransmitCpltCallback(hirda);
1856 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1857 }
1858 }
1859 else
1860 #endif /* HAL_DMA_MODULE_ENABLED */
1861 {
1862 /* Reset Tx transfer counter */
1863 hirda->TxXferCount = 0U;
1864
1865 /* Restore hirda->gState to Ready */
1866 hirda->gState = HAL_IRDA_STATE_READY;
1867
1868 /* As no DMA to be aborted, call directly user Abort complete callback */
1869 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1870 /* Call registered Abort Transmit Complete Callback */
1871 hirda->AbortTransmitCpltCallback(hirda);
1872 #else
1873 /* Call legacy weak Abort Transmit Complete Callback */
1874 HAL_IRDA_AbortTransmitCpltCallback(hirda);
1875 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1876 }
1877
1878 return HAL_OK;
1879 }
1880
1881 /**
1882 * @brief Abort ongoing Receive transfer (Interrupt mode).
1883 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1884 * the configuration information for the specified UART module.
1885 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1886 * This procedure performs following operations :
1887 * - Disable IRDA Interrupts (Rx)
1888 * - Disable the DMA transfer in the peripheral register (if enabled)
1889 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1890 * - Set handle State to READY
1891 * - At abort completion, call user abort complete callback
1892 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1893 * considered as completed only when user abort complete callback is executed (not when exiting function).
1894 * @retval HAL status
1895 */
HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef * hirda)1896 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
1897 {
1898 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1899 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
1900 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1901
1902 #if defined(HAL_DMA_MODULE_ENABLED)
1903 /* Disable the IRDA DMA Rx request if enabled */
1904 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1905 {
1906 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1907
1908 /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1909 if (hirda->hdmarx != NULL)
1910 {
1911 /* Set the IRDA DMA Abort callback :
1912 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1913 hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
1914
1915 /* Abort DMA RX */
1916 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1917 {
1918 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1919 hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1920 }
1921 }
1922 else
1923 {
1924 /* Reset Rx transfer counter */
1925 hirda->RxXferCount = 0U;
1926
1927 /* Clear the Error flags in the ICR register */
1928 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1929
1930 /* Restore hirda->RxState to Ready */
1931 hirda->RxState = HAL_IRDA_STATE_READY;
1932
1933 /* As no DMA to be aborted, call directly user Abort complete callback */
1934 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1935 /* Call registered Abort Receive Complete Callback */
1936 hirda->AbortReceiveCpltCallback(hirda);
1937 #else
1938 /* Call legacy weak Abort Receive Complete Callback */
1939 HAL_IRDA_AbortReceiveCpltCallback(hirda);
1940 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1941 }
1942 }
1943 else
1944 #endif /* HAL_DMA_MODULE_ENABLED */
1945 {
1946 /* Reset Rx transfer counter */
1947 hirda->RxXferCount = 0U;
1948
1949 /* Clear the Error flags in the ICR register */
1950 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1951
1952 /* Restore hirda->RxState to Ready */
1953 hirda->RxState = HAL_IRDA_STATE_READY;
1954
1955 /* As no DMA to be aborted, call directly user Abort complete callback */
1956 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1957 /* Call registered Abort Receive Complete Callback */
1958 hirda->AbortReceiveCpltCallback(hirda);
1959 #else
1960 /* Call legacy weak Abort Receive Complete Callback */
1961 HAL_IRDA_AbortReceiveCpltCallback(hirda);
1962 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1963 }
1964
1965 return HAL_OK;
1966 }
1967
1968 /**
1969 * @brief Handle IRDA interrupt request.
1970 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1971 * the configuration information for the specified IRDA module.
1972 * @retval None
1973 */
HAL_IRDA_IRQHandler(IRDA_HandleTypeDef * hirda)1974 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
1975 {
1976 uint32_t isrflags = READ_REG(hirda->Instance->ISR);
1977 uint32_t cr1its = READ_REG(hirda->Instance->CR1);
1978 uint32_t cr3its;
1979 uint32_t errorflags;
1980 uint32_t errorcode;
1981
1982 /* If no error occurs */
1983 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
1984 if (errorflags == 0U)
1985 {
1986 /* IRDA in mode Receiver ---------------------------------------------------*/
1987 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
1988 {
1989 IRDA_Receive_IT(hirda);
1990 return;
1991 }
1992 }
1993
1994 /* If some errors occur */
1995 cr3its = READ_REG(hirda->Instance->CR3);
1996 if ((errorflags != 0U)
1997 && (((cr3its & USART_CR3_EIE) != 0U)
1998 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
1999 {
2000 /* IRDA parity error interrupt occurred -------------------------------------*/
2001 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2002 {
2003 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
2004
2005 hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
2006 }
2007
2008 /* IRDA frame error interrupt occurred --------------------------------------*/
2009 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2010 {
2011 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
2012
2013 hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
2014 }
2015
2016 /* IRDA noise error interrupt occurred --------------------------------------*/
2017 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2018 {
2019 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
2020
2021 hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
2022 }
2023
2024 /* IRDA Over-Run interrupt occurred -----------------------------------------*/
2025 if (((isrflags & USART_ISR_ORE) != 0U) &&
2026 (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U)))
2027 {
2028 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
2029
2030 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
2031 }
2032
2033 /* Call IRDA Error Call back function if need be --------------------------*/
2034 if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
2035 {
2036 /* IRDA in mode Receiver ---------------------------------------------------*/
2037 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U))
2038 {
2039 IRDA_Receive_IT(hirda);
2040 }
2041
2042 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2043 consider error as blocking */
2044 errorcode = hirda->ErrorCode;
2045 if ((HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) ||
2046 ((errorcode & HAL_IRDA_ERROR_ORE) != 0U))
2047 {
2048 /* Blocking error : transfer is aborted
2049 Set the IRDA state ready to be able to start again the process,
2050 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2051 IRDA_EndRxTransfer(hirda);
2052
2053 #if defined(HAL_DMA_MODULE_ENABLED)
2054 /* Disable the IRDA DMA Rx request if enabled */
2055 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2056 {
2057 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2058
2059 /* Abort the IRDA DMA Rx channel */
2060 if (hirda->hdmarx != NULL)
2061 {
2062 /* Set the IRDA DMA Abort callback :
2063 will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
2064 hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
2065
2066 /* Abort DMA RX */
2067 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
2068 {
2069 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
2070 hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
2071 }
2072 }
2073 else
2074 {
2075 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2076 /* Call registered user error callback */
2077 hirda->ErrorCallback(hirda);
2078 #else
2079 /* Call legacy weak user error callback */
2080 HAL_IRDA_ErrorCallback(hirda);
2081 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2082 }
2083 }
2084 else
2085 #endif /* HAL_DMA_MODULE_ENABLED */
2086 {
2087 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2088 /* Call registered user error callback */
2089 hirda->ErrorCallback(hirda);
2090 #else
2091 /* Call legacy weak user error callback */
2092 HAL_IRDA_ErrorCallback(hirda);
2093 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2094 }
2095 }
2096 else
2097 {
2098 /* Non Blocking error : transfer could go on.
2099 Error is notified to user through user error callback */
2100 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2101 /* Call registered user error callback */
2102 hirda->ErrorCallback(hirda);
2103 #else
2104 /* Call legacy weak user error callback */
2105 HAL_IRDA_ErrorCallback(hirda);
2106 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2107 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2108 }
2109 }
2110 return;
2111
2112 } /* End if some error occurs */
2113
2114 /* IRDA in mode Transmitter ------------------------------------------------*/
2115 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) && ((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U))
2116 {
2117 IRDA_Transmit_IT(hirda);
2118 return;
2119 }
2120
2121 /* IRDA in mode Transmitter (transmission end) -----------------------------*/
2122 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2123 {
2124 IRDA_EndTransmit_IT(hirda);
2125 return;
2126 }
2127
2128 }
2129
2130 /**
2131 * @brief Tx Transfer completed callback.
2132 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2133 * the configuration information for the specified IRDA module.
2134 * @retval None
2135 */
HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef * hirda)2136 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
2137 {
2138 /* Prevent unused argument(s) compilation warning */
2139 UNUSED(hirda);
2140
2141 /* NOTE : This function should not be modified, when the callback is needed,
2142 the HAL_IRDA_TxCpltCallback can be implemented in the user file.
2143 */
2144 }
2145
2146 /**
2147 * @brief Tx Half Transfer completed callback.
2148 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2149 * the configuration information for the specified USART module.
2150 * @retval None
2151 */
HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef * hirda)2152 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2153 {
2154 /* Prevent unused argument(s) compilation warning */
2155 UNUSED(hirda);
2156
2157 /* NOTE : This function should not be modified, when the callback is needed,
2158 the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
2159 */
2160 }
2161
2162 /**
2163 * @brief Rx Transfer completed callback.
2164 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2165 * the configuration information for the specified IRDA module.
2166 * @retval None
2167 */
HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef * hirda)2168 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
2169 {
2170 /* Prevent unused argument(s) compilation warning */
2171 UNUSED(hirda);
2172
2173 /* NOTE : This function should not be modified, when the callback is needed,
2174 the HAL_IRDA_RxCpltCallback can be implemented in the user file.
2175 */
2176 }
2177
2178 /**
2179 * @brief Rx Half Transfer complete callback.
2180 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2181 * the configuration information for the specified IRDA module.
2182 * @retval None
2183 */
HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef * hirda)2184 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2185 {
2186 /* Prevent unused argument(s) compilation warning */
2187 UNUSED(hirda);
2188
2189 /* NOTE : This function should not be modified, when the callback is needed,
2190 the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
2191 */
2192 }
2193
2194 /**
2195 * @brief IRDA error callback.
2196 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2197 * the configuration information for the specified IRDA module.
2198 * @retval None
2199 */
HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef * hirda)2200 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
2201 {
2202 /* Prevent unused argument(s) compilation warning */
2203 UNUSED(hirda);
2204
2205 /* NOTE : This function should not be modified, when the callback is needed,
2206 the HAL_IRDA_ErrorCallback can be implemented in the user file.
2207 */
2208 }
2209
2210 /**
2211 * @brief IRDA Abort Complete callback.
2212 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2213 * the configuration information for the specified IRDA module.
2214 * @retval None
2215 */
HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef * hirda)2216 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
2217 {
2218 /* Prevent unused argument(s) compilation warning */
2219 UNUSED(hirda);
2220
2221 /* NOTE : This function should not be modified, when the callback is needed,
2222 the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
2223 */
2224 }
2225
2226 /**
2227 * @brief IRDA Abort Complete callback.
2228 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2229 * the configuration information for the specified IRDA module.
2230 * @retval None
2231 */
HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef * hirda)2232 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
2233 {
2234 /* Prevent unused argument(s) compilation warning */
2235 UNUSED(hirda);
2236
2237 /* NOTE : This function should not be modified, when the callback is needed,
2238 the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
2239 */
2240 }
2241
2242 /**
2243 * @brief IRDA Abort Receive Complete callback.
2244 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2245 * the configuration information for the specified IRDA module.
2246 * @retval None
2247 */
HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef * hirda)2248 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
2249 {
2250 /* Prevent unused argument(s) compilation warning */
2251 UNUSED(hirda);
2252
2253 /* NOTE : This function should not be modified, when the callback is needed,
2254 the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
2255 */
2256 }
2257
2258 /**
2259 * @}
2260 */
2261
2262 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
2263 * @brief IRDA State and Errors functions
2264 *
2265 @verbatim
2266 ==============================================================================
2267 ##### Peripheral State and Error functions #####
2268 ==============================================================================
2269 [..]
2270 This subsection provides a set of functions allowing to return the State of IrDA
2271 communication process and also return Peripheral Errors occurred during communication process
2272 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
2273 of the IRDA peripheral handle.
2274 (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
2275 communication.
2276
2277 @endverbatim
2278 * @{
2279 */
2280
2281 /**
2282 * @brief Return the IRDA handle state.
2283 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2284 * the configuration information for the specified IRDA module.
2285 * @retval HAL state
2286 */
HAL_IRDA_GetState(const IRDA_HandleTypeDef * hirda)2287 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(const IRDA_HandleTypeDef *hirda)
2288 {
2289 /* Return IRDA handle state */
2290 uint32_t temp1;
2291 uint32_t temp2;
2292 temp1 = (uint32_t)hirda->gState;
2293 temp2 = (uint32_t)hirda->RxState;
2294
2295 return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
2296 }
2297
2298 /**
2299 * @brief Return the IRDA handle error code.
2300 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2301 * the configuration information for the specified IRDA module.
2302 * @retval IRDA Error Code
2303 */
HAL_IRDA_GetError(const IRDA_HandleTypeDef * hirda)2304 uint32_t HAL_IRDA_GetError(const IRDA_HandleTypeDef *hirda)
2305 {
2306 return hirda->ErrorCode;
2307 }
2308
2309 /**
2310 * @}
2311 */
2312
2313 /**
2314 * @}
2315 */
2316
2317 /** @defgroup IRDA_Private_Functions IRDA Private Functions
2318 * @{
2319 */
2320
2321 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2322 /**
2323 * @brief Initialize the callbacks to their default values.
2324 * @param hirda IRDA handle.
2325 * @retval none
2326 */
IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef * hirda)2327 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
2328 {
2329 /* Init the IRDA Callback settings */
2330 hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2331 hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */
2332 hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2333 hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */
2334 hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */
2335 hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2336 hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2337 hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
2338
2339 }
2340 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2341
2342 /**
2343 * @brief Configure the IRDA peripheral.
2344 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2345 * the configuration information for the specified IRDA module.
2346 * @retval HAL status
2347 */
IRDA_SetConfig(IRDA_HandleTypeDef * hirda)2348 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
2349 {
2350 uint32_t tmpreg;
2351 IRDA_ClockSourceTypeDef clocksource;
2352 HAL_StatusTypeDef ret = HAL_OK;
2353 static const uint16_t IRDAPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
2354 PLL2_ClocksTypeDef pll2_clocks;
2355 #if defined(RCC_CR_PLL3ON)
2356 PLL3_ClocksTypeDef pll3_clocks;
2357 #endif /* RCC_CR_PLL3ON */
2358 uint32_t pclk;
2359
2360 /* Check the communication parameters */
2361 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2362 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2363 assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2364 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
2365 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
2366 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
2367 assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler));
2368
2369 /*-------------------------- USART CR1 Configuration -----------------------*/
2370 /* Configure the IRDA Word Length, Parity and transfer Mode:
2371 Set the M bits according to hirda->Init.WordLength value
2372 Set PCE and PS bits according to hirda->Init.Parity value
2373 Set TE and RE bits according to hirda->Init.Mode value */
2374 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
2375
2376 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
2377
2378 /*-------------------------- USART CR3 Configuration -----------------------*/
2379 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
2380
2381 /*--------------------- USART clock PRESC Configuration ----------------*/
2382 /* Configure
2383 * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */
2384 MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler);
2385
2386 /*-------------------------- USART GTPR Configuration ----------------------*/
2387 MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler);
2388
2389 /*-------------------------- USART BRR Configuration -----------------------*/
2390 IRDA_GETCLOCKSOURCE(hirda, clocksource);
2391 tmpreg = 0U;
2392 switch (clocksource)
2393 {
2394 case IRDA_CLOCKSOURCE_PLL2Q:
2395 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2396 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll2_clocks.PLL2_Q_Frequency,
2397 hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2398 break;
2399 #if defined(RCC_CR_PLL3ON)
2400 case IRDA_CLOCKSOURCE_PLL3Q:
2401 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2402 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll3_clocks.PLL3_Q_Frequency, hirda->Init.BaudRate,
2403 hirda->Init.ClockPrescaler));
2404 break;
2405 #endif /* RCC_CR_PLL3ON */
2406 case IRDA_CLOCKSOURCE_CSI:
2407 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(CSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2408 break;
2409 case IRDA_CLOCKSOURCE_PCLK1:
2410 pclk = HAL_RCC_GetPCLK1Freq();
2411 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2412 break;
2413 case IRDA_CLOCKSOURCE_PCLK2:
2414 pclk = HAL_RCC_GetPCLK2Freq();
2415 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2416 break;
2417 case IRDA_CLOCKSOURCE_HSI:
2418 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2419 break;
2420 case IRDA_CLOCKSOURCE_LSE:
2421 tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler));
2422 break;
2423 default:
2424 ret = HAL_ERROR;
2425 break;
2426 }
2427
2428 /* USARTDIV must be greater than or equal to 0d16 */
2429 if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX))
2430 {
2431 hirda->Instance->BRR = (uint16_t)tmpreg;
2432 }
2433 else
2434 {
2435 ret = HAL_ERROR;
2436 }
2437
2438 return ret;
2439 }
2440
2441 /**
2442 * @brief Check the IRDA Idle State.
2443 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2444 * the configuration information for the specified IRDA module.
2445 * @retval HAL status
2446 */
IRDA_CheckIdleState(IRDA_HandleTypeDef * hirda)2447 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
2448 {
2449 uint32_t tickstart;
2450
2451 /* Initialize the IRDA ErrorCode */
2452 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2453
2454 /* Init tickstart for timeout management */
2455 tickstart = HAL_GetTick();
2456
2457 /* Check if the Transmitter is enabled */
2458 if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2459 {
2460 /* Wait until TEACK flag is set */
2461 if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2462 {
2463 /* Timeout occurred */
2464 return HAL_TIMEOUT;
2465 }
2466 }
2467 /* Check if the Receiver is enabled */
2468 if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2469 {
2470 /* Wait until REACK flag is set */
2471 if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2472 {
2473 /* Timeout occurred */
2474 return HAL_TIMEOUT;
2475 }
2476 }
2477
2478 /* Initialize the IRDA state*/
2479 hirda->gState = HAL_IRDA_STATE_READY;
2480 hirda->RxState = HAL_IRDA_STATE_READY;
2481
2482 /* Process Unlocked */
2483 __HAL_UNLOCK(hirda);
2484
2485 return HAL_OK;
2486 }
2487
2488 /**
2489 * @brief Handle IRDA Communication Timeout. It waits
2490 * until a flag is no longer in the specified status.
2491 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2492 * the configuration information for the specified IRDA module.
2493 * @param Flag Specifies the IRDA flag to check.
2494 * @param Status The actual Flag status (SET or RESET)
2495 * @param Tickstart Tick start value
2496 * @param Timeout Timeout duration
2497 * @retval HAL status
2498 */
IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef * hirda,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)2499 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
2500 uint32_t Tickstart, uint32_t Timeout)
2501 {
2502 /* Wait until flag is set */
2503 while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
2504 {
2505 /* Check for the Timeout */
2506 if (Timeout != HAL_MAX_DELAY)
2507 {
2508 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2509 {
2510 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
2511 interrupts for the interrupt process */
2512 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
2513 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2514
2515 hirda->gState = HAL_IRDA_STATE_READY;
2516 hirda->RxState = HAL_IRDA_STATE_READY;
2517
2518 /* Process Unlocked */
2519 __HAL_UNLOCK(hirda);
2520 return HAL_TIMEOUT;
2521 }
2522 }
2523 }
2524 return HAL_OK;
2525 }
2526
2527
2528 #if defined(HAL_DMA_MODULE_ENABLED)
2529 /**
2530 * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
2531 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2532 * the configuration information for the specified IRDA module.
2533 * @retval None
2534 */
IRDA_EndTxTransfer(IRDA_HandleTypeDef * hirda)2535 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
2536 {
2537 /* Disable TXEIE and TCIE interrupts */
2538 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
2539
2540 /* At end of Tx process, restore hirda->gState to Ready */
2541 hirda->gState = HAL_IRDA_STATE_READY;
2542 }
2543 #endif /* HAL_DMA_MODULE_ENABLED */
2544
2545 /**
2546 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
2547 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2548 * the configuration information for the specified IRDA module.
2549 * @retval None
2550 */
IRDA_EndRxTransfer(IRDA_HandleTypeDef * hirda)2551 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
2552 {
2553 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2554 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2555 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2556
2557 /* At end of Rx process, restore hirda->RxState to Ready */
2558 hirda->RxState = HAL_IRDA_STATE_READY;
2559 }
2560
2561
2562 #if defined(HAL_DMA_MODULE_ENABLED)
2563 /**
2564 * @brief DMA IRDA transmit process complete callback.
2565 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2566 * the configuration information for the specified DMA module.
2567 * @retval None
2568 */
IRDA_DMATransmitCplt(DMA_HandleTypeDef * hdma)2569 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2570 {
2571 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2572
2573 /* DMA Normal mode */
2574 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2575 {
2576 hirda->TxXferCount = 0U;
2577
2578 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2579 in the IRDA CR3 register */
2580 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
2581
2582 /* Enable the IRDA Transmit Complete Interrupt */
2583 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2584 }
2585 /* DMA Circular mode */
2586 else
2587 {
2588 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2589 /* Call registered Tx complete callback */
2590 hirda->TxCpltCallback(hirda);
2591 #else
2592 /* Call legacy weak Tx complete callback */
2593 HAL_IRDA_TxCpltCallback(hirda);
2594 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2595 }
2596
2597 }
2598
2599 /**
2600 * @brief DMA IRDA transmit process half complete callback.
2601 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2602 * the configuration information for the specified DMA module.
2603 * @retval None
2604 */
IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef * hdma)2605 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
2606 {
2607 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2608
2609 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2610 /* Call registered Tx Half complete callback */
2611 hirda->TxHalfCpltCallback(hirda);
2612 #else
2613 /* Call legacy weak Tx complete callback */
2614 HAL_IRDA_TxHalfCpltCallback(hirda);
2615 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2616 }
2617
2618 /**
2619 * @brief DMA IRDA receive process complete callback.
2620 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2621 * the configuration information for the specified DMA module.
2622 * @retval None
2623 */
IRDA_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2624 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2625 {
2626 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2627
2628 /* DMA Normal mode */
2629 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2630 {
2631 hirda->RxXferCount = 0U;
2632
2633 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2634 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2635 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2636
2637 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2638 in the IRDA CR3 register */
2639 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2640
2641 /* At end of Rx process, restore hirda->RxState to Ready */
2642 hirda->RxState = HAL_IRDA_STATE_READY;
2643 }
2644
2645 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2646 /* Call registered Rx complete callback */
2647 hirda->RxCpltCallback(hirda);
2648 #else
2649 /* Call legacy weak Rx complete callback */
2650 HAL_IRDA_RxCpltCallback(hirda);
2651 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2652 }
2653
2654 /**
2655 * @brief DMA IRDA receive process half complete callback.
2656 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2657 * the configuration information for the specified DMA module.
2658 * @retval None
2659 */
IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef * hdma)2660 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
2661 {
2662 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2663
2664 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2665 /*Call registered Rx Half complete callback*/
2666 hirda->RxHalfCpltCallback(hirda);
2667 #else
2668 /* Call legacy weak Rx Half complete callback */
2669 HAL_IRDA_RxHalfCpltCallback(hirda);
2670 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2671 }
2672
2673 /**
2674 * @brief DMA IRDA communication error callback.
2675 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2676 * the configuration information for the specified DMA module.
2677 * @retval None
2678 */
IRDA_DMAError(DMA_HandleTypeDef * hdma)2679 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
2680 {
2681 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2682
2683 /* Stop IRDA DMA Tx request if ongoing */
2684 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2685 {
2686 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
2687 {
2688 hirda->TxXferCount = 0U;
2689 IRDA_EndTxTransfer(hirda);
2690 }
2691 }
2692
2693 /* Stop IRDA DMA Rx request if ongoing */
2694 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2695 {
2696 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2697 {
2698 hirda->RxXferCount = 0U;
2699 IRDA_EndRxTransfer(hirda);
2700 }
2701 }
2702
2703 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
2704 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2705 /* Call registered user error callback */
2706 hirda->ErrorCallback(hirda);
2707 #else
2708 /* Call legacy weak user error callback */
2709 HAL_IRDA_ErrorCallback(hirda);
2710 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2711 }
2712
2713 /**
2714 * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error
2715 * (To be called at end of DMA Abort procedure following error occurrence).
2716 * @param hdma DMA handle.
2717 * @retval None
2718 */
IRDA_DMAAbortOnError(DMA_HandleTypeDef * hdma)2719 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2720 {
2721 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2722 hirda->RxXferCount = 0U;
2723 hirda->TxXferCount = 0U;
2724
2725 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2726 /* Call registered user error callback */
2727 hirda->ErrorCallback(hirda);
2728 #else
2729 /* Call legacy weak user error callback */
2730 HAL_IRDA_ErrorCallback(hirda);
2731 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2732 }
2733
2734 /**
2735 * @brief DMA IRDA Tx communication abort callback, when initiated by user
2736 * (To be called at end of DMA Tx Abort procedure following user abort request).
2737 * @note When this callback is executed, User Abort complete call back is called only if no
2738 * Abort still ongoing for Rx DMA Handle.
2739 * @param hdma DMA handle.
2740 * @retval None
2741 */
IRDA_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2742 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2743 {
2744 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2745
2746 hirda->hdmatx->XferAbortCallback = NULL;
2747
2748 /* Check if an Abort process is still ongoing */
2749 if (hirda->hdmarx != NULL)
2750 {
2751 if (hirda->hdmarx->XferAbortCallback != NULL)
2752 {
2753 return;
2754 }
2755 }
2756
2757 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2758 hirda->TxXferCount = 0U;
2759 hirda->RxXferCount = 0U;
2760
2761 /* Reset errorCode */
2762 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2763
2764 /* Clear the Error flags in the ICR register */
2765 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2766
2767 /* Restore hirda->gState and hirda->RxState to Ready */
2768 hirda->gState = HAL_IRDA_STATE_READY;
2769 hirda->RxState = HAL_IRDA_STATE_READY;
2770
2771 /* Call user Abort complete callback */
2772 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2773 /* Call registered Abort complete callback */
2774 hirda->AbortCpltCallback(hirda);
2775 #else
2776 /* Call legacy weak Abort complete callback */
2777 HAL_IRDA_AbortCpltCallback(hirda);
2778 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2779 }
2780
2781
2782 /**
2783 * @brief DMA IRDA Rx communication abort callback, when initiated by user
2784 * (To be called at end of DMA Rx Abort procedure following user abort request).
2785 * @note When this callback is executed, User Abort complete call back is called only if no
2786 * Abort still ongoing for Tx DMA Handle.
2787 * @param hdma DMA handle.
2788 * @retval None
2789 */
IRDA_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2790 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2791 {
2792 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2793
2794 hirda->hdmarx->XferAbortCallback = NULL;
2795
2796 /* Check if an Abort process is still ongoing */
2797 if (hirda->hdmatx != NULL)
2798 {
2799 if (hirda->hdmatx->XferAbortCallback != NULL)
2800 {
2801 return;
2802 }
2803 }
2804
2805 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2806 hirda->TxXferCount = 0U;
2807 hirda->RxXferCount = 0U;
2808
2809 /* Reset errorCode */
2810 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2811
2812 /* Clear the Error flags in the ICR register */
2813 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2814
2815 /* Restore hirda->gState and hirda->RxState to Ready */
2816 hirda->gState = HAL_IRDA_STATE_READY;
2817 hirda->RxState = HAL_IRDA_STATE_READY;
2818
2819 /* Call user Abort complete callback */
2820 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2821 /* Call registered Abort complete callback */
2822 hirda->AbortCpltCallback(hirda);
2823 #else
2824 /* Call legacy weak Abort complete callback */
2825 HAL_IRDA_AbortCpltCallback(hirda);
2826 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2827 }
2828
2829
2830 /**
2831 * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to
2832 * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
2833 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2834 * and leads to user Tx Abort Complete callback execution).
2835 * @param hdma DMA handle.
2836 * @retval None
2837 */
IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2838 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2839 {
2840 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2841
2842 hirda->TxXferCount = 0U;
2843
2844 /* Restore hirda->gState to Ready */
2845 hirda->gState = HAL_IRDA_STATE_READY;
2846
2847 /* Call user Abort complete callback */
2848 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2849 /* Call registered Abort Transmit Complete Callback */
2850 hirda->AbortTransmitCpltCallback(hirda);
2851 #else
2852 /* Call legacy weak Abort Transmit Complete Callback */
2853 HAL_IRDA_AbortTransmitCpltCallback(hirda);
2854 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2855 }
2856
2857 /**
2858 * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to
2859 * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
2860 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2861 * and leads to user Rx Abort Complete callback execution).
2862 * @param hdma DMA handle.
2863 * @retval None
2864 */
IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2865 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2866 {
2867 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2868
2869 hirda->RxXferCount = 0U;
2870
2871 /* Clear the Error flags in the ICR register */
2872 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2873
2874 /* Restore hirda->RxState to Ready */
2875 hirda->RxState = HAL_IRDA_STATE_READY;
2876
2877 /* Call user Abort complete callback */
2878 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2879 /* Call registered Abort Receive Complete Callback */
2880 hirda->AbortReceiveCpltCallback(hirda);
2881 #else
2882 /* Call legacy weak Abort Receive Complete Callback */
2883 HAL_IRDA_AbortReceiveCpltCallback(hirda);
2884 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2885 }
2886 #endif /* HAL_DMA_MODULE_ENABLED */
2887
2888 /**
2889 * @brief Send an amount of data in interrupt mode.
2890 * @note Function is called under interruption only, once
2891 * interruptions have been enabled by HAL_IRDA_Transmit_IT().
2892 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2893 * the configuration information for the specified IRDA module.
2894 * @retval None
2895 */
IRDA_Transmit_IT(IRDA_HandleTypeDef * hirda)2896 static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
2897 {
2898 const uint16_t *tmp;
2899
2900 /* Check that a Tx process is ongoing */
2901 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2902 {
2903 if (hirda->TxXferCount == 0U)
2904 {
2905 /* Disable the IRDA Transmit Data Register Empty Interrupt */
2906 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
2907
2908 /* Enable the IRDA Transmit Complete Interrupt */
2909 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2910 }
2911 else
2912 {
2913 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2914 {
2915 tmp = (const uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */
2916 hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
2917 hirda->pTxBuffPtr += 2U;
2918 }
2919 else
2920 {
2921 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU);
2922 hirda->pTxBuffPtr++;
2923 }
2924 hirda->TxXferCount--;
2925 }
2926 }
2927 }
2928
2929 /**
2930 * @brief Wrap up transmission in non-blocking mode.
2931 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2932 * the configuration information for the specified IRDA module.
2933 * @retval None
2934 */
IRDA_EndTransmit_IT(IRDA_HandleTypeDef * hirda)2935 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
2936 {
2937 /* Disable the IRDA Transmit Complete Interrupt */
2938 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2939
2940 /* Tx process is ended, restore hirda->gState to Ready */
2941 hirda->gState = HAL_IRDA_STATE_READY;
2942
2943 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2944 /* Call registered Tx complete callback */
2945 hirda->TxCpltCallback(hirda);
2946 #else
2947 /* Call legacy weak Tx complete callback */
2948 HAL_IRDA_TxCpltCallback(hirda);
2949 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2950 }
2951
2952 /**
2953 * @brief Receive an amount of data in interrupt mode.
2954 * @note Function is called under interruption only, once
2955 * interruptions have been enabled by HAL_IRDA_Receive_IT()
2956 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2957 * the configuration information for the specified IRDA module.
2958 * @retval None
2959 */
IRDA_Receive_IT(IRDA_HandleTypeDef * hirda)2960 static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
2961 {
2962 uint16_t *tmp;
2963 uint16_t uhMask = hirda->Mask;
2964 uint16_t uhdata;
2965
2966 /* Check that a Rx process is ongoing */
2967 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2968 {
2969 uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
2970 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2971 {
2972 tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */
2973 *tmp = (uint16_t)(uhdata & uhMask);
2974 hirda->pRxBuffPtr += 2U;
2975 }
2976 else
2977 {
2978 *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
2979 hirda->pRxBuffPtr++;
2980 }
2981
2982 hirda->RxXferCount--;
2983 if (hirda->RxXferCount == 0U)
2984 {
2985 /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */
2986 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2987
2988 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2989 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2990
2991 /* Rx process is completed, restore hirda->RxState to Ready */
2992 hirda->RxState = HAL_IRDA_STATE_READY;
2993
2994 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2995 /* Call registered Rx complete callback */
2996 hirda->RxCpltCallback(hirda);
2997 #else
2998 /* Call legacy weak Rx complete callback */
2999 HAL_IRDA_RxCpltCallback(hirda);
3000 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
3001 }
3002 }
3003 else
3004 {
3005 /* Clear RXNE interrupt flag */
3006 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
3007 }
3008 }
3009
3010 /**
3011 * @}
3012 */
3013
3014 #endif /* HAL_IRDA_MODULE_ENABLED */
3015 /**
3016 * @}
3017 */
3018
3019 /**
3020 * @}
3021 */
3022