2 ******************************************************************************
3 * @file stm32f0xx_hal_irda.c
4 * @author MCD Application Team
6 * @date 11-December-2014
7 * @brief IRDA HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the IrDA (Infrared Data Association) Peripheral
11 * + Initialization and de-initialization function
12 * + IO operation function
13 * + Peripheral Control function
17 ===============================================================================
18 ##### How to use this driver #####
19 ===============================================================================
21 The IRDA HAL driver can be used as follows:
23 (#) Declare a IRDA_HandleTypeDef handle structure.
24 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
25 (##) Enable the USARTx interface clock.
26 (##) IRDA pins configuration:
27 (+++) Enable the clock for the IRDA GPIOs.
28 (+++) Configure these IRDA pins as alternate function pull-up.
29 (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
30 and HAL_IRDA_Receive_IT() APIs):
31 (+++) Configure the USARTx interrupt priority.
32 (+++) Enable the NVIC USART IRQ handle.
33 (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
34 and HAL_IRDA_Receive_DMA() APIs):
35 (+++) Declare a DMA handle structure for the Tx/Rx channel.
36 (+++) Enable the DMAx interface clock.
37 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
38 (+++) Configure the DMA Tx/Rx channel.
39 (+++) Associate the initilalized DMA handle to the IRDA DMA Tx/Rx handle.
40 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
42 (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
43 the normal or low power mode and the clock prescaler in the hirda Init structure.
45 (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
46 (++) This API configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
47 by calling the customed HAL_IRDA_MspInit() API.
49 -@@- The specific IRDA interrupts (Transmission complete interrupt,
50 RXNE interrupt and Error Interrupts) will be managed using the macros
51 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
53 (#) Three operation modes are available within this driver :
55 *** Polling mode IO operation ***
56 =================================
58 (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
59 (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
61 *** Interrupt mode IO operation ***
62 ===================================
64 (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
65 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
67 (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
68 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
69 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
70 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
71 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
73 *** DMA mode IO operation ***
74 ==============================
76 (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
77 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
79 (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
80 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
81 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
82 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
83 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
85 *** IRDA HAL driver macros list ***
86 ====================================
88 Below the list of most used macros in IRDA HAL driver.
90 (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
91 (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
92 (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
93 (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
94 (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
95 (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
98 (@) You can refer to the IRDA HAL driver header file for more useful macros
101 ******************************************************************************
104 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
106 * Redistribution and use in source and binary forms, with or without modification,
107 * are permitted provided that the following conditions are met:
108 * 1. Redistributions of source code must retain the above copyright notice,
109 * this list of conditions and the following disclaimer.
110 * 2. Redistributions in binary form must reproduce the above copyright notice,
111 * this list of conditions and the following disclaimer in the documentation
112 * and/or other materials provided with the distribution.
113 * 3. Neither the name of STMicroelectronics nor the names of its contributors
114 * may be used to endorse or promote products derived from this software
115 * without specific prior written permission.
117 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
118 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
119 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
121 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
122 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
123 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
124 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
125 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
126 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128 ******************************************************************************
131 /* Includes ------------------------------------------------------------------*/
132 #include "stm32f0xx_hal.h"
134 #ifdef HAL_IRDA_MODULE_ENABLED
136 #if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && !defined(STM32F070xB) && !defined(STM32F030xC)
138 /** @addtogroup STM32F0xx_HAL_Driver
142 /** @defgroup IRDA IRDA HAL module driver
143 * @brief HAL IRDA module driver
147 /* Private typedef -----------------------------------------------------------*/
148 /* Private define ------------------------------------------------------------*/
149 /** @defgroup IRDA_Private_Constants IRDA Private Constants
152 #define TEACK_REACK_TIMEOUT 1000
153 #define IRDA_TXDMA_TIMEOUTVALUE 22000
154 #define IRDA_TIMEOUT_VALUE 22000
155 #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
156 | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))
161 /* Private macro -------------------------------------------------------------*/
162 /* Private variables ---------------------------------------------------------*/
163 /* Private function prototypes -----------------------------------------------*/
164 /** @defgroup IRDA_Private_Functions IRDA Private Functions
167 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
168 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
169 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
170 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
171 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
172 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
173 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
174 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
175 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
179 /* Exported functions ---------------------------------------------------------*/
181 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions
185 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
186 * @brief Initialization and Configuration functions
189 ==============================================================================
190 ##### Initialization and Configuration functions #####
191 ==============================================================================
193 This subsection provides a set of functions allowing to initialize the USARTx
195 (+) For the asynchronous mode only these parameters can be configured:
198 (++) Parity: If the parity is enabled, then the MSB bit of the data written
199 in the data register is transmitted but is changed by the parity bit.
200 Depending on the frame length defined by the M bit (8-bits or 9-bits)
201 or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
202 the possible IRDA frame formats are as listed in the following table:
203 +---------------------------------------------------------------+
204 | M bit | PCE bit | IRDA frame |
205 |-----------|-----------|---------------------------------------|
206 | 0 | 0 | | SB | 8-bit data | STB | |
207 |-----------|-----------|---------------------------------------|
208 | 0 | 1 | | SB | 7-bit data | PB | STB | |
209 |-----------|-----------|---------------------------------------|
210 | 1 | 0 | | SB | 9-bit data | STB | |
211 |-----------|-----------|---------------------------------------|
212 | 1 | 1 | | SB | 8-bit data | PB | STB | |
213 +---------------------------------------------------------------+
214 | M1M0 bits | PCE bit | IRDA frame |
215 |-----------------------|---------------------------------------|
216 | 10 | 0 | | SB | 7-bit data | STB | |
217 |-----------|-----------|---------------------------------------|
218 | 10 | 1 | | SB | 6-bit data | PB | STB | |
219 +---------------------------------------------------------------+
222 (++) Prescaler setting
223 (++) Receiver/transmitter modes
226 The HAL_IRDA_Init() function follows IRDA configuration procedures
227 (details for the procedures are available in reference manual).
234 * @brief Initializes the IRDA mode according to the specified
235 * parameters in the IRDA_InitTypeDef and creates the associated handle .
236 * @param hirda: IRDA handle
239 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
241 /* Check the IRDA handle allocation */
247 /* Check the USART/UART associated to the IRDA handle */
248 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
250 if(hirda->State == HAL_IRDA_STATE_RESET)
252 /* Init the low level hardware : GPIO, CLOCK */
253 HAL_IRDA_MspInit(hirda);
256 hirda->State = HAL_IRDA_STATE_BUSY;
258 /* Disable the Peripheral to update the configuration registers */
259 __HAL_IRDA_DISABLE(hirda);
261 /* Set the IRDA Communication parameters */
262 if (IRDA_SetConfig(hirda) == HAL_ERROR)
267 /* In IRDA mode, the following bits must be kept cleared:
268 - LINEN, STOP and CLKEN bits in the USART_CR2 register,
269 - SCEN and HDSEL bits in the USART_CR3 register.*/
270 hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP);
271 hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL);
273 /* set the UART/USART in IRDA mode */
274 hirda->Instance->CR3 |= USART_CR3_IREN;
276 /* Enable the Peripheral */
277 __HAL_IRDA_ENABLE(hirda);
279 /* TEACK and/or REACK to check before moving hirda->State to Ready */
280 return (IRDA_CheckIdleState(hirda));
284 * @brief DeInitializes the IRDA peripheral
285 * @param hirda: IRDA handle
288 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
290 /* Check the IRDA handle allocation */
296 /* Check the USART/UART associated to the IRDA handle */
297 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
299 hirda->State = HAL_IRDA_STATE_BUSY;
301 /* DeInit the low level hardware */
302 HAL_IRDA_MspDeInit(hirda);
303 /* Disable the Peripheral */
304 __HAL_IRDA_DISABLE(hirda);
306 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
307 hirda->State = HAL_IRDA_STATE_RESET;
316 * @brief IRDA MSP Init
317 * @param hirda: IRDA handle
320 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
322 /* NOTE : This function should not be modified, when the callback is needed,
323 the HAL_IRDA_MspInit can be implemented in the user file
328 * @brief IRDA MSP DeInit
329 * @param hirda: IRDA handle
332 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
334 /* NOTE : This function should not be modified, when the callback is needed,
335 the HAL_IRDA_MspDeInit can be implemented in the user file
343 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
344 * @brief IRDA Transmit and Receive functions
347 ===============================================================================
348 ##### IO operation functions #####
349 ===============================================================================
351 This subsection provides a set of functions allowing to manage the IRDA data transfers.
354 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
355 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
356 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
357 While receiving data, transmission should be avoided as the data to be transmitted
360 (#) There are two modes of transfer:
361 (++) Blocking mode: The communication is performed in polling mode.
362 The HAL status of all data processing is returned by the same function
363 after finishing transfer.
364 (++) Non Blocking mode: The communication is performed using Interrupts
365 or DMA, these API s return the HAL status.
366 The end of the data processing will be indicated through the
367 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
369 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
370 will be executed respectivelly at the end of the Transmit or Receive process
371 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
373 (#) Blocking mode API s are :
374 (++) HAL_IRDA_Transmit()
375 (++) HAL_IRDA_Receive()
377 (#) Non Blocking mode API s with Interrupt are :
378 (++) HAL_IRDA_Transmit_IT()
379 (++) HAL_IRDA_Receive_IT()
380 (++) HAL_IRDA_IRQHandler()
381 (++) IRDA_Transmit_IT()
382 (++) IRDA_Receive_IT()
384 (#) Non Blocking mode functions with DMA are :
385 (++) HAL_IRDA_Transmit_DMA()
386 (++) HAL_IRDA_Receive_DMA()
388 (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
389 (++) HAL_IRDA_TxCpltCallback()
390 (++) HAL_IRDA_RxCpltCallback()
391 (++) HAL_IRDA_ErrorCallback()
398 * @brief Send an amount of data in blocking mode
399 * @param hirda: IRDA handle
400 * @param pData: pointer to data buffer
401 * @param Size: amount of data to be sent
402 * @param Timeout: Duration of the timeout
405 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
409 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
411 if((pData == NULL) || (Size == 0))
418 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
420 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
422 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
426 hirda->State = HAL_IRDA_STATE_BUSY_TX;
429 hirda->TxXferSize = Size;
430 hirda->TxXferCount = Size;
431 while(hirda->TxXferCount > 0)
433 hirda->TxXferCount--;
435 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK)
439 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
441 tmp = (uint16_t*) pData;
442 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
447 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF);
451 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK)
456 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
458 hirda->State = HAL_IRDA_STATE_BUSY_RX;
462 hirda->State = HAL_IRDA_STATE_READY;
465 /* Process Unlocked */
477 * @brief Receive an amount of data in blocking mode
478 * @param hirda: IRDA handle
479 * @param pData: pointer to data buffer
480 * @param Size: amount of data to be received
481 * @param Timeout: Duration of the timeout
484 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
489 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
491 if((pData == NULL) || (Size == 0))
498 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
500 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
502 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
506 hirda->State = HAL_IRDA_STATE_BUSY_RX;
509 hirda->RxXferSize = Size;
510 hirda->RxXferCount = Size;
512 /* Computation of the mask to apply to the RDR register
513 of the UART associated to the IRDA */
514 __HAL_IRDA_MASK_COMPUTATION(hirda);
515 uhMask = hirda->Mask;
517 /* Check data remaining to be received */
518 while(hirda->RxXferCount > 0)
520 hirda->RxXferCount--;
522 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK)
526 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
528 tmp = (uint16_t*) pData ;
529 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
534 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
538 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
540 hirda->State = HAL_IRDA_STATE_BUSY_TX;
544 hirda->State = HAL_IRDA_STATE_READY;
547 /* Process Unlocked */
559 * @brief Send an amount of data in interrupt mode
560 * @param hirda: IRDA handle
561 * @param pData: pointer to data buffer
562 * @param Size: amount of data to be sent
565 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
567 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
569 if((pData == NULL) || (Size == 0))
577 hirda->pTxBuffPtr = pData;
578 hirda->TxXferSize = Size;
579 hirda->TxXferCount = Size;
581 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
582 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
584 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
588 hirda->State = HAL_IRDA_STATE_BUSY_TX;
591 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
592 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
594 /* Process Unlocked */
597 /* Enable the IRDA Transmit Data Register Empty Interrupt */
598 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
609 * @brief Receive an amount of data in interrupt mode
610 * @param hirda: IRDA handle
611 * @param pData: pointer to data buffer
612 * @param Size: amount of data to be received
615 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
617 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
619 if((pData == NULL) || (Size == 0))
627 hirda->pRxBuffPtr = pData;
628 hirda->RxXferSize = Size;
629 hirda->RxXferCount = Size;
631 /* Computation of the mask to apply to the RDR register
632 of the UART associated to the IRDA */
633 __HAL_IRDA_MASK_COMPUTATION(hirda);
635 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
636 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
638 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
642 hirda->State = HAL_IRDA_STATE_BUSY_RX;
645 /* Enable the IRDA Parity Error Interrupt */
646 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
648 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
649 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
651 /* Process Unlocked */
654 /* Enable the IRDA Data Register not empty Interrupt */
655 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
666 * @brief Send an amount of data in DMA mode
667 * @param hirda: IRDA handle
668 * @param pData: pointer to data buffer
669 * @param Size: amount of data to be sent
672 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
676 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
678 if((pData == NULL) || (Size == 0))
686 hirda->pTxBuffPtr = pData;
687 hirda->TxXferSize = Size;
688 hirda->TxXferCount = Size;
690 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
692 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
694 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
698 hirda->State = HAL_IRDA_STATE_BUSY_TX;
701 /* Set the IRDA DMA transfer complete callback */
702 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
704 /* Set the DMA error callback */
705 hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
707 /* Enable the IRDA transmit DMA channel */
708 tmp = (uint32_t*)&pData;
709 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
711 /* Enable the DMA transfer for transmit request by setting the DMAT bit
712 in the IRDA CR3 register */
713 hirda->Instance->CR3 |= USART_CR3_DMAT;
715 /* Process Unlocked */
727 * @brief Receive an amount of data in DMA mode
728 * @param hirda: IRDA handle
729 * @param pData: pointer to data buffer
730 * @param Size: amount of data to be received
731 * @note When the IRDA parity is enabled (PCE = 1), the received data contain
732 * the parity bit (MSB position)
735 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
739 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
741 if((pData == NULL) || (Size == 0))
749 hirda->pRxBuffPtr = pData;
750 hirda->RxXferSize = Size;
752 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
753 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
755 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
759 hirda->State = HAL_IRDA_STATE_BUSY_RX;
762 /* Set the IRDA DMA transfer complete callback */
763 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
765 /* Set the DMA error callback */
766 hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
768 /* Enable the DMA channel */
769 tmp = (uint32_t*)&pData;
770 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
772 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
773 in the IRDA CR3 register */
774 hirda->Instance->CR3 |= USART_CR3_DMAR;
776 /* Process Unlocked */
788 * @brief This function handles IRDA interrupt request.
789 * @param hirda: IRDA handle
792 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
794 /* IRDA parity error interrupt occurred -------------------------------------*/
795 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET))
797 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
799 hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
800 /* Set the IRDA state ready to be able to start again the process */
801 hirda->State = HAL_IRDA_STATE_READY;
804 /* IRDA frame error interrupt occured --------------------------------------*/
805 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
807 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
809 hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
810 /* Set the IRDA state ready to be able to start again the process */
811 hirda->State = HAL_IRDA_STATE_READY;
814 /* IRDA noise error interrupt occured --------------------------------------*/
815 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
817 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
819 hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
820 /* Set the IRDA state ready to be able to start again the process */
821 hirda->State = HAL_IRDA_STATE_READY;
824 /* IRDA Over-Run interrupt occured -----------------------------------------*/
825 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
827 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
829 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
830 /* Set the IRDA state ready to be able to start again the process */
831 hirda->State = HAL_IRDA_STATE_READY;
834 /* Call IRDA Error Call back function if need be --------------------------*/
835 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
837 HAL_IRDA_ErrorCallback(hirda);
840 /* IRDA in mode Receiver ---------------------------------------------------*/
841 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET))
843 IRDA_Receive_IT(hirda);
844 /* Clear RXNE interrupt flag */
845 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
849 /* IRDA in mode Transmitter ------------------------------------------------*/
850 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET))
852 IRDA_Transmit_IT(hirda);
855 /* IRDA in mode Transmitter (transmission end) -----------------------------*/
856 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET))
858 IRDA_EndTransmit_IT(hirda);
870 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
875 * @brief DMA IRDA Tx transfer completed callback
876 * @param hdma: DMA handle
879 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
881 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
882 hirda->TxXferCount = 0;
884 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
885 in the IRDA CR3 register */
886 hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT);
888 /* Enable the IRDA Transmit Complete Interrupt */
889 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
893 * @brief DMA IRDA Rx Transfer completed callback
894 * @param hdma: DMA handle
897 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
899 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
900 hirda->RxXferCount = 0;
902 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
903 in the IRDA CR3 register */
904 hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR);
906 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
908 hirda->State = HAL_IRDA_STATE_BUSY_TX;
912 hirda->State = HAL_IRDA_STATE_READY;
915 HAL_IRDA_RxCpltCallback(hirda);
919 * @brief DMA IRDA communication error callback
920 * @param hdma: DMA handle
923 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
925 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
926 hirda->RxXferCount = 0;
927 hirda->TxXferCount = 0;
928 hirda->State= HAL_IRDA_STATE_READY;
929 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
930 HAL_IRDA_ErrorCallback(hirda);
936 /** @addtogroup IRDA_Exported_Functions IRDA Exported Functions
940 /** @addtogroup IRDA_Exported_Functions_Group2 IO operation functions
945 * @brief Tx Transfer completed callback
946 * @param hirda: irda handle
949 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
951 /* NOTE : This function should not be modified, when the callback is needed,
952 the HAL_IRDA_TxCpltCallback can be implemented in the user file
957 * @brief Rx Transfer completed callback
958 * @param hirda: irda handle
961 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
963 /* NOTE : This function should not be modified, when the callback is needed,
964 the HAL_IRDA_TxCpltCallback can be implemented in the user file
969 * @brief IRDA error callback
970 * @param hirda: IRDA handle
973 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
975 /* NOTE : This function should not be modified, when the callback is needed,
976 the HAL_IRDA_ErrorCallback can be implemented in the user file
988 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
993 * @brief Receive an amount of data in non blocking mode.
994 * Function called under interruption only, once
995 * interruptions have been enabled by HAL_IRDA_Transmit_IT()
996 * @param hirda: IRDA handle
999 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
1003 if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
1006 if(hirda->TxXferCount == 0)
1008 /* Disable the IRDA Transmit Data Register Empty Interrupt */
1009 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1011 /* Enable the IRDA Transmit Complete Interrupt */
1012 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
1018 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1020 tmp = (uint16_t*) hirda->pTxBuffPtr;
1021 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1022 hirda->pTxBuffPtr += 2;
1026 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF);
1028 hirda->TxXferCount--;
1040 * @brief Wraps up transmission in non blocking mode.
1041 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1042 * the configuration information for the specified IRDA module.
1043 * @retval HAL status
1045 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
1047 /* Disable the IRDA Transmit Complete Interrupt */
1048 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC);
1050 /* Check if a receive process is ongoing or not */
1051 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
1053 hirda->State = HAL_IRDA_STATE_BUSY_RX;
1057 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1058 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1060 hirda->State = HAL_IRDA_STATE_READY;
1063 HAL_IRDA_TxCpltCallback(hirda);
1070 * @brief Receive an amount of data in non blocking mode.
1071 * Function called under interruption only, once
1072 * interruptions have been enabled by HAL_IRDA_Receive_IT()
1073 * @param hirda: IRDA handle
1074 * @retval HAL status
1076 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
1079 uint16_t uhMask = hirda->Mask;
1081 if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
1084 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1086 tmp = (uint16_t*) hirda->pRxBuffPtr ;
1087 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
1088 hirda->pRxBuffPtr +=2;
1092 *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
1095 if(--hirda->RxXferCount == 0)
1097 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1099 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
1101 hirda->State = HAL_IRDA_STATE_BUSY_TX;
1105 /* Disable the IRDA Parity Error Interrupt */
1106 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1108 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1109 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1111 hirda->State = HAL_IRDA_STATE_READY;
1114 HAL_IRDA_RxCpltCallback(hirda);
1131 /** @addtogroup IRDA_Exported_Functions IRDA Exported Functions
1135 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
1136 * @brief IRDA control functions
1139 ===============================================================================
1140 ##### Peripheral Control functions #####
1141 ===============================================================================
1143 This subsection provides a set of functions allowing to control the IRDA.
1144 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IRDA peripheral.
1145 (+) IRDA_SetConfig() API is used to configure the IRDA communications parameters.
1151 * @brief return the IRDA state
1152 * @param hirda: irda handle
1155 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
1157 return hirda->State;
1161 * @brief Return the IRDA error code
1162 * @param hirda : pointer to a IRDA_HandleTypeDef structure that contains
1163 * the configuration information for the specified IRDA.
1164 * @retval IRDA Error Code
1166 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
1168 return hirda->ErrorCode;
1179 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
1184 * @brief Configure the IRDA peripheral
1185 * @param hirda: irda handle
1188 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
1190 uint32_t tmpreg = 0x00000000;
1191 IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED;
1192 HAL_StatusTypeDef ret = HAL_OK;
1194 /* Check the communication parameters */
1195 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
1196 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
1197 assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
1198 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
1199 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
1200 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
1202 /*-------------------------- USART CR1 Configuration -----------------------*/
1203 /* Configure the IRDA Word Length, Parity and transfer Mode:
1204 Set the M bits according to hirda->Init.WordLength value
1205 Set PCE and PS bits according to hirda->Init.Parity value
1206 Set TE and RE bits according to hirda->Init.Mode value */
1207 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
1209 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
1211 /*-------------------------- USART CR3 Configuration -----------------------*/
1212 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
1214 /*-------------------------- USART GTPR Configuration ----------------------*/
1215 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
1217 /*-------------------------- USART BRR Configuration -----------------------*/
1218 __HAL_IRDA_GETCLOCKSOURCE(hirda, clocksource);
1219 switch (clocksource)
1221 case IRDA_CLOCKSOURCE_PCLK1:
1222 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hirda->Init.BaudRate);
1224 case IRDA_CLOCKSOURCE_HSI:
1225 hirda->Instance->BRR = (uint16_t)(HSI_VALUE / hirda->Init.BaudRate);
1227 case IRDA_CLOCKSOURCE_SYSCLK:
1228 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hirda->Init.BaudRate);
1230 case IRDA_CLOCKSOURCE_LSE:
1231 hirda->Instance->BRR = (uint16_t)(LSE_VALUE / hirda->Init.BaudRate);
1233 case IRDA_CLOCKSOURCE_UNDEFINED:
1243 * @brief Check the IRDA Idle State
1244 * @param hirda: IRDA handle
1245 * @retval HAL status
1247 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
1250 /* Initialize the IRDA ErrorCode */
1251 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1253 /* Check if the Transmitter is enabled */
1254 if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1256 /* Wait until TEACK flag is set */
1257 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1259 /* Timeout Occured */
1263 /* Check if the Receiver is enabled */
1264 if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1266 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1268 /* Timeout Occured */
1273 /* Initialize the IRDA state*/
1274 hirda->State= HAL_IRDA_STATE_READY;
1275 /* Process Unlocked */
1276 __HAL_UNLOCK(hirda);
1282 * @brief Handle IRDA Communication Timeout.
1283 * @param hirda: IRDA handle
1284 * @param Flag: specifies the IRDA flag to check.
1285 * @param Status: the flag status (SET or RESET). The function is locked in a while loop as long as the flag remains set to Status.
1286 * @param Timeout: Timeout duration
1287 * @retval HAL status
1289 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1291 uint32_t tickstart = HAL_GetTick();
1293 /* Wait until flag is set */
1296 while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET)
1298 /* Check for the Timeout */
1299 if(Timeout != HAL_MAX_DELAY)
1301 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1303 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1304 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1305 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1306 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1307 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1309 hirda->State= HAL_IRDA_STATE_READY;
1311 /* Process Unlocked */
1312 __HAL_UNLOCK(hirda);
1321 while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET)
1323 /* Check for the Timeout */
1324 if(Timeout != HAL_MAX_DELAY)
1326 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1328 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1329 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1330 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1331 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1332 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1334 hirda->State= HAL_IRDA_STATE_READY;
1336 /* Process Unlocked */
1337 __HAL_UNLOCK(hirda);
1359 #endif /* !defined(STM32F030x6) && !defined(STM32F030x8)&& !defined(STM32F070x6) && !defined(STM32F070xB) && !defined(STM32F030xC) */
1361 #endif /* HAL_IRDA_MODULE_ENABLED */
1363 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/