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