source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c

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