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