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