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