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