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