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