comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c @ 160:e3ca52b8e7fa

Merge with FlipDisplay
author heinrichsweikamp
date Thu, 07 Mar 2019 15:06:43 +0100
parents c78bcbd5deda
children
comparison
equal deleted inserted replaced
80:cc2bb7bb8456 160:e3ca52b8e7fa
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_irda.c
4 * @author MCD Application Team
5 * @brief IRDA HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the IrDA SIR ENDEC block (IrDA):
8 * + Initialization and de-initialization methods
9 * + IO operation methods
10 * + Peripheral Control methods
11 *
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 The IRDA HAL driver can be used as follows:
18
19 (#) Declare a IRDA_HandleTypeDef handle structure.
20 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
21 (##) Enable the USARTx interface clock.
22 (##) IRDA pins configuration:
23 (+++) Enable the clock for the IRDA GPIOs.
24 (+++) Configure these IRDA pins as alternate function pull-up.
25 (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
26 and HAL_IRDA_Receive_IT() APIs):
27 (+++) Configure the USARTx interrupt priority.
28 (+++) Enable the NVIC USART IRQ handle.
29 (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
30 and HAL_IRDA_Receive_DMA() APIs):
31 (+++) Declare a DMA handle structure for the Tx/Rx stream.
32 (+++) Enable the DMAx interface clock.
33 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
34 (+++) Configure the DMA Tx/Rx Stream.
35 (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
36 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
37
38 (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
39 and Mode(Receiver/Transmitter) in the hirda Init structure.
40
41 (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
42 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
43 by calling the customized HAL_IRDA_MspInit() API.
44 -@@- The specific IRDA interrupts (Transmission complete interrupt,
45 RXNE interrupt and Error Interrupts) will be managed using the macros
46 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
47
48 (#) Three operation modes are available within this driver :
49
50 *** Polling mode IO operation ***
51 =================================
52 [..]
53 (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
54 (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
55
56 *** Interrupt mode IO operation ***
57 ===================================
58 [..]
59 (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
60 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
61 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
62 (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
63 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
65 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
66 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
67
68 *** DMA mode IO operation ***
69 =============================
70 [..]
71 (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
72 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
73 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
74 (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
75 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
76 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
77 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
78 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
79
80 *** IRDA HAL driver macros list ***
81 ===================================
82 [..]
83 Below the list of most used macros in IRDA HAL driver.
84
85 (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
86 (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
87 (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not
88 (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag
89 (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt
90 (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt
91
92 [..]
93 (@) You can refer to the IRDA HAL driver header file for more useful macros
94
95 @endverbatim
96 ******************************************************************************
97 * @attention
98 *
99 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
100 *
101 * Redistribution and use in source and binary forms, with or without modification,
102 * are permitted provided that the following conditions are met:
103 * 1. Redistributions of source code must retain the above copyright notice,
104 * this list of conditions and the following disclaimer.
105 * 2. Redistributions in binary form must reproduce the above copyright notice,
106 * this list of conditions and the following disclaimer in the documentation
107 * and/or other materials provided with the distribution.
108 * 3. Neither the name of STMicroelectronics nor the names of its contributors
109 * may be used to endorse or promote products derived from this software
110 * without specific prior written permission.
111 *
112 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
113 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
114 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
115 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
116 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
117 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
118 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
119 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
120 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
121 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122 *
123 ******************************************************************************
124 */
125
126 /* Includes ------------------------------------------------------------------*/
127 #include "stm32f4xx_hal.h"
128
129 /** @addtogroup STM32F4xx_HAL_Driver
130 * @{
131 */
132
133 /** @defgroup IRDA IRDA
134 * @brief HAL IRDA module driver
135 * @{
136 */
137
138 #ifdef HAL_IRDA_MODULE_ENABLED
139
140 /* Private typedef -----------------------------------------------------------*/
141 /* Private define ------------------------------------------------------------*/
142 /** @addtogroup IRDA_Private_Constants
143 * @{
144 */
145 /**
146 * @}
147 */
148 /* Private macro -------------------------------------------------------------*/
149 /* Private variables ---------------------------------------------------------*/
150 /* Private function prototypes -----------------------------------------------*/
151 /** @addtogroup IRDA_Private_Functions
152 * @{
153 */
154 static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
155 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
156 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
157 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
158 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
159 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
160 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
161 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
162 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
163 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
164 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
165 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
166 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
167 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
168 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart,uint32_t Timeout);
169 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
170 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
171 /**
172 * @}
173 */
174 /* Exported functions --------------------------------------------------------*/
175 /** @defgroup IRDA_Exported_Functions IrDA Exported Functions
176 * @{
177 */
178
179 /** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
180 * @brief Initialization and Configuration functions
181 *
182 @verbatim
183
184 ===============================================================================
185 ##### Initialization and Configuration functions #####
186 ===============================================================================
187 [..]
188 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
189 in IrDA mode.
190 (+) For the asynchronous mode only these parameters can be configured:
191 (++) BaudRate
192 (++) WordLength
193 (++) Parity: If the parity is enabled, then the MSB bit of the data written
194 in the data register is transmitted but is changed by the parity bit.
195 Depending on the frame length defined by the M bit (8-bits or 9-bits),
196 please refer to Reference manual for possible IRDA frame formats.
197 (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
198 not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
199 specification specifies a minimum of 10 ms delay between transmission and
200 reception (IrDA is a half duplex protocol).
201 (++) Mode: Receiver/transmitter modes
202 (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
203 [..]
204 The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
205 are available in reference manual).
206
207 @endverbatim
208 * @{
209 */
210
211 /**
212 * @brief Initializes the IRDA mode according to the specified
213 * parameters in the IRDA_InitTypeDef and create the associated handle.
214 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
215 * the configuration information for the specified IRDA module.
216 * @retval HAL status
217 */
218 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
219 {
220 /* Check the IRDA handle allocation */
221 if(hirda == NULL)
222 {
223 return HAL_ERROR;
224 }
225
226 /* Check the IRDA instance parameters */
227 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
228 /* Check the IRDA mode parameter in the IRDA handle */
229 assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
230
231 if(hirda->gState == HAL_IRDA_STATE_RESET)
232 {
233 /* Allocate lock resource and initialize it */
234 hirda->Lock = HAL_UNLOCKED;
235 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
236 HAL_IRDA_MspInit(hirda);
237 }
238
239 hirda->gState = HAL_IRDA_STATE_BUSY;
240
241 /* Disable the IRDA peripheral */
242 __HAL_IRDA_DISABLE(hirda);
243
244 /* Set the IRDA communication parameters */
245 IRDA_SetConfig(hirda);
246
247 /* In IrDA mode, the following bits must be kept cleared:
248 - LINEN, STOP and CLKEN bits in the USART_CR2 register,
249 - SCEN and HDSEL bits in the USART_CR3 register.*/
250 CLEAR_BIT(hirda->Instance->CR2, USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN);
251 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_SCEN | USART_CR3_HDSEL);
252
253 /* Enable the IRDA peripheral */
254 __HAL_IRDA_ENABLE(hirda);
255
256 /* Set the prescaler */
257 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
258
259 /* Configure the IrDA mode */
260 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
261
262 /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
263 SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
264
265 /* Initialize the IRDA state*/
266 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
267 hirda->gState= HAL_IRDA_STATE_READY;
268 hirda->RxState= HAL_IRDA_STATE_READY;
269
270 return HAL_OK;
271 }
272
273 /**
274 * @brief DeInitializes the IRDA peripheral
275 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
276 * the configuration information for the specified IRDA module.
277 * @retval HAL status
278 */
279 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
280 {
281 /* Check the IRDA handle allocation */
282 if(hirda == NULL)
283 {
284 return HAL_ERROR;
285 }
286
287 /* Check the parameters */
288 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
289
290 hirda->gState = HAL_IRDA_STATE_BUSY;
291
292 /* Disable the Peripheral */
293 __HAL_IRDA_DISABLE(hirda);
294
295 /* DeInit the low level hardware */
296 HAL_IRDA_MspDeInit(hirda);
297
298 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
299
300 hirda->gState = HAL_IRDA_STATE_RESET;
301 hirda->RxState = HAL_IRDA_STATE_RESET;
302
303 /* Release Lock */
304 __HAL_UNLOCK(hirda);
305
306 return HAL_OK;
307 }
308
309 /**
310 * @brief IRDA MSP Init.
311 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
312 * the configuration information for the specified IRDA module.
313 * @retval None
314 */
315 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
316 {
317 /* Prevent unused argument(s) compilation warning */
318 UNUSED(hirda);
319 /* NOTE : This function Should not be modified, when the callback is needed,
320 the HAL_IRDA_MspInit could be implemented in the user file
321 */
322 }
323
324 /**
325 * @brief IRDA MSP DeInit.
326 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
327 * the configuration information for the specified IRDA module.
328 * @retval None
329 */
330 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
331 {
332 /* Prevent unused argument(s) compilation warning */
333 UNUSED(hirda);
334 /* NOTE : This function Should not be modified, when the callback is needed,
335 the HAL_IRDA_MspDeInit could be implemented in the user file
336 */
337 }
338
339 /**
340 * @}
341 */
342
343 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
344 * @brief IRDA Transmit/Receive functions
345 *
346 @verbatim
347 ===============================================================================
348 ##### IO operation functions #####
349 ===============================================================================
350 This subsection provides a set of functions allowing to manage the IRDA data transfers.
351 [..]
352 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
353 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
354 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
355 While receiving data, transmission should be avoided as the data to be transmitted
356 could be corrupted.
357
358 (#) There are two modes of transfer:
359 (++) Blocking mode: The communication is performed in polling mode.
360 The HAL status of all data processing is returned by the same function
361 after finishing transfer.
362 (++) No-Blocking mode: The communication is performed using Interrupts
363 or DMA, These APIs return the HAL status.
364 The end of the data processing will be indicated through the
365 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
366 using DMA mode.
367 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
368 will be executed respectively at the end of the transmit or Receive process
369 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
370
371 (#) Blocking mode API's are :
372 (++) HAL_IRDA_Transmit()
373 (++) HAL_IRDA_Receive()
374
375 (#) Non Blocking mode APIs with Interrupt are :
376 (++) HAL_IRDA_Transmit_IT()
377 (++) HAL_IRDA_Receive_IT()
378 (++) HAL_IRDA_IRQHandler()
379
380 (#) Non Blocking mode functions with DMA are :
381 (++) HAL_IRDA_Transmit_DMA()
382 (++) HAL_IRDA_Receive_DMA()
383
384 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
385 (++) HAL_IRDA_TxCpltCallback()
386 (++) HAL_IRDA_RxCpltCallback()
387 (++) HAL_IRDA_ErrorCallback()
388
389 @endverbatim
390 * @{
391 */
392
393 /**
394 * @brief Sends an amount of data in blocking mode.
395 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
396 * the configuration information for the specified IRDA module.
397 * @param pData Pointer to data buffer
398 * @param Size Amount of data to be sent
399 * @param Timeout Specify timeout value
400 * @retval HAL status
401 */
402 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
403 {
404 uint16_t* tmp;
405 uint32_t tickstart = 0U;
406
407 /* Check that a Tx process is not already ongoing */
408 if(hirda->gState == HAL_IRDA_STATE_READY)
409 {
410 if((pData == NULL) || (Size == 0))
411 {
412 return HAL_ERROR;
413 }
414
415 /* Process Locked */
416 __HAL_LOCK(hirda);
417
418 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
419 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
420
421 /* Init tickstart for timeout managment*/
422 tickstart = HAL_GetTick();
423
424 hirda->TxXferSize = Size;
425 hirda->TxXferCount = Size;
426 while(hirda->TxXferCount > 0U)
427 {
428 hirda->TxXferCount--;
429 if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
430 {
431 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
432 {
433 return HAL_TIMEOUT;
434 }
435 tmp = (uint16_t*) pData;
436 hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
437 if(hirda->Init.Parity == IRDA_PARITY_NONE)
438 {
439 pData +=2;
440 }
441 else
442 {
443 pData +=1;
444 }
445 }
446 else
447 {
448 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
449 {
450 return HAL_TIMEOUT;
451 }
452 hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
453 }
454 }
455
456 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
457 {
458 return HAL_TIMEOUT;
459 }
460
461 /* At end of Tx process, restore hirda->gState to Ready */
462 hirda->gState = HAL_IRDA_STATE_READY;
463
464 /* Process Unlocked */
465 __HAL_UNLOCK(hirda);
466
467 return HAL_OK;
468 }
469 else
470 {
471 return HAL_BUSY;
472 }
473 }
474
475 /**
476 * @brief Receive an amount of data in blocking mode.
477 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
478 * the configuration information for the specified IRDA module.
479 * @param pData Pointer to data buffer
480 * @param Size Amount of data to be received
481 * @param Timeout Specify timeout value
482 * @retval HAL status
483 */
484 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
485 {
486 uint16_t* tmp;
487 uint32_t tickstart = 0U;
488
489 /* Check that a Rx process is not already ongoing */
490 if(hirda->RxState == HAL_IRDA_STATE_READY)
491 {
492 if((pData == NULL) || (Size == 0))
493 {
494 return HAL_ERROR;
495 }
496
497 /* Process Locked */
498 __HAL_LOCK(hirda);
499
500 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
501 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
502
503 /* Init tickstart for timeout managment*/
504 tickstart = HAL_GetTick();
505
506 hirda->RxXferSize = Size;
507 hirda->RxXferCount = Size;
508 /* Check the remain data to be received */
509 while(hirda->RxXferCount > 0U)
510 {
511 hirda->RxXferCount--;
512 if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
513 {
514 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
515 {
516 return HAL_TIMEOUT;
517 }
518 tmp = (uint16_t*) pData ;
519 if(hirda->Init.Parity == IRDA_PARITY_NONE)
520 {
521 *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
522 pData +=2;
523 }
524 else
525 {
526 *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
527 pData +=1;
528 }
529 }
530 else
531 {
532 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
533 {
534 return HAL_TIMEOUT;
535 }
536 if(hirda->Init.Parity == IRDA_PARITY_NONE)
537 {
538 *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
539 }
540 else
541 {
542 *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
543 }
544 }
545 }
546
547 /* At end of Rx process, restore hirda->RxState to Ready */
548 hirda->RxState = HAL_IRDA_STATE_READY;
549
550 /* Process Unlocked */
551 __HAL_UNLOCK(hirda);
552
553 return HAL_OK;
554 }
555 else
556 {
557 return HAL_BUSY;
558 }
559 }
560
561 /**
562 * @brief Send an amount of data in non blocking mode.
563 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
564 * the configuration information for the specified IRDA module.
565 * @param pData Pointer to data buffer
566 * @param Size Amount of data to be sent
567 * @retval HAL status
568 */
569 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
570 {
571 /* Check that a Tx process is not already ongoing */
572 if(hirda->gState == HAL_IRDA_STATE_READY)
573 {
574 if((pData == NULL) || (Size == 0))
575 {
576 return HAL_ERROR;
577 }
578 /* Process Locked */
579 __HAL_LOCK(hirda);
580
581 hirda->pTxBuffPtr = pData;
582 hirda->TxXferSize = Size;
583 hirda->TxXferCount = Size;
584 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
585 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
586
587 /* Process Unlocked */
588 __HAL_UNLOCK(hirda);
589
590 /* Enable the IRDA Transmit Data Register Empty Interrupt */
591 SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
592
593 return HAL_OK;
594 }
595 else
596 {
597 return HAL_BUSY;
598 }
599 }
600
601 /**
602 * @brief Receives an amount of data in non blocking mode.
603 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
604 * the configuration information for the specified IRDA module.
605 * @param pData Pointer to data buffer
606 * @param Size Amount of data to be received
607 * @retval HAL status
608 */
609 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
610 {
611 /* Check that a Rx process is not already ongoing */
612 if(hirda->RxState == HAL_IRDA_STATE_READY)
613 {
614 if((pData == NULL) || (Size == 0))
615 {
616 return HAL_ERROR;
617 }
618
619 /* Process Locked */
620 __HAL_LOCK(hirda);
621
622 hirda->pRxBuffPtr = pData;
623 hirda->RxXferSize = Size;
624 hirda->RxXferCount = Size;
625 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
626 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
627
628 /* Process Unlocked */
629 __HAL_UNLOCK(hirda);
630
631 /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
632 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE);
633
634 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
635 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
636
637 return HAL_OK;
638 }
639 else
640 {
641 return HAL_BUSY;
642 }
643 }
644
645 /**
646 * @brief Sends an amount of data in non blocking mode.
647 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
648 * the configuration information for the specified IRDA module.
649 * @param pData Pointer to data buffer
650 * @param Size Amount of data to be sent
651 * @retval HAL status
652 */
653 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
654 {
655 uint32_t *tmp;
656
657 /* Check that a Tx process is not already ongoing */
658 if(hirda->gState == HAL_IRDA_STATE_READY)
659 {
660 if((pData == NULL) || (Size == 0))
661 {
662 return HAL_ERROR;
663 }
664
665 /* Process Locked */
666 __HAL_LOCK(hirda);
667
668 hirda->pTxBuffPtr = pData;
669 hirda->TxXferSize = Size;
670 hirda->TxXferCount = Size;
671 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
672 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
673
674 /* Set the IRDA DMA transfer complete callback */
675 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
676
677 /* Set the IRDA DMA half transfer complete callback */
678 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
679
680 /* Set the DMA error callback */
681 hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
682
683 /* Set the DMA abort callback */
684 hirda->hdmatx->XferAbortCallback = NULL;
685
686 /* Enable the IRDA transmit DMA Stream */
687 tmp = (uint32_t*)&pData;
688 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size);
689
690 /* Clear the TC flag in the SR register by writing 0 to it */
691 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
692
693 /* Process Unlocked */
694 __HAL_UNLOCK(hirda);
695
696 /* Enable the DMA transfer for transmit request by setting the DMAT bit
697 in the USART CR3 register */
698 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
699
700 return HAL_OK;
701 }
702 else
703 {
704 return HAL_BUSY;
705 }
706 }
707
708 /**
709 * @brief Receives an amount of data in non blocking mode.
710 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
711 * the configuration information for the specified IRDA module.
712 * @param pData Pointer to data buffer
713 * @param Size Amount of data to be received
714 * @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
715 * @retval HAL status
716 */
717 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
718 {
719 uint32_t *tmp;
720
721 /* Check that a Rx process is not already ongoing */
722 if(hirda->RxState == HAL_IRDA_STATE_READY)
723 {
724 if((pData == NULL) || (Size == 0))
725 {
726 return HAL_ERROR;
727 }
728
729 /* Process Locked */
730 __HAL_LOCK(hirda);
731
732 hirda->pRxBuffPtr = pData;
733 hirda->RxXferSize = Size;
734 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
735 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
736
737 /* Set the IRDA DMA transfer complete callback */
738 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
739
740 /* Set the IRDA DMA half transfer complete callback */
741 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
742
743 /* Set the DMA error callback */
744 hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
745
746 /* Set the DMA abort callback */
747 hirda->hdmarx->XferAbortCallback = NULL;
748
749 /* Enable the DMA Stream */
750 tmp = (uint32_t*)&pData;
751 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size);
752
753 /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
754 __HAL_IRDA_CLEAR_OREFLAG(hirda);
755
756 /* Process Unlocked */
757 __HAL_UNLOCK(hirda);
758
759 /* Enable the IRDA Parity Error Interrupt */
760 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
761
762 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
763 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
764
765 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
766 in the USART CR3 register */
767 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
768
769 return HAL_OK;
770 }
771 else
772 {
773 return HAL_BUSY;
774 }
775 }
776
777 /**
778 * @brief Pauses the DMA Transfer.
779 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
780 * the configuration information for the specified IRDA module.
781 * @retval HAL status
782 */
783 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
784 {
785 uint32_t dmarequest = 0x00U;
786
787 /* Process Locked */
788 __HAL_LOCK(hirda);
789
790 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
791 if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
792 {
793 /* Disable the IRDA DMA Tx request */
794 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
795 }
796
797 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
798 if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
799 {
800 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
801 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
802 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
803
804 /* Disable the IRDA DMA Rx request */
805 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
806 }
807
808 /* Process Unlocked */
809 __HAL_UNLOCK(hirda);
810
811 return HAL_OK;
812 }
813
814 /**
815 * @brief Resumes the DMA Transfer.
816 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
817 * the configuration information for the specified IRDA module.
818 * @retval HAL status
819 */
820 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
821 {
822 /* Process Locked */
823 __HAL_LOCK(hirda);
824
825 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
826 {
827 /* Enable the IRDA DMA Tx request */
828 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
829 }
830 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
831 {
832 /* Clear the Overrun flag before resuming the Rx transfer */
833 __HAL_IRDA_CLEAR_OREFLAG(hirda);
834
835 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
836 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
837 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
838
839 /* Enable the IRDA DMA Rx request */
840 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
841 }
842
843 /* Process Unlocked */
844 __HAL_UNLOCK(hirda);
845
846 return HAL_OK;
847 }
848
849 /**
850 * @brief Stops the DMA Transfer.
851 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
852 * the configuration information for the specified IRDA module.
853 * @retval HAL status
854 */
855 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
856 {
857 uint32_t dmarequest = 0x00U;
858 /* The Lock is not implemented on this API to allow the user application
859 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
860 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
861 and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
862 */
863
864 /* Stop IRDA DMA Tx request if ongoing */
865 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
866 if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
867 {
868 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
869
870 /* Abort the IRDA DMA Tx channel */
871 if(hirda->hdmatx != NULL)
872 {
873 HAL_DMA_Abort(hirda->hdmatx);
874 }
875 IRDA_EndTxTransfer(hirda);
876 }
877
878 /* Stop IRDA DMA Rx request if ongoing */
879 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
880 if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
881 {
882 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
883
884 /* Abort the IRDA DMA Rx channel */
885 if(hirda->hdmarx != NULL)
886 {
887 HAL_DMA_Abort(hirda->hdmarx);
888 }
889 IRDA_EndRxTransfer(hirda);
890 }
891 return HAL_OK;
892 }
893
894 /**
895 * @brief Abort ongoing transfers (blocking mode).
896 * @param hirda IRDA handle.
897 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
898 * This procedure performs following operations :
899 * - Disable PPP Interrupts
900 * - Disable the DMA transfer in the peripheral register (if enabled)
901 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
902 * - Set handle State to READY
903 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
904 * @retval HAL status
905 */
906 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
907 {
908 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
909 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
910 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
911
912 /* Disable the IRDA DMA Tx request if enabled */
913 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
914 {
915 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
916
917 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
918 if(hirda->hdmatx != NULL)
919 {
920 /* Set the IRDA DMA Abort callback to Null.
921 No call back execution at end of DMA abort procedure */
922 hirda->hdmatx->XferAbortCallback = NULL;
923
924 HAL_DMA_Abort(hirda->hdmatx);
925 }
926 }
927
928 /* Disable the IRDA DMA Rx request if enabled */
929 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
930 {
931 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
932
933 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
934 if(hirda->hdmarx != NULL)
935 {
936 /* Set the IRDA DMA Abort callback to Null.
937 No call back execution at end of DMA abort procedure */
938 hirda->hdmarx->XferAbortCallback = NULL;
939
940 HAL_DMA_Abort(hirda->hdmarx);
941 }
942 }
943
944 /* Reset Tx and Rx transfer counters */
945 hirda->TxXferCount = 0x00U;
946 hirda->RxXferCount = 0x00U;
947
948 /* Reset ErrorCode */
949 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
950
951 /* Restore hirda->RxState and hirda->gState to Ready */
952 hirda->RxState = HAL_IRDA_STATE_READY;
953 hirda->gState = HAL_IRDA_STATE_READY;
954
955 return HAL_OK;
956 }
957
958 /**
959 * @brief Abort ongoing Transmit transfer (blocking mode).
960 * @param hirda IRDA handle.
961 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
962 * This procedure performs following operations :
963 * - Disable PPP Interrupts
964 * - Disable the DMA transfer in the peripheral register (if enabled)
965 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
966 * - Set handle State to READY
967 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
968 * @retval HAL status
969 */
970 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
971 {
972 /* Disable TXEIE and TCIE interrupts */
973 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
974
975 /* Disable the IRDA DMA Tx request if enabled */
976 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
977 {
978 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
979
980 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
981 if(hirda->hdmatx != NULL)
982 {
983 /* Set the IRDA DMA Abort callback to Null.
984 No call back execution at end of DMA abort procedure */
985 hirda->hdmatx->XferAbortCallback = NULL;
986
987 HAL_DMA_Abort(hirda->hdmatx);
988 }
989 }
990
991 /* Reset Tx transfer counter */
992 hirda->TxXferCount = 0x00U;
993
994 /* Restore hirda->gState to Ready */
995 hirda->gState = HAL_IRDA_STATE_READY;
996
997 return HAL_OK;
998 }
999
1000 /**
1001 * @brief Abort ongoing Receive transfer (blocking mode).
1002 * @param hirda IRDA handle.
1003 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1004 * This procedure performs following operations :
1005 * - Disable PPP Interrupts
1006 * - Disable the DMA transfer in the peripheral register (if enabled)
1007 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1008 * - Set handle State to READY
1009 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1010 * @retval HAL status
1011 */
1012 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
1013 {
1014 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1015 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1016 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1017
1018 /* Disable the IRDA DMA Rx request if enabled */
1019 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1020 {
1021 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1022
1023 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1024 if(hirda->hdmarx != NULL)
1025 {
1026 /* Set the IRDA DMA Abort callback to Null.
1027 No call back execution at end of DMA abort procedure */
1028 hirda->hdmarx->XferAbortCallback = NULL;
1029
1030 HAL_DMA_Abort(hirda->hdmarx);
1031 }
1032 }
1033
1034 /* Reset Rx transfer counter */
1035 hirda->RxXferCount = 0x00U;
1036
1037 /* Restore hirda->RxState to Ready */
1038 hirda->RxState = HAL_IRDA_STATE_READY;
1039
1040 return HAL_OK;
1041 }
1042
1043 /**
1044 * @brief Abort ongoing transfers (Interrupt mode).
1045 * @param hirda IRDA handle.
1046 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1047 * This procedure performs following operations :
1048 * - Disable PPP Interrupts
1049 * - Disable the DMA transfer in the peripheral register (if enabled)
1050 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1051 * - Set handle State to READY
1052 * - At abort completion, call user abort complete callback
1053 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1054 * considered as completed only when user abort complete callback is executed (not when exiting function).
1055 * @retval HAL status
1056 */
1057 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
1058 {
1059 uint32_t AbortCplt = 1U;
1060
1061 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1062 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1063 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1064
1065 /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
1066 before any call to DMA Abort functions */
1067 /* DMA Tx Handle is valid */
1068 if(hirda->hdmatx != NULL)
1069 {
1070 /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
1071 Otherwise, set it to NULL */
1072 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1073 {
1074 hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
1075 }
1076 else
1077 {
1078 hirda->hdmatx->XferAbortCallback = NULL;
1079 }
1080 }
1081 /* DMA Rx Handle is valid */
1082 if(hirda->hdmarx != NULL)
1083 {
1084 /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
1085 Otherwise, set it to NULL */
1086 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1087 {
1088 hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
1089 }
1090 else
1091 {
1092 hirda->hdmarx->XferAbortCallback = NULL;
1093 }
1094 }
1095
1096 /* Disable the IRDA DMA Tx request if enabled */
1097 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1098 {
1099 /* Disable DMA Tx at IRDA level */
1100 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1101
1102 /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1103 if(hirda->hdmatx != NULL)
1104 {
1105 /* IRDA Tx DMA Abort callback has already been initialised :
1106 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1107
1108 /* Abort DMA TX */
1109 if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1110 {
1111 hirda->hdmatx->XferAbortCallback = NULL;
1112 }
1113 else
1114 {
1115 AbortCplt = 0x00U;
1116 }
1117 }
1118 }
1119
1120 /* Disable the IRDA DMA Rx request if enabled */
1121 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1122 {
1123 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1124
1125 /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1126 if(hirda->hdmarx != NULL)
1127 {
1128 /* IRDA Rx DMA Abort callback has already been initialised :
1129 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1130
1131 /* Abort DMA RX */
1132 if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1133 {
1134 hirda->hdmarx->XferAbortCallback = NULL;
1135 AbortCplt = 0x01U;
1136 }
1137 else
1138 {
1139 AbortCplt = 0x00U;
1140 }
1141 }
1142 }
1143
1144 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1145 if(AbortCplt == 0x01U)
1146 {
1147 /* Reset Tx and Rx transfer counters */
1148 hirda->TxXferCount = 0x00U;
1149 hirda->RxXferCount = 0x00U;
1150
1151 /* Reset ErrorCode */
1152 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1153
1154 /* Restore hirda->gState and hirda->RxState to Ready */
1155 hirda->gState = HAL_IRDA_STATE_READY;
1156 hirda->RxState = HAL_IRDA_STATE_READY;
1157
1158 /* As no DMA to be aborted, call directly user Abort complete callback */
1159 HAL_IRDA_AbortCpltCallback(hirda);
1160 }
1161
1162 return HAL_OK;
1163 }
1164
1165 /**
1166 * @brief Abort ongoing Transmit transfer (Interrupt mode).
1167 * @param hirda IRDA handle.
1168 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1169 * This procedure performs following operations :
1170 * - Disable PPP Interrupts
1171 * - Disable the DMA transfer in the peripheral register (if enabled)
1172 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1173 * - Set handle State to READY
1174 * - At abort completion, call user abort complete callback
1175 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1176 * considered as completed only when user abort complete callback is executed (not when exiting function).
1177 * @retval HAL status
1178 */
1179 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
1180 {
1181 /* Disable TXEIE and TCIE interrupts */
1182 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1183
1184 /* Disable the IRDA DMA Tx request if enabled */
1185 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1186 {
1187 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1188
1189 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1190 if(hirda->hdmatx != NULL)
1191 {
1192 /* Set the IRDA DMA Abort callback :
1193 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1194 hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
1195
1196 /* Abort DMA TX */
1197 if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1198 {
1199 /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
1200 hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
1201 }
1202 }
1203 else
1204 {
1205 /* Reset Tx transfer counter */
1206 hirda->TxXferCount = 0x00U;
1207
1208 /* Restore hirda->gState to Ready */
1209 hirda->gState = HAL_IRDA_STATE_READY;
1210
1211 /* As no DMA to be aborted, call directly user Abort complete callback */
1212 HAL_IRDA_AbortTransmitCpltCallback(hirda);
1213 }
1214 }
1215 else
1216 {
1217 /* Reset Tx transfer counter */
1218 hirda->TxXferCount = 0x00U;
1219
1220 /* Restore hirda->gState to Ready */
1221 hirda->gState = HAL_IRDA_STATE_READY;
1222
1223 /* As no DMA to be aborted, call directly user Abort complete callback */
1224 HAL_IRDA_AbortTransmitCpltCallback(hirda);
1225 }
1226
1227 return HAL_OK;
1228 }
1229
1230 /**
1231 * @brief Abort ongoing Receive transfer (Interrupt mode).
1232 * @param hirda IRDA handle.
1233 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1234 * This procedure performs following operations :
1235 * - Disable PPP Interrupts
1236 * - Disable the DMA transfer in the peripheral register (if enabled)
1237 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1238 * - Set handle State to READY
1239 * - At abort completion, call user abort complete callback
1240 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1241 * considered as completed only when user abort complete callback is executed (not when exiting function).
1242 * @retval HAL status
1243 */
1244 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
1245 {
1246 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1247 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1248 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1249
1250 /* Disable the IRDA DMA Rx request if enabled */
1251 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1252 {
1253 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1254
1255 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1256 if(hirda->hdmarx != NULL)
1257 {
1258 /* Set the IRDA DMA Abort callback :
1259 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1260 hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
1261
1262 /* Abort DMA RX */
1263 if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1264 {
1265 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1266 hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1267 }
1268 }
1269 else
1270 {
1271 /* Reset Rx transfer counter */
1272 hirda->RxXferCount = 0x00U;
1273
1274 /* Restore hirda->RxState to Ready */
1275 hirda->RxState = HAL_IRDA_STATE_READY;
1276
1277 /* As no DMA to be aborted, call directly user Abort complete callback */
1278 HAL_IRDA_AbortReceiveCpltCallback(hirda);
1279 }
1280 }
1281 else
1282 {
1283 /* Reset Rx transfer counter */
1284 hirda->RxXferCount = 0x00U;
1285
1286 /* Restore hirda->RxState to Ready */
1287 hirda->RxState = HAL_IRDA_STATE_READY;
1288
1289 /* As no DMA to be aborted, call directly user Abort complete callback */
1290 HAL_IRDA_AbortReceiveCpltCallback(hirda);
1291 }
1292
1293 return HAL_OK;
1294 }
1295
1296 /**
1297 * @brief This function handles IRDA interrupt request.
1298 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1299 * the configuration information for the specified IRDA module.
1300 * @retval None
1301 */
1302 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
1303 {
1304 uint32_t isrflags = READ_REG(hirda->Instance->SR);
1305 uint32_t cr1its = READ_REG(hirda->Instance->CR1);
1306 uint32_t cr3its = READ_REG(hirda->Instance->CR3);
1307 uint32_t errorflags = 0x00U;
1308 uint32_t dmarequest = 0x00U;
1309
1310 /* If no error occurs */
1311 errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
1312 if(errorflags == RESET)
1313 {
1314 /* IRDA in mode Receiver -----------------------------------------------*/
1315 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1316 {
1317 IRDA_Receive_IT(hirda);
1318 return;
1319 }
1320 }
1321
1322 /* If some errors occur */
1323 if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
1324 {
1325 /* IRDA parity error interrupt occurred -------------------------------*/
1326 if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
1327 {
1328 hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
1329 }
1330
1331 /* IRDA noise error interrupt occurred --------------------------------*/
1332 if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1333 {
1334 hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
1335 }
1336
1337 /* IRDA frame error interrupt occurred --------------------------------*/
1338 if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1339 {
1340 hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
1341 }
1342
1343 /* IRDA Over-Run interrupt occurred -----------------------------------*/
1344 if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1345 {
1346 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
1347 }
1348 /* Call IRDA Error Call back function if need be -----------------------*/
1349 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
1350 {
1351 /* IRDA in mode Receiver ---------------------------------------------*/
1352 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1353 {
1354 IRDA_Receive_IT(hirda);
1355 }
1356
1357 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
1358 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1359 consider error as blocking */
1360 if(((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
1361 {
1362 /* Blocking error : transfer is aborted
1363 Set the IRDA state ready to be able to start again the process,
1364 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1365 IRDA_EndRxTransfer(hirda);
1366
1367 /* Disable the IRDA DMA Rx request if enabled */
1368 if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1369 {
1370 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1371
1372 /* Abort the IRDA DMA Rx channel */
1373 if(hirda->hdmarx != NULL)
1374 {
1375 /* Set the IRDA DMA Abort callback :
1376 will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
1377 hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
1378
1379 if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1380 {
1381 /* Call Directly XferAbortCallback function in case of error */
1382 hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1383 }
1384 }
1385 else
1386 {
1387 /* Call user error callback */
1388 HAL_IRDA_ErrorCallback(hirda);
1389 }
1390 }
1391 else
1392 {
1393 /* Call user error callback */
1394 HAL_IRDA_ErrorCallback(hirda);
1395 }
1396 }
1397 else
1398 {
1399 /* Non Blocking error : transfer could go on.
1400 Error is notified to user through user error callback */
1401 HAL_IRDA_ErrorCallback(hirda);
1402 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1403 }
1404 }
1405 return;
1406 } /* End if some error occurs */
1407
1408 /* IRDA in mode Transmitter ------------------------------------------------*/
1409 if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
1410 {
1411 IRDA_Transmit_IT(hirda);
1412 return;
1413 }
1414
1415 /* IRDA in mode Transmitter end --------------------------------------------*/
1416 if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
1417 {
1418 IRDA_EndTransmit_IT(hirda);
1419 return;
1420 }
1421 }
1422
1423 /**
1424 * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
1425 * @param hirda IRDA handle.
1426 * @retval None
1427 */
1428 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
1429 {
1430 /* Disable TXEIE and TCIE interrupts */
1431 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1432
1433 /* At end of Tx process, restore hirda->gState to Ready */
1434 hirda->gState = HAL_IRDA_STATE_READY;
1435 }
1436
1437 /**
1438 * @brief End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
1439 * @param hirda IRDA handle.
1440 * @retval None
1441 */
1442 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
1443 {
1444 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1445 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1446 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1447
1448 /* At end of Rx process, restore hirda->RxState to Ready */
1449 hirda->RxState = HAL_IRDA_STATE_READY;
1450 }
1451
1452 /**
1453 * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error
1454 * (To be called at end of DMA Abort procedure following error occurrence).
1455 * @param hdma DMA handle.
1456 * @retval None
1457 */
1458 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1459 {
1460 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1461 hirda->RxXferCount = 0x00U;
1462 hirda->TxXferCount = 0x00U;
1463
1464 HAL_IRDA_ErrorCallback(hirda);
1465 }
1466
1467 /**
1468 * @brief DMA IRDA Tx communication abort callback, when initiated by user
1469 * (To be called at end of DMA Tx Abort procedure following user abort request).
1470 * @note When this callback is executed, User Abort complete call back is called only if no
1471 * Abort still ongoing for Rx DMA Handle.
1472 * @param hdma DMA handle.
1473 * @retval None
1474 */
1475 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
1476 {
1477 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1478
1479 hirda->hdmatx->XferAbortCallback = NULL;
1480
1481 /* Check if an Abort process is still ongoing */
1482 if(hirda->hdmarx != NULL)
1483 {
1484 if(hirda->hdmarx->XferAbortCallback != NULL)
1485 {
1486 return;
1487 }
1488 }
1489
1490 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
1491 hirda->TxXferCount = 0x00U;
1492 hirda->RxXferCount = 0x00U;
1493
1494 /* Reset ErrorCode */
1495 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1496
1497 /* Restore hirda->gState and hirda->RxState to Ready */
1498 hirda->gState = HAL_IRDA_STATE_READY;
1499 hirda->RxState = HAL_IRDA_STATE_READY;
1500
1501 /* Call user Abort complete callback */
1502 HAL_IRDA_AbortCpltCallback(hirda);
1503 }
1504
1505 /**
1506 * @brief DMA IRDA Rx communication abort callback, when initiated by user
1507 * (To be called at end of DMA Rx Abort procedure following user abort request).
1508 * @note When this callback is executed, User Abort complete call back is called only if no
1509 * Abort still ongoing for Tx DMA Handle.
1510 * @param hdma DMA handle.
1511 * @retval None
1512 */
1513 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
1514 {
1515 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1516
1517 hirda->hdmarx->XferAbortCallback = NULL;
1518
1519 /* Check if an Abort process is still ongoing */
1520 if(hirda->hdmatx != NULL)
1521 {
1522 if(hirda->hdmatx->XferAbortCallback != NULL)
1523 {
1524 return;
1525 }
1526 }
1527
1528 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
1529 hirda->TxXferCount = 0x00U;
1530 hirda->RxXferCount = 0x00U;
1531
1532 /* Reset ErrorCode */
1533 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1534
1535 /* Restore hirda->gState and hirda->RxState to Ready */
1536 hirda->gState = HAL_IRDA_STATE_READY;
1537 hirda->RxState = HAL_IRDA_STATE_READY;
1538
1539 /* Call user Abort complete callback */
1540 HAL_IRDA_AbortCpltCallback(hirda);
1541 }
1542
1543 /**
1544 * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to
1545 * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
1546 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
1547 * and leads to user Tx Abort Complete callback execution).
1548 * @param hdma DMA handle.
1549 * @retval None
1550 */
1551 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
1552 {
1553 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1554
1555 hirda->TxXferCount = 0x00U;
1556
1557 /* Restore hirda->gState to Ready */
1558 hirda->gState = HAL_IRDA_STATE_READY;
1559
1560 /* Call user Abort complete callback */
1561 HAL_IRDA_AbortTransmitCpltCallback(hirda);
1562 }
1563
1564 /**
1565 * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to
1566 * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
1567 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
1568 * and leads to user Rx Abort Complete callback execution).
1569 * @param hdma DMA handle.
1570 * @retval None
1571 */
1572 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
1573 {
1574 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1575
1576 hirda->RxXferCount = 0x00U;
1577
1578 /* Restore hirda->RxState to Ready */
1579 hirda->RxState = HAL_IRDA_STATE_READY;
1580
1581 /* Call user Abort complete callback */
1582 HAL_IRDA_AbortReceiveCpltCallback(hirda);
1583 }
1584
1585 /**
1586 * @brief Tx Transfer complete callbacks.
1587 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1588 * the configuration information for the specified IRDA module.
1589 * @retval None
1590 */
1591 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
1592 {
1593 /* Prevent unused argument(s) compilation warning */
1594 UNUSED(hirda);
1595 /* NOTE : This function Should not be modified, when the callback is needed,
1596 the HAL_IRDA_TxCpltCallback could be implemented in the user file
1597 */
1598 }
1599
1600 /**
1601 * @brief Tx Half Transfer completed callbacks.
1602 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1603 * the configuration information for the specified USART module.
1604 * @retval None
1605 */
1606 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1607 {
1608 /* Prevent unused argument(s) compilation warning */
1609 UNUSED(hirda);
1610 /* NOTE: This function Should not be modified, when the callback is needed,
1611 the HAL_IRDA_TxHalfCpltCallback could be implemented in the user file
1612 */
1613 }
1614
1615 /**
1616 * @brief Rx Transfer complete callbacks.
1617 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1618 * the configuration information for the specified IRDA module.
1619 * @retval None
1620 */
1621 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
1622 {
1623 /* Prevent unused argument(s) compilation warning */
1624 UNUSED(hirda);
1625 /* NOTE : This function Should not be modified, when the callback is needed,
1626 the HAL_IRDA_RxCpltCallback could be implemented in the user file
1627 */
1628 }
1629
1630 /**
1631 * @brief Rx Half Transfer complete callbacks.
1632 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1633 * the configuration information for the specified IRDA module.
1634 * @retval None
1635 */
1636 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1637 {
1638 /* Prevent unused argument(s) compilation warning */
1639 UNUSED(hirda);
1640 /* NOTE : This function Should not be modified, when the callback is needed,
1641 the HAL_IRDA_RxHalfCpltCallback could be implemented in the user file
1642 */
1643 }
1644
1645 /**
1646 * @brief IRDA error callbacks.
1647 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1648 * the configuration information for the specified IRDA module.
1649 * @retval None
1650 */
1651 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
1652 {
1653 /* Prevent unused argument(s) compilation warning */
1654 UNUSED(hirda);
1655 /* NOTE : This function Should not be modified, when the callback is needed,
1656 the HAL_IRDA_ErrorCallback could be implemented in the user file
1657 */
1658 }
1659
1660 /**
1661 * @brief IRDA Abort Complete callback.
1662 * @param hirda IRDA handle.
1663 * @retval None
1664 */
1665 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
1666 {
1667 /* Prevent unused argument(s) compilation warning */
1668 UNUSED(hirda);
1669
1670 /* NOTE : This function should not be modified, when the callback is needed,
1671 the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
1672 */
1673 }
1674
1675 /**
1676 * @brief IRDA Abort Transmit Complete callback.
1677 * @param hirda IRDA handle.
1678 * @retval None
1679 */
1680 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
1681 {
1682 /* Prevent unused argument(s) compilation warning */
1683 UNUSED(hirda);
1684
1685 /* NOTE : This function should not be modified, when the callback is needed,
1686 the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
1687 */
1688 }
1689
1690 /**
1691 * @brief IRDA Abort ReceiveComplete callback.
1692 * @param hirda IRDA handle.
1693 * @retval None
1694 */
1695 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
1696 {
1697 /* Prevent unused argument(s) compilation warning */
1698 UNUSED(hirda);
1699
1700 /* NOTE : This function should not be modified, when the callback is needed,
1701 the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
1702 */
1703 }
1704
1705 /**
1706 * @}
1707 */
1708
1709 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
1710 * @brief IRDA State and Errors functions
1711 *
1712 @verbatim
1713 ==============================================================================
1714 ##### Peripheral State and Errors functions #####
1715 ==============================================================================
1716 [..]
1717 This subsection provides a set of functions allowing to return the State of IrDA
1718 communication process and also return Peripheral Errors occurred during communication process
1719 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
1720 (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication.
1721
1722 @endverbatim
1723 * @{
1724 */
1725
1726 /**
1727 * @brief Returns the IRDA state.
1728 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1729 * the configuration information for the specified IRDA module.
1730 * @retval HAL state
1731 */
1732 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
1733 {
1734 uint32_t temp1 = 0x00U, temp2 = 0x00U;
1735 temp1 = hirda->gState;
1736 temp2 = hirda->RxState;
1737
1738 return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
1739 }
1740
1741 /**
1742 * @brief Return the IARDA error code
1743 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1744 * the configuration information for the specified IRDA.
1745 * @retval IRDA Error Code
1746 */
1747 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
1748 {
1749 return hirda->ErrorCode;
1750 }
1751
1752 /**
1753 * @}
1754 */
1755
1756 /**
1757 * @brief DMA IRDA transmit process complete callback.
1758 * @param hdma DMA handle
1759 * @retval None
1760 */
1761 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1762 {
1763 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1764 /* DMA Normal mode */
1765 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1766 {
1767 hirda->TxXferCount = 0U;
1768
1769 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1770 in the IRDA CR3 register */
1771 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1772
1773 /* Enable the IRDA Transmit Complete Interrupt */
1774 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1775 }
1776 /* DMA Circular mode */
1777 else
1778 {
1779 HAL_IRDA_TxCpltCallback(hirda);
1780 }
1781 }
1782
1783 /**
1784 * @brief DMA IRDA receive process half complete callback
1785 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1786 * the configuration information for the specified DMA module.
1787 * @retval None
1788 */
1789 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
1790 {
1791 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1792
1793 HAL_IRDA_TxHalfCpltCallback(hirda);
1794 }
1795
1796 /**
1797 * @brief DMA IRDA receive process complete callback.
1798 * @param hdma DMA handle
1799 * @retval None
1800 */
1801 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1802 {
1803 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1804 /* DMA Normal mode */
1805 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1806 {
1807 hirda->RxXferCount = 0U;
1808
1809 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1810 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1811 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1812
1813 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1814 in the IRDA CR3 register */
1815 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1816
1817 /* At end of Rx process, restore hirda->RxState to Ready */
1818 hirda->RxState = HAL_IRDA_STATE_READY;
1819 }
1820
1821 HAL_IRDA_RxCpltCallback(hirda);
1822 }
1823
1824 /**
1825 * @brief DMA IRDA receive process half complete callback
1826 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1827 * the configuration information for the specified DMA module.
1828 * @retval None
1829 */
1830 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
1831 {
1832 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1833 HAL_IRDA_RxHalfCpltCallback(hirda);
1834 }
1835
1836 /**
1837 * @brief DMA IRDA communication error callback.
1838 * @param hdma DMA handle
1839 * @retval None
1840 */
1841 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
1842 {
1843 uint32_t dmarequest = 0x00U;
1844 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1845
1846 /* Stop IRDA DMA Tx request if ongoing */
1847 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
1848 if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
1849 {
1850 hirda->TxXferCount = 0U;
1851 IRDA_EndTxTransfer(hirda);
1852 }
1853
1854 /* Stop IRDA DMA Rx request if ongoing */
1855 dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
1856 if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
1857 {
1858 hirda->RxXferCount = 0U;
1859 IRDA_EndRxTransfer(hirda);
1860 }
1861
1862 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
1863
1864 HAL_IRDA_ErrorCallback(hirda);
1865 }
1866
1867 /**
1868 * @brief This function handles IRDA Communication Timeout.
1869 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1870 * the configuration information for the specified IRDA module.
1871 * @param Flag specifies the IRDA flag to check.
1872 * @param Status The new Flag status (SET or RESET).
1873 * @param Tickstart Tick start value
1874 * @param Timeout Timeout duration
1875 * @retval HAL status
1876 */
1877 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
1878 {
1879 /* Wait until flag is set */
1880 while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
1881 {
1882 /* Check for the Timeout */
1883 if(Timeout != HAL_MAX_DELAY)
1884 {
1885 if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
1886 {
1887 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1888 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
1889 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1890
1891 hirda->gState = HAL_IRDA_STATE_READY;
1892 hirda->RxState = HAL_IRDA_STATE_READY;
1893
1894 /* Process Unlocked */
1895 __HAL_UNLOCK(hirda);
1896
1897 return HAL_TIMEOUT;
1898 }
1899 }
1900 }
1901 return HAL_OK;
1902 }
1903
1904 /**
1905 * @brief Send an amount of data in non blocking mode.
1906 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1907 * the configuration information for the specified IRDA module.
1908 * @retval HAL status
1909 */
1910 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
1911 {
1912 uint16_t* tmp;
1913
1914 /* Check that a Tx process is ongoing */
1915 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1916 {
1917 if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
1918 {
1919 tmp = (uint16_t*) hirda->pTxBuffPtr;
1920 hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
1921 if(hirda->Init.Parity == IRDA_PARITY_NONE)
1922 {
1923 hirda->pTxBuffPtr += 2U;
1924 }
1925 else
1926 {
1927 hirda->pTxBuffPtr += 1U;
1928 }
1929 }
1930 else
1931 {
1932 hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
1933 }
1934
1935 if(--hirda->TxXferCount == 0U)
1936 {
1937 /* Disable the IRDA Transmit Data Register Empty Interrupt */
1938 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
1939
1940 /* Enable the IRDA Transmit Complete Interrupt */
1941 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1942 }
1943
1944 return HAL_OK;
1945 }
1946 else
1947 {
1948 return HAL_BUSY;
1949 }
1950 }
1951
1952 /**
1953 * @brief Wraps up transmission in non blocking mode.
1954 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1955 * the configuration information for the specified IRDA module.
1956 * @retval HAL status
1957 */
1958 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
1959 {
1960 /* Disable the IRDA Transmit Complete Interrupt */
1961 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1962
1963 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1964 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1965
1966 /* Tx process is ended, restore hirda->gState to Ready */
1967 hirda->gState = HAL_IRDA_STATE_READY;
1968
1969 HAL_IRDA_TxCpltCallback(hirda);
1970
1971 return HAL_OK;
1972 }
1973
1974 /**
1975 * @brief Receives an amount of data in non blocking mode.
1976 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1977 * the configuration information for the specified IRDA module.
1978 * @retval HAL status
1979 */
1980 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
1981 {
1982 uint16_t* tmp;
1983 uint16_t uhdata;
1984
1985 /* Check that a Rx process is ongoing */
1986 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1987 {
1988 uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
1989 if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
1990 {
1991 tmp = (uint16_t*) hirda->pRxBuffPtr;
1992 if(hirda->Init.Parity == IRDA_PARITY_NONE)
1993 {
1994 *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
1995 hirda->pRxBuffPtr += 2U;
1996 }
1997 else
1998 {
1999 *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
2000 hirda->pRxBuffPtr += 1U;
2001 }
2002 }
2003 else
2004 {
2005 if(hirda->Init.Parity == IRDA_PARITY_NONE)
2006 {
2007 *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
2008 }
2009 else
2010 {
2011 *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
2012 }
2013 }
2014
2015 if(--hirda->RxXferCount == 0U)
2016 {
2017 /* Disable the IRDA Data Register not empty Interrupt */
2018 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
2019
2020 /* Disable the IRDA Parity Error Interrupt */
2021 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2022
2023 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2024 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2025
2026 /* Rx process is completed, restore hirda->RxState to Ready */
2027 hirda->RxState = HAL_IRDA_STATE_READY;
2028
2029 HAL_IRDA_RxCpltCallback(hirda);
2030
2031 return HAL_OK;
2032 }
2033 return HAL_OK;
2034 }
2035 else
2036 {
2037 return HAL_BUSY;
2038 }
2039 }
2040
2041 /**
2042 * @brief Configures the IRDA peripheral.
2043 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
2044 * the configuration information for the specified IRDA module.
2045 * @retval None
2046 */
2047 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
2048 {
2049 /* Check the parameters */
2050 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
2051 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2052 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2053 assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2054 assert_param(IS_IRDA_MODE(hirda->Init.Mode));
2055
2056 /*-------------------------- IRDA CR2 Configuration ------------------------*/
2057 /* Clear STOP[13:12] bits */
2058 CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
2059
2060 /*-------------------------- USART CR1 Configuration -----------------------*/
2061 /* Clear M, PCE, PS, TE and RE bits */
2062 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE);
2063
2064 /* Configure the USART Word Length, Parity and mode:
2065 Set the M bits according to hirda->Init.WordLength value
2066 Set PCE and PS bits according to hirda->Init.Parity value
2067 Set TE and RE bits according to hirda->Init.Mode value */
2068 /* Write to USART CR1 */
2069 SET_BIT(hirda->Instance->CR1, (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode);
2070
2071 /*-------------------------- USART CR3 Configuration -----------------------*/
2072 /* Clear CTSE and RTSE bits */
2073 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_RTSE | USART_CR3_CTSE);
2074
2075 /*-------------------------- USART BRR Configuration -----------------------*/
2076 #if defined(USART6)
2077 if((hirda->Instance == USART1) || (hirda->Instance == USART6))
2078 {
2079 SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
2080 }
2081 #else
2082 if(hirda->Instance == USART1)
2083 {
2084 SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
2085 }
2086 #endif /* USART6 */
2087 else
2088 {
2089 SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate));
2090 }
2091 }
2092
2093 /**
2094 * @}
2095 */
2096
2097 #endif /* HAL_IRDA_MODULE_ENABLED */
2098 /**
2099 * @}
2100 */
2101
2102 /**
2103 * @}
2104 */
2105
2106 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/