2 ******************************************************************************
3 * @file stm32f3xx_hal_irda.c
4 * @author MCD Application Team
7 * @brief IRDA HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the IrDA (Infrared Data Association) Peripheral
12 * + Initialization and de-initialization functions
13 * + IO operation functions
14 * + Peripheral Control functions
18 ===============================================================================
19 ##### How to use this driver #####
20 ===============================================================================
22 The IRDA HAL driver can be used as follows:
24 (#) Declare a IRDA_HandleTypeDef handle structure.
25 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API
26 in setting the associated USART or UART in IRDA mode:
27 (##) Enable the USARTx/UARTx interface clock.
28 (##) USARTx/UARTx pins configuration:
29 (+) Enable the clock for the USARTx/UARTx GPIOs.
30 (+) Configure these USARTx/UARTx pins as alternate function pull-up.
31 (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
32 and HAL_IRDA_Receive_IT() APIs):
33 (+) Configure the USARTx/UARTx interrupt priority.
34 (+) Enable the NVIC IRDA IRQ handle.
35 (@) The specific IRDA interrupts (Transmission complete interrupt,
36 RXNE interrupt and Error Interrupts) will be managed using the macros
37 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
38 (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
39 and HAL_IRDA_Receive_DMA() APIs):
40 (+) Declare a DMA handle structure for the Tx/Rx stream.
41 (+) Enable the DMAx interface clock.
42 (+) Configure the declared DMA handle structure with the required Tx/Rx parameters.
43 (+) Configure the DMA Tx/Rx Stream.
44 (+) Associate the initilalized DMA handle to the IRDA DMA Tx/Rx handle.
45 (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
47 (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
48 the normal or low power mode and the clock prescaler in the hirda Init structure.
50 (#) Initialize the IRDA registers by calling
51 the HAL_IRDA_Init() API.
53 (@) This API (HAL_IRDA_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
54 by calling the customized HAL_IRDA_MspInit() API.
57 ******************************************************************************
60 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
62 * Redistribution and use in source and binary forms, with or without modification,
63 * are permitted provided that the following conditions are met:
64 * 1. Redistributions of source code must retain the above copyright notice,
65 * this list of conditions and the following disclaimer.
66 * 2. Redistributions in binary form must reproduce the above copyright notice,
67 * this list of conditions and the following disclaimer in the documentation
68 * and/or other materials provided with the distribution.
69 * 3. Neither the name of STMicroelectronics nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
80 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
81 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
82 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84 ******************************************************************************
87 /* Includes ------------------------------------------------------------------*/
88 #include "stm32f3xx_hal.h"
90 /** @addtogroup STM32F3xx_HAL_Driver
94 /** @defgroup IRDA IRDA HAL module driver
95 * @brief HAL IRDA module driver
98 #ifdef HAL_IRDA_MODULE_ENABLED
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /** @defgroup IRDA_Private_Constants IRDA Private Constants
105 #define TEACK_REACK_TIMEOUT 1000
106 #define IRDA_TXDMA_TIMEOUTVALUE 22000
107 #define IRDA_TIMEOUT_VALUE 22000
108 #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
109 | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))
114 /* Private macro -------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private function prototypes -----------------------------------------------*/
117 /** @defgroup IRDA_Private_Functions IRDA Private Functions
120 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
121 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
122 static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
123 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
124 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
125 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
126 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
127 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
128 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
132 /* Exported functions ---------------------------------------------------------*/
134 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions
138 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
139 * @brief Initialization and Configuration functions
142 ==============================================================================
143 ##### Initialization and Configuration functions #####
144 ==============================================================================
146 This subsection provides a set of functions allowing to initialize the USARTx
147 in asynchronous IRDA mode.
148 (+) For the asynchronous mode only these parameters can be configured:
151 (++) Parity: If the parity is enabled, then the MSB bit of the data written
152 in the data register is transmitted but is changed by the parity bit.
153 Depending on the frame length defined by the M bit (8-bits or 9-bits)
154 or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
155 the possible IRDA frame formats are as listed in the following table:
156 +---------------------------------------------------------------+
157 | M bit | PCE bit | IRDA frame |
158 |-----------|-----------|---------------------------------------|
159 | 0 | 0 | | SB | 8-bit data | STB | |
160 |-----------|-----------|---------------------------------------|
161 | 0 | 1 | | SB | 7-bit data | PB | STB | |
162 |-----------|-----------|---------------------------------------|
163 | 1 | 0 | | SB | 9-bit data | STB | |
164 |-----------|-----------|---------------------------------------|
165 | 1 | 1 | | SB | 8-bit data | PB | STB | |
166 +---------------------------------------------------------------+
167 | M1M0 bits | PCE bit | IRDA frame |
168 |-----------------------|---------------------------------------|
169 | 10 | 0 | | SB | 7-bit data | STB | |
170 |-----------|-----------|---------------------------------------|
171 | 10 | 1 | | SB | 6-bit data | PB | STB | |
172 +---------------------------------------------------------------+
175 (++) Prescaler setting
176 (++) Receiver/transmitter modes
179 The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
180 (details for the procedures are available in reference manual).
187 * @brief Initializes the IRDA mode according to the specified
188 * parameters in the IRDA_InitTypeDef and creates the associated handle .
189 * @param hirda: IRDA handle
192 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
194 /* Check the IRDA handle allocation */
195 if(hirda == HAL_NULL)
200 /* Check the USART/UART associated to the IRDA handle */
201 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
203 if(hirda->State == HAL_IRDA_STATE_RESET)
205 /* Init the low level hardware : GPIO, CLOCK */
206 HAL_IRDA_MspInit(hirda);
209 hirda->State = HAL_IRDA_STATE_BUSY;
211 /* Disable the Peripheral to update the configuration registers */
212 __HAL_IRDA_DISABLE(hirda);
214 /* Set the IRDA Communication parameters */
215 if (IRDA_SetConfig(hirda) == HAL_ERROR)
220 /* In IRDA mode, the following bits must be kept cleared:
221 - LINEN, STOP and CLKEN bits in the USART_CR2 register,
222 - SCEN and HDSEL bits in the USART_CR3 register.*/
223 hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP);
224 hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL);
226 /* set the UART/USART in IRDA mode */
227 hirda->Instance->CR3 |= USART_CR3_IREN;
229 /* Enable the Peripheral */
230 __HAL_IRDA_ENABLE(hirda);
232 /* TEACK and/or REACK to check before moving hirda->State to Ready */
233 return (IRDA_CheckIdleState(hirda));
237 * @brief DeInitializes the IRDA peripheral
238 * @param hirda: IRDA handle
241 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
243 /* Check the IRDA handle allocation */
244 if(hirda == HAL_NULL)
249 /* Check the USART/UART associated to the IRDA handle */
250 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
252 hirda->State = HAL_IRDA_STATE_BUSY;
254 /* DeInit the low level hardware */
255 HAL_IRDA_MspDeInit(hirda);
256 /* Disable the Peripheral */
257 __HAL_IRDA_DISABLE(hirda);
259 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
260 hirda->State = HAL_IRDA_STATE_RESET;
269 * @brief IRDA MSP Init
270 * @param hirda: IRDA handle
273 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
275 /* NOTE : This function should not be modified, when the callback is needed,
276 the HAL_IRDA_MspInit can be implemented in the user file
281 * @brief IRDA MSP DeInit
282 * @param hirda: IRDA handle
285 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
287 /* NOTE : This function should not be modified, when the callback is needed,
288 the HAL_IRDA_MspDeInit can be implemented in the user file
296 /** @defgroup IRDA_Exported_Functions_Group2 Input and Output operation functions
297 * @brief IRDA Transmit and Receive functions
300 ===============================================================================
301 ##### I/O operation functions #####
302 ===============================================================================
303 This subsection provides a set of functions allowing to manage the IRDA asynchronous
306 (#) There are two modes of transfer:
307 (+) Blocking mode: the communication is performed in polling mode.
308 The HAL status of all data processing is returned by the same function
309 after finishing transfer.
310 (+) No-Blocking mode: the communication is performed using Interrupts
311 or DMA, these API's return the HAL status.
312 The end of the data processing will be indicated through the
313 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
315 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
316 will be executed respectivelly at the end of the Transmit or Receive process
317 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
319 (#) Blocking mode API's are :
320 (+) HAL_IRDA_Transmit()
321 (+) HAL_IRDA_Receive()
323 (#) Non-Blocking mode API's with Interrupt are :
324 (+) HAL_IRDA_Transmit_IT()
325 (+) HAL_IRDA_Receive_IT()
326 (+) HAL_IRDA_IRQHandler()
327 (+) IRDA_Transmit_IT()
328 (+) IRDA_Receive_IT()
330 (#) Non-Blocking mode functions with DMA are :
331 (+) HAL_IRDA_Transmit_DMA()
332 (+) HAL_IRDA_Receive_DMA()
334 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
335 (+) HAL_IRDA_TxCpltCallback()
336 (+) HAL_IRDA_RxCpltCallback()
337 (+) HAL_IRDA_ErrorCallback()
344 * @brief Send an amount of data in blocking mode
345 * @param hirda: IRDA handle
346 * @param pData: pointer to data buffer
347 * @param Size: amount of data to be sent
348 * @param Timeout: Duration of the timeout
351 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
355 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
357 if((pData == HAL_NULL) || (Size == 0))
364 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
366 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
368 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
372 hirda->State = HAL_IRDA_STATE_BUSY_TX;
375 hirda->TxXferSize = Size;
376 hirda->TxXferCount = Size;
377 while(hirda->TxXferCount > 0)
379 hirda->TxXferCount--;
381 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK)
385 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
387 tmp = (uint16_t*) pData;
388 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
393 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF);
397 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK)
402 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
404 hirda->State = HAL_IRDA_STATE_BUSY_RX;
408 hirda->State = HAL_IRDA_STATE_READY;
411 /* Process Unlocked */
423 * @brief Receive an amount of data in blocking mode
424 * @param hirda: IRDA handle
425 * @param pData: pointer to data buffer
426 * @param Size: amount of data to be received
427 * @param Timeout: Duration of the timeout
430 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
435 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
437 if((pData == HAL_NULL) || (Size == 0))
444 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
446 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
448 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
452 hirda->State = HAL_IRDA_STATE_BUSY_RX;
455 hirda->RxXferSize = Size;
456 hirda->RxXferCount = Size;
458 /* Computation of the mask to apply to the RDR register
459 of the UART associated to the IRDA */
460 __HAL_IRDA_MASK_COMPUTATION(hirda);
461 uhMask = hirda->Mask;
463 /* Check data remaining to be received */
464 while(hirda->RxXferCount > 0)
466 hirda->RxXferCount--;
468 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK)
472 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
474 tmp = (uint16_t*) pData ;
475 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
480 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
484 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
486 hirda->State = HAL_IRDA_STATE_BUSY_TX;
490 hirda->State = HAL_IRDA_STATE_READY;
493 /* Process Unlocked */
505 * @brief Send an amount of data in interrupt mode
506 * @param hirda: IRDA handle
507 * @param pData: pointer to data buffer
508 * @param Size: amount of data to be sent
511 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
513 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
515 if((pData == HAL_NULL) || (Size == 0))
523 hirda->pTxBuffPtr = pData;
524 hirda->TxXferSize = Size;
525 hirda->TxXferCount = Size;
527 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
528 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
530 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
534 hirda->State = HAL_IRDA_STATE_BUSY_TX;
537 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
538 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
540 /* Process Unlocked */
543 /* Enable the IRDA Transmit Data Register Empty Interrupt */
544 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
555 * @brief Receive an amount of data in interrupt mode
556 * @param hirda: IRDA handle
557 * @param pData: pointer to data buffer
558 * @param Size: amount of data to be received
561 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
563 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
565 if((pData == HAL_NULL) || (Size == 0))
573 hirda->pRxBuffPtr = pData;
574 hirda->RxXferSize = Size;
575 hirda->RxXferCount = Size;
577 /* Computation of the mask to apply to the RDR register
578 of the UART associated to the IRDA */
579 __HAL_IRDA_MASK_COMPUTATION(hirda);
581 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
582 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
584 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
588 hirda->State = HAL_IRDA_STATE_BUSY_RX;
591 /* Enable the IRDA Parity Error Interrupt */
592 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
594 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
595 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
597 /* Process Unlocked */
600 /* Enable the IRDA Data Register not empty Interrupt */
601 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
612 * @brief Send an amount of data in DMA mode
613 * @param hirda: IRDA handle
614 * @param pData: pointer to data buffer
615 * @param Size: amount of data to be sent
618 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
622 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX))
624 if((pData == HAL_NULL) || (Size == 0))
632 hirda->pTxBuffPtr = pData;
633 hirda->TxXferSize = Size;
634 hirda->TxXferCount = Size;
636 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
638 if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
640 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
644 hirda->State = HAL_IRDA_STATE_BUSY_TX;
647 /* Set the IRDA DMA transfer complete callback */
648 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
650 /* Set the DMA error callback */
651 hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
653 /* Enable the IRDA transmit DMA channel */
654 tmp = (uint32_t*)&pData;
655 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
657 /* Enable the DMA transfer for transmit request by setting the DMAT bit
658 in the IRDA CR3 register */
659 hirda->Instance->CR3 |= USART_CR3_DMAT;
661 /* Process Unlocked */
673 * @brief Receive an amount of data in DMA mode
674 * @param hirda: IRDA handle
675 * @param pData: pointer to data buffer
676 * @param Size: amount of data to be received
677 * @note When the IRDA parity is enabled (PCE = 1), the received data contain
678 * the parity bit (MSB position)
681 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
685 if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX))
687 if((pData == HAL_NULL) || (Size == 0))
695 hirda->pRxBuffPtr = pData;
696 hirda->RxXferSize = Size;
698 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
699 if(hirda->State == HAL_IRDA_STATE_BUSY_TX)
701 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
705 hirda->State = HAL_IRDA_STATE_BUSY_RX;
708 /* Set the IRDA DMA transfer complete callback */
709 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
711 /* Set the DMA error callback */
712 hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
714 /* Enable the DMA channel */
715 tmp = (uint32_t*)&pData;
716 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
718 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
719 in the IRDA CR3 register */
720 hirda->Instance->CR3 |= USART_CR3_DMAR;
722 /* Process Unlocked */
734 * @brief This function handles IRDA interrupt request.
735 * @param hirda: IRDA handle
738 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
740 /* IRDA parity error interrupt occurred -------------------------------------*/
741 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET))
743 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
745 hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
746 /* Set the IRDA state ready to be able to start again the process */
747 hirda->State = HAL_IRDA_STATE_READY;
750 /* IRDA frame error interrupt occured --------------------------------------*/
751 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
753 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
755 hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
756 /* Set the IRDA state ready to be able to start again the process */
757 hirda->State = HAL_IRDA_STATE_READY;
760 /* IRDA noise error interrupt occured --------------------------------------*/
761 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
763 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
765 hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
766 /* Set the IRDA state ready to be able to start again the process */
767 hirda->State = HAL_IRDA_STATE_READY;
770 /* IRDA Over-Run interrupt occured -----------------------------------------*/
771 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET))
773 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
775 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
776 /* Set the IRDA state ready to be able to start again the process */
777 hirda->State = HAL_IRDA_STATE_READY;
780 /* Call IRDA Error Call back function if need be --------------------------*/
781 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
783 HAL_IRDA_ErrorCallback(hirda);
786 /* IRDA in mode Receiver ---------------------------------------------------*/
787 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET))
789 IRDA_Receive_IT(hirda);
790 /* Clear RXNE interrupt flag */
791 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
795 /* IRDA in mode Transmitter ------------------------------------------------*/
796 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET))
798 IRDA_Transmit_IT(hirda);
801 /* IRDA in mode Transmitter (transmission end) -----------------------------*/
802 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET))
804 IRDA_EndTransmit_IT(hirda);
816 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
821 * @brief DMA IRDA Tx transfer completed callback
822 * @param hdma: DMA handle
825 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
827 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
828 hirda->TxXferCount = 0;
830 /* Disable the DMA transfer for transmit request by setting the DMAT bit
831 in the IRDA CR3 register */
832 hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT);
834 /* Wait for IRDA TC Flag */
835 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, IRDA_TXDMA_TIMEOUTVALUE) != HAL_OK)
837 /* Timeout Occured */
838 HAL_IRDA_ErrorCallback(hirda);
843 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
845 hirda->State = HAL_IRDA_STATE_BUSY_RX;
849 hirda->State = HAL_IRDA_STATE_READY;
851 HAL_IRDA_TxCpltCallback(hirda);
856 * @brief DMA IRDA Rx Transfer completed callback
857 * @param hdma: DMA handle
860 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
862 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
863 hirda->RxXferCount = 0;
865 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
866 in the IRDA CR3 register */
867 hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR);
869 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
871 hirda->State = HAL_IRDA_STATE_BUSY_TX;
875 hirda->State = HAL_IRDA_STATE_READY;
878 HAL_IRDA_RxCpltCallback(hirda);
882 * @brief DMA IRDA communication error callback
883 * @param hdma: DMA handle
886 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
888 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
889 hirda->RxXferCount = 0;
890 hirda->TxXferCount = 0;
891 hirda->State= HAL_IRDA_STATE_READY;
892 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
893 HAL_IRDA_ErrorCallback(hirda);
899 /** @addtogroup IRDA_Exported_Functions IRDA Exported Functions
903 /** @addtogroup IRDA_Exported_Functions_Group2 Input and Output operation functions
908 * @brief Tx Transfer completed callback
909 * @param hirda: irda handle
912 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
914 /* NOTE : This function should not be modified, when the callback is needed,
915 the HAL_IRDA_TxCpltCallback can be implemented in the user file
920 * @brief Rx Transfer completed callback
921 * @param hirda: irda handle
924 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
926 /* NOTE : This function should not be modified, when the callback is needed,
927 the HAL_IRDA_TxCpltCallback can be implemented in the user file
932 * @brief IRDA error callback
933 * @param hirda: IRDA handle
936 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
938 /* NOTE : This function should not be modified, when the callback is needed,
939 the HAL_IRDA_ErrorCallback can be implemented in the user file
951 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
956 * @brief Receive an amount of data in non blocking mode.
957 * Function called under interruption only, once
958 * interruptions have been enabled by HAL_IRDA_Transmit_IT()
959 * @param hirda: IRDA handle
962 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
966 if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
969 if(hirda->TxXferCount == 0)
971 /* Disable the IRDA Transmit Data Register Empty Interrupt */
972 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
974 /* Enable the IRDA Transmit Complete Interrupt */
975 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
981 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
983 tmp = (uint16_t*) hirda->pTxBuffPtr;
984 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF);
985 hirda->pTxBuffPtr += 2;
989 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF);
991 hirda->TxXferCount--;
1003 * @brief Wraps up transmission in non blocking mode.
1004 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1005 * the configuration information for the specified IRDA module.
1006 * @retval HAL status
1008 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
1010 /* Disable the IRDA Transmit Complete Interrupt */
1011 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC);
1013 /* Check if a receive process is ongoing or not */
1014 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
1016 hirda->State = HAL_IRDA_STATE_BUSY_RX;
1020 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1021 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1023 hirda->State = HAL_IRDA_STATE_READY;
1026 HAL_IRDA_TxCpltCallback(hirda);
1033 * @brief Receive an amount of data in non blocking mode.
1034 * Function called under interruption only, once
1035 * interruptions have been enabled by HAL_IRDA_Receive_IT()
1036 * @param hirda: IRDA handle
1037 * @retval HAL status
1039 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
1042 uint16_t uhMask = hirda->Mask;
1044 if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX))
1047 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1049 tmp = (uint16_t*) hirda->pRxBuffPtr ;
1050 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
1051 hirda->pRxBuffPtr +=2;
1055 *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
1058 if(--hirda->RxXferCount == 0)
1060 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1062 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
1064 hirda->State = HAL_IRDA_STATE_BUSY_TX;
1068 /* Disable the IRDA Parity Error Interrupt */
1069 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1071 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1072 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1074 hirda->State = HAL_IRDA_STATE_READY;
1077 HAL_IRDA_RxCpltCallback(hirda);
1094 /** @addtogroup IRDA_Exported_Functions IRDA Exported Functions
1098 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
1099 * @brief IRDA control functions
1102 ===============================================================================
1103 ##### Peripheral State and Error functions #####
1104 ===============================================================================
1106 This subsection provides a set of functions allowing to control the IRDA.
1107 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IRDA peripheral.
1108 (+) IRDA_SetConfig() API is used to configure the IRDA communications parameters.
1114 * @brief return the IRDA state
1115 * @param hirda: irda handle
1118 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
1120 return hirda->State;
1124 * @brief Return the IRDA error code
1125 * @param hirda : pointer to a IRDA_HandleTypeDef structure that contains
1126 * the configuration information for the specified IRDA.
1127 * @retval IRDA Error Code
1129 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
1131 return hirda->ErrorCode;
1142 /** @addtogroup IRDA_Private_Functions IRDA Private Functions
1147 * @brief Configure the IRDA peripheral
1148 * @param hirda: irda handle
1151 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
1153 uint32_t tmpreg = 0x00000000;
1154 IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED;
1155 HAL_StatusTypeDef ret = HAL_OK;
1157 /* Check the communication parameters */
1158 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
1159 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
1160 assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
1161 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
1162 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
1163 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
1165 /*-------------------------- USART CR1 Configuration -----------------------*/
1166 /* Configure the IRDA Word Length, Parity and transfer Mode:
1167 Set the M bits according to hirda->Init.WordLength value
1168 Set PCE and PS bits according to hirda->Init.Parity value
1169 Set TE and RE bits according to hirda->Init.Mode value */
1170 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
1172 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
1174 /*-------------------------- USART CR3 Configuration -----------------------*/
1175 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
1177 /*-------------------------- USART GTPR Configuration ----------------------*/
1178 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
1180 /*-------------------------- USART BRR Configuration -----------------------*/
1181 __HAL_IRDA_GETCLOCKSOURCE(hirda, clocksource);
1182 switch (clocksource)
1184 case IRDA_CLOCKSOURCE_PCLK1:
1185 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hirda->Init.BaudRate);
1187 case IRDA_CLOCKSOURCE_PCLK2:
1188 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hirda->Init.BaudRate);
1190 case IRDA_CLOCKSOURCE_HSI:
1191 hirda->Instance->BRR = (uint16_t)(HSI_VALUE / hirda->Init.BaudRate);
1193 case IRDA_CLOCKSOURCE_SYSCLK:
1194 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hirda->Init.BaudRate);
1196 case IRDA_CLOCKSOURCE_LSE:
1197 hirda->Instance->BRR = (uint16_t)(LSE_VALUE / hirda->Init.BaudRate);
1199 case IRDA_CLOCKSOURCE_UNDEFINED:
1209 * @brief Check the IRDA Idle State
1210 * @param hirda: IRDA handle
1211 * @retval HAL status
1213 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
1216 /* Initialize the IRDA ErrorCode */
1217 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1219 /* Check if the Transmitter is enabled */
1220 if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1222 /* Wait until TEACK flag is set */
1223 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1225 /* Timeout Occured */
1229 /* Check if the Receiver is enabled */
1230 if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1232 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1234 /* Timeout Occured */
1239 /* Initialize the IRDA state*/
1240 hirda->State= HAL_IRDA_STATE_READY;
1241 /* Process Unlocked */
1242 __HAL_UNLOCK(hirda);
1248 * @brief Handle IRDA Communication Timeout.
1249 * @param hirda: IRDA handle
1250 * @param Flag: specifies the IRDA flag to check.
1251 * @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.
1252 * @param Timeout: Timeout duration
1253 * @retval HAL status
1255 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1257 uint32_t tickstart = HAL_GetTick();
1259 /* Wait until flag is set */
1262 while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET)
1264 /* Check for the Timeout */
1265 if(Timeout != HAL_MAX_DELAY)
1267 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1269 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1270 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1271 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1272 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1273 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1275 hirda->State= HAL_IRDA_STATE_TIMEOUT;
1277 /* Process Unlocked */
1278 __HAL_UNLOCK(hirda);
1287 while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET)
1289 /* Check for the Timeout */
1290 if(Timeout != HAL_MAX_DELAY)
1292 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1294 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1295 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE);
1296 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
1297 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
1298 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
1300 hirda->State= HAL_IRDA_STATE_TIMEOUT;
1302 /* Process Unlocked */
1303 __HAL_UNLOCK(hirda);
1317 #endif /* HAL_IRDA_MODULE_ENABLED */
1326 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/