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