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