672598c4d4b8e74aa20ba65315228ba3008655b6
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_irda.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_irda.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
7 * @brief IRDA HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the IrDA SIR ENDEC block (IrDA):
10 * + Initialization and de-initialization methods
11 * + IO operation methods
12 * + Peripheral Control methods
13 *
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 The IRDA HAL driver can be used as follows:
20
21 (#) Declare a IRDA_HandleTypeDef handle structure.
22 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
23 (##) Enable the USARTx interface clock.
24 (##) IRDA pins configuration:
25 (+++) Enable the clock for the IRDA GPIOs.
26 (+++) Configure these IRDA pins as alternate function pull-up.
27 (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
28 and HAL_IRDA_Receive_IT() APIs):
29 (+++) Configure the USARTx interrupt priority.
30 (+++) Enable the NVIC USART IRQ handle.
31 (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
32 and HAL_IRDA_Receive_DMA() APIs):
33 (+++) Declare a DMA handle structure for the Tx/Rx stream.
34 (+++) Enable the DMAx interface clock.
35 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
36 (+++) Configure the DMA Tx/Rx Stream.
37 (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
38 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
39
40 (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
41 and Mode(Receiver/Transmitter) in the hirda Init structure.
42
43 (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
44 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
45 by calling the customized HAL_IRDA_MspInit() API.
46 -@@- The specific IRDA interrupts (Transmission complete interrupt,
47 RXNE interrupt and Error Interrupts) will be managed using the macros
48 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
49
50 (#) Three operation modes are available within this driver :
51
52 *** Polling mode IO operation ***
53 =================================
54 [..]
55 (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
56 (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
57
58 *** Interrupt mode IO operation ***
59 ===================================
60 [..]
61 (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
62 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
63 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
64 (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
65 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
67 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
68 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
69
70 *** DMA mode IO operation ***
71 =============================
72 [..]
73 (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
74 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
75 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
76 (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
77 (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
79 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
80 add his own code by customization of function pointer HAL_IRDA_ErrorCallback
81
82 *** IRDA HAL driver macros list ***
83 ===================================
84 [..]
85 Below the list of most used macros in IRDA HAL driver.
86
87 (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
88 (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
89 (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not
90 (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag
91 (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt
92 (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt
93
94 (@) You can refer to the IRDA HAL driver header file for more useful macros
95
96 @endverbatim
97 ******************************************************************************
98 * @attention
99 *
100 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
101 *
102 * Redistribution and use in source and binary forms, with or without modification,
103 * are permitted provided that the following conditions are met:
104 * 1. Redistributions of source code must retain the above copyright notice,
105 * this list of conditions and the following disclaimer.
106 * 2. Redistributions in binary form must reproduce the above copyright notice,
107 * this list of conditions and the following disclaimer in the documentation
108 * and/or other materials provided with the distribution.
109 * 3. Neither the name of STMicroelectronics nor the names of its contributors
110 * may be used to endorse or promote products derived from this software
111 * without specific prior written permission.
112 *
113 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
114 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
115 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
117 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
118 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
119 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
120 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
121 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
122 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123 *
124 ******************************************************************************
125 */
126
127 /* Includes ------------------------------------------------------------------*/
128 #include "stm32f7xx_hal.h"
129
130 /** @addtogroup STM32F7xx_HAL_Driver
131 * @{
132 */
133
134 /** @defgroup IRDA IRDA
135 * @brief HAL IRDA module driver
136 * @{
137 */
138 #ifdef HAL_IRDA_MODULE_ENABLED
139
140 /* Private typedef -----------------------------------------------------------*/
141 /* Private define ------------------------------------------------------------*/
142 /** @addtogroup IRDA_Private_Constants
143 * @{
144 */
145 #define TEACK_REACK_TIMEOUT 1000U
146 #define HAL_IRDA_TXDMA_TIMEOUTVALUE 22000U
147 #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
148 | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))
149 /**
150 * @}
151 */
152 /* Private macro -------------------------------------------------------------*/
153 /* Private variables ---------------------------------------------------------*/
154 /* Private function prototypes -----------------------------------------------*/
155 /** @addtogroup IRDA_Private_Functions
156 * @{
157 */
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_EndTxTransfer(IRDA_HandleTypeDef *hirda);
165 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
166 static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
167 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
168 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
169 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
170 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
171 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
172 /**
173 * @}
174 */
175 /* Exported functions --------------------------------------------------------*/
176 /** @defgroup IRDA_Exported_Functions IrDA Exported Functions
177 * @{
178 */
179
180 /** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
181 * @brief Initialization and Configuration functions
182 *
183 @verbatim
184
185 ===============================================================================
186 ##### Initialization and Configuration functions #####
187 ===============================================================================
188 [..]
189 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
190 in IrDA mode.
191 (+) For the asynchronous mode only these parameters can be configured:
192 (++) BaudRate
193 (++) WordLength
194 (++) Parity: If the parity is enabled, then the MSB bit of the data written
195 in the data register is transmitted but is changed by the parity bit.
196 Depending on the frame length defined by the M bit (8-bits or 9-bits),
197 please refer to Reference manual for possible IRDA frame formats.
198 (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
199 not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
200 specification specifies a minimum of 10 ms delay between transmission and
201 reception (IrDA is a half duplex protocol).
202 (++) Mode: Receiver/transmitter modes
203 (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
204 [..]
205 The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
206 are available in reference manual).
207
208 @endverbatim
209 * @{
210 */
211
212 /**
213 * @brief Initializes the IRDA mode according to the specified
214 * parameters in the IRDA_InitTypeDef and create the associated handle.
215 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
216 * the configuration information for the specified IRDA module.
217 * @retval HAL status
218 */
219 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
220 {
221 /* Check the IRDA handle allocation */
222 if(hirda == NULL)
223 {
224 return HAL_ERROR;
225 }
226
227 /* Check the USART/UART associated to the IRDA handle */
228 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
229
230 if(hirda->gState == HAL_IRDA_STATE_RESET)
231 {
232 /* Allocate lock resource and initialize it */
233 hirda->Lock = HAL_UNLOCKED;
234 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
235 HAL_IRDA_MspInit(hirda);
236 }
237
238 hirda->gState = HAL_IRDA_STATE_BUSY;
239
240 /* Disable the Peripheral to update the configuration registers */
241 __HAL_IRDA_DISABLE(hirda);
242
243 /* Set the IRDA Communication parameters */
244 IRDA_SetConfig(hirda);
245
246 /* In IRDA mode, the following bits must be kept cleared:
247 - LINEN, STOP and CLKEN bits in the USART_CR2 register,
248 - SCEN and HDSEL bits in the USART_CR3 register.*/
249 CLEAR_BIT(hirda->Instance->CR3, USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN);
250 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_SCEN | USART_CR3_HDSEL);
251
252 /* set the UART/USART in IRDA mode */
253 SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
254
255 /* Enable the Peripheral */
256 __HAL_IRDA_ENABLE(hirda);
257
258 /* TEACK and/or REACK to check before moving hirda->State to Ready */
259 return (IRDA_CheckIdleState(hirda));
260 }
261
262 /**
263 * @brief DeInitializes the IRDA peripheral
264 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
265 * the configuration information for the specified IRDA module.
266 * @retval HAL status
267 */
268 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
269 {
270 /* Check the IRDA handle allocation */
271 if(hirda == NULL)
272 {
273 return HAL_ERROR;
274 }
275
276 /* Check the parameters */
277 assert_param(IS_IRDA_INSTANCE(hirda->Instance));
278
279 hirda->gState = HAL_IRDA_STATE_BUSY;
280
281 /* DeInit the low level hardware */
282 HAL_IRDA_MspDeInit(hirda);
283 /* Disable the Peripheral */
284 __HAL_IRDA_DISABLE(hirda);
285
286 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
287 hirda->gState = HAL_IRDA_STATE_RESET;
288 hirda->RxState = HAL_IRDA_STATE_RESET;
289
290 /* Release Lock */
291 __HAL_UNLOCK(hirda);
292
293 return HAL_OK;
294 }
295
296 /**
297 * @brief IRDA MSP Init.
298 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
299 * the configuration information for the specified IRDA module.
300 * @retval None
301 */
302 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
303 {
304 /* Prevent unused argument(s) compilation warning */
305 UNUSED(hirda);
306
307 /* NOTE : This function Should not be modified, when the callback is needed,
308 the HAL_IRDA_MspInit could be implemented in the user file
309 */
310 }
311
312 /**
313 * @brief IRDA MSP DeInit.
314 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
315 * the configuration information for the specified IRDA module.
316 * @retval None
317 */
318 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
319 {
320 /* Prevent unused argument(s) compilation warning */
321 UNUSED(hirda);
322
323 /* NOTE : This function Should not be modified, when the callback is needed,
324 the HAL_IRDA_MspDeInit could be implemented in the user file
325 */
326 }
327
328 /**
329 * @}
330 */
331
332 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
333 * @brief IRDA Transmit/Receive functions
334 *
335 @verbatim
336 ===============================================================================
337 ##### IO operation functions #####
338 ===============================================================================
339 This subsection provides a set of functions allowing to manage the IRDA data transfers.
340 [..]
341 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
342 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
343 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
344 While receiving data, transmission should be avoided as the data to be transmitted
345 could be corrupted.
346
347 (#) There are two modes of transfer:
348 (++) Blocking mode: the communication is performed in polling mode.
349 The HAL status of all data processing is returned by the same function
350 after finishing transfer.
351 (++) No-Blocking mode: the communication is performed using Interrupts
352 or DMA, these API's return the HAL status.
353 The end of the data processing will be indicated through the
354 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
355 using DMA mode.
356 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
357 will be executed respectively at the end of the Transmit or Receive process
358 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
359
360 (#) Blocking mode API's are :
361 (++) HAL_IRDA_Transmit()
362 (++) HAL_IRDA_Receive()
363
364 (#) Non-Blocking mode API's with Interrupt are :
365 (++) HAL_IRDA_Transmit_IT()
366 (++) HAL_IRDA_Receive_IT()
367 (++) HAL_IRDA_IRQHandler()
368 (++) IRDA_Transmit_IT()
369 (++) IRDA_Receive_IT()
370
371 (#) Non-Blocking mode functions with DMA are :
372 (++) HAL_IRDA_Transmit_DMA()
373 (++) HAL_IRDA_Receive_DMA()
374
375 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
376 (++) HAL_IRDA_TxCpltCallback()
377 (++) HAL_IRDA_RxCpltCallback()
378 (++) HAL_IRDA_ErrorCallback()
379
380 @endverbatim
381 * @{
382 */
383
384 /**
385 * @brief Sends an amount of data in blocking mode.
386 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
387 * the configuration information for the specified IRDA module.
388 * @param pData: Pointer to data buffer
389 * @param Size: Amount of data to be sent
390 * @param Timeout: Specify timeout value
391 * @retval HAL status
392 */
393 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
394 {
395 uint16_t* tmp;
396 uint32_t tickstart = 0U;
397
398 /* Check that a Tx process is not already ongoing */
399 if(hirda->gState == HAL_IRDA_STATE_READY)
400 {
401 if((pData == NULL) || (Size == 0U))
402 {
403 return HAL_ERROR;
404 }
405
406 /* Process Locked */
407 __HAL_LOCK(hirda);
408 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
409 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
410
411 /* Init tickstart for timeout managment*/
412 tickstart = HAL_GetTick();
413
414 hirda->TxXferSize = Size;
415 hirda->TxXferCount = Size;
416 while(hirda->TxXferCount > 0U)
417 {
418 hirda->TxXferCount--;
419
420 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
421 {
422 return HAL_TIMEOUT;
423 }
424 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
425 {
426 tmp = (uint16_t*) pData;
427 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FFU);
428 pData +=2;
429 }
430 else
431 {
432 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFFU);
433 }
434 }
435
436 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
437 {
438 return HAL_TIMEOUT;
439 }
440
441 /* At end of Tx process, restore hirda->gState to Ready */
442 hirda->gState = HAL_IRDA_STATE_READY;
443
444 /* Process Unlocked */
445 __HAL_UNLOCK(hirda);
446
447 return HAL_OK;
448 }
449 else
450 {
451 return HAL_BUSY;
452 }
453 }
454
455 /**
456 * @brief Receive an amount of data in blocking mode.
457 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
458 * the configuration information for the specified IRDA module.
459 * @param pData: Pointer to data buffer
460 * @param Size: Amount of data to be received
461 * @param Timeout: Specify timeout value
462 * @retval HAL status
463 */
464 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
465 {
466 uint16_t* tmp;
467 uint16_t uhMask;
468 uint32_t tickstart = 0U;
469
470 /* Check that a Rx process is not already ongoing */
471 if(hirda->RxState == HAL_IRDA_STATE_READY)
472 {
473 if((pData == NULL) || (Size == 0U))
474 {
475 return HAL_ERROR;
476 }
477
478 /* Process Locked */
479 __HAL_LOCK(hirda);
480 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
481 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
482
483 /* Init tickstart for timeout managment*/
484 tickstart = HAL_GetTick();
485
486 hirda->RxXferSize = Size;
487 hirda->RxXferCount = Size;
488
489 /* Computation of the mask to apply to the RDR register
490 of the UART associated to the IRDA */
491 IRDA_MASK_COMPUTATION(hirda);
492 uhMask = hirda->Mask;
493
494 /* Check data remaining to be received */
495 while(hirda->RxXferCount > 0U)
496 {
497 hirda->RxXferCount--;
498
499 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
500 {
501 return HAL_TIMEOUT;
502 }
503 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
504 {
505 tmp = (uint16_t*) pData ;
506 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask);
507 pData +=2;
508 }
509 else
510 {
511 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
512 }
513 }
514
515 /* At end of Rx process, restore hirda->RxState to Ready */
516 hirda->RxState = HAL_IRDA_STATE_READY;
517
518 /* Process Unlocked */
519 __HAL_UNLOCK(hirda);
520
521 return HAL_OK;
522 }
523 else
524 {
525 return HAL_BUSY;
526 }
527 }
528
529 /**
530 * @brief Send an amount of data in non blocking mode.
531 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
532 * the configuration information for the specified IRDA module.
533 * @param pData: Pointer to data buffer
534 * @param Size: Amount of data to be sent
535 * @retval HAL status
536 */
537 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
538 {
539 /* Check that a Tx process is not already ongoing */
540 if(hirda->gState == HAL_IRDA_STATE_READY)
541 {
542 if((pData == NULL) || (Size == 0U))
543 {
544 return HAL_ERROR;
545 }
546
547 /* Process Locked */
548 __HAL_LOCK(hirda);
549
550 hirda->pTxBuffPtr = pData;
551 hirda->TxXferSize = Size;
552 hirda->TxXferCount = Size;
553
554 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
555 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
556
557 /* Process Unlocked */
558 __HAL_UNLOCK(hirda);
559
560 /* Enable the IRDA Transmit Complete Interrupt */
561 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
562
563 return HAL_OK;
564 }
565 else
566 {
567 return HAL_BUSY;
568 }
569 }
570
571 /**
572 * @brief Receives an amount of data in non blocking mode.
573 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
574 * the configuration information for the specified IRDA module.
575 * @param pData: Pointer to data buffer
576 * @param Size: Amount of data to be received
577 * @retval HAL status
578 */
579 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
580 {
581 /* Check that a Rx process is not already ongoing */
582 if(hirda->RxState == HAL_IRDA_STATE_READY)
583 {
584 if((pData == NULL) || (Size == 0U))
585 {
586 return HAL_ERROR;
587 }
588
589 /* Process Locked */
590 __HAL_LOCK(hirda);
591
592 hirda->pRxBuffPtr = pData;
593 hirda->RxXferSize = Size;
594 hirda->RxXferCount = Size;
595
596 /* Computation of the mask to apply to the RDR register
597 of the UART associated to the IRDA */
598 IRDA_MASK_COMPUTATION(hirda);
599
600 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
601 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
602
603 /* Process Unlocked */
604 __HAL_UNLOCK(hirda);
605
606 /* Enable the IRDA Parity Error Interrupt */
607 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
608
609 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
610 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
611
612 /* Enable the IRDA Data Register not empty Interrupt */
613 SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
614
615 return HAL_OK;
616 }
617 else
618 {
619 return HAL_BUSY;
620 }
621 }
622
623 /**
624 * @brief Sends an amount of data in non blocking mode.
625 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
626 * the configuration information for the specified IRDA module.
627 * @param pData: Pointer to data buffer
628 * @param Size: Amount of data to be sent
629 * @retval HAL status
630 */
631 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
632 {
633 uint32_t *tmp;
634
635 /* Check that a Tx process is not already ongoing */
636 if(hirda->gState == HAL_IRDA_STATE_READY)
637 {
638 if((pData == NULL) || (Size == 0U))
639 {
640 return HAL_ERROR;
641 }
642
643 /* Process Locked */
644 __HAL_LOCK(hirda);
645
646 hirda->pTxBuffPtr = pData;
647 hirda->TxXferSize = Size;
648 hirda->TxXferCount = Size;
649
650 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
651 hirda->gState = HAL_IRDA_STATE_BUSY_TX;
652
653 /* Set the IRDA DMA transfer complete callback */
654 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
655
656 /* Set the IRDA DMA half transfer complete callback */
657 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
658
659 /* Set the DMA error callback */
660 hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
661
662 /* Set the DMA abort callback */
663 hirda->hdmatx->XferAbortCallback = NULL;
664
665 /* Enable the IRDA transmit DMA channel */
666 tmp = (uint32_t*)&pData;
667 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);
668
669 /* Clear the TC flag in the SR register by writing 0 to it */
670 __HAL_IRDA_CLEAR_IT(hirda, IRDA_FLAG_TC);
671
672 /* Process Unlocked */
673 __HAL_UNLOCK(hirda);
674
675 /* Enable the DMA transfer for transmit request by setting the DMAT bit
676 in the IRDA CR3 register */
677 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
678
679 return HAL_OK;
680 }
681 else
682 {
683 return HAL_BUSY;
684 }
685 }
686
687 /**
688 * @brief Receives an amount of data in non blocking mode.
689 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
690 * the configuration information for the specified IRDA module.
691 * @param pData: Pointer to data buffer
692 * @param Size: Amount of data to be received
693 * @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
694 * @retval HAL status
695 */
696 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
697 {
698 uint32_t *tmp;
699
700 /* Check that a Rx process is not already ongoing */
701 if(hirda->RxState == HAL_IRDA_STATE_READY)
702 {
703 if((pData == NULL) || (Size == 0U))
704 {
705 return HAL_ERROR;
706 }
707
708 /* Process Locked */
709 __HAL_LOCK(hirda);
710
711 hirda->pRxBuffPtr = pData;
712 hirda->RxXferSize = Size;
713
714 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
715 hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
716
717 /* Set the IRDA DMA transfer complete callback */
718 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
719
720 /* Set the IRDA DMA half transfer complete callback */
721 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
722
723 /* Set the DMA error callback */
724 hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
725
726 /* Set the DMA abort callback */
727 hirda->hdmarx->XferAbortCallback = NULL;
728
729 /* Enable the DMA channel */
730 tmp = (uint32_t*)&pData;
731 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size);
732
733 /* Process Unlocked */
734 __HAL_UNLOCK(hirda);
735
736 /* Enable the IRDA Parity Error Interrupt */
737 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
738
739 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
740 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
741
742 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
743 in the USART CR3 register */
744 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
745
746 return HAL_OK;
747 }
748 else
749 {
750 return HAL_BUSY;
751 }
752 }
753
754 /**
755 * @brief Pauses the DMA Transfer.
756 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
757 * the configuration information for the specified IRDA module.
758 * @retval HAL status
759 */
760 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
761 {
762 /* Process Locked */
763 __HAL_LOCK(hirda);
764
765 if((hirda->gState == HAL_IRDA_STATE_BUSY_TX)&&
766 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)))
767 {
768 /* Disable the UART DMA Tx request */
769 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
770 }
771 if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX)&&
772 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)))
773 {
774 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
775 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
776 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
777
778 /* Disable the UART DMA Rx request */
779 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
780 }
781
782 /* Process Unlocked */
783 __HAL_UNLOCK(hirda);
784
785 return HAL_OK;
786 }
787
788 /**
789 * @brief Resumes the DMA Transfer.
790 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
791 * the configuration information for the specified UART module.
792 * @retval HAL status
793 */
794 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
795 {
796 /* Process Locked */
797 __HAL_LOCK(hirda);
798
799 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
800 {
801 /* Enable the UART DMA Tx request */
802 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
803 }
804 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
805 {
806 /* Clear the Overrun flag before resuming the Rx transfer*/
807 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
808
809 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
810 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
811 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
812
813 /* Enable the UART DMA Rx request */
814 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
815 }
816
817 /* Process Unlocked */
818 __HAL_UNLOCK(hirda);
819
820 return HAL_OK;
821 }
822
823 /**
824 * @brief Stops the DMA Transfer.
825 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
826 * the configuration information for the specified UART module.
827 * @retval HAL status
828 */
829 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
830 {
831 /* The Lock is not implemented on this API to allow the user application
832 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
833 HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback:
834 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
835 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
836 the stream and the corresponding call back is executed. */
837
838 /* Stop IRDA DMA Tx request if ongoing */
839 if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) &&
840 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)))
841 {
842 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
843
844 /* Abort the IRDA DMA Tx channel */
845 if(hirda->hdmatx != NULL)
846 {
847 HAL_DMA_Abort(hirda->hdmatx);
848 }
849 IRDA_EndTxTransfer(hirda);
850 }
851
852 /* Stop IRDA DMA Rx request if ongoing */
853 if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) &&
854 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)))
855 {
856 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
857
858 /* Abort the IRDA DMA Rx channel */
859 if(hirda->hdmarx != NULL)
860 {
861 HAL_DMA_Abort(hirda->hdmarx);
862 }
863 IRDA_EndRxTransfer(hirda);
864 }
865 return HAL_OK;
866 }
867
868 /**
869 * @brief DMA IRDA communication abort callback, when call by HAL services on Error
870 * (To be called at end of DMA Abort procedure following error occurrence).
871 * @param hdma: DMA handle.
872 * @retval None
873 */
874 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
875 {
876 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
877 hirda->RxXferCount = 0U;
878 hirda->TxXferCount = 0U;
879
880 HAL_IRDA_ErrorCallback(hirda);
881 }
882
883 /**
884 * @brief This function handles IRDA interrupt request.
885 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
886 * the configuration information for the specified IRDA module.
887 * @retval None
888 */
889 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
890 {
891 uint32_t isrflags, cr1its, cr3its, errorflags;
892
893 isrflags = READ_REG(hirda->Instance->ISR);
894 cr1its = READ_REG(hirda->Instance->CR1);
895 cr3its = READ_REG(hirda->Instance->CR3);
896
897 /* If no error occurs */
898 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
899 if (errorflags == RESET)
900 {
901 /* IRDA in mode Receiver ---------------------------------------------------*/
902 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
903 {
904 IRDA_Receive_IT(hirda);
905 /* Clear RXNE interrupt flag */
906 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
907 }
908 }
909
910 /* If some errors occur */
911 if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET))
912 {
913 /* IRDA parity error interrupt occurred -------------------------------------*/
914 if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
915 {
916 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
917 hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
918 }
919
920 /* IRDA frame error interrupt occurred --------------------------------------*/
921 if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
922 {
923 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
924 hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
925 }
926
927 /* IRDA noise error interrupt occurred --------------------------------------*/
928 if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
929 {
930 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
931 hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
932 }
933
934 /* IRDA Over-Run interrupt occurred -----------------------------------------*/
935 if(((isrflags & USART_ISR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
936 {
937 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
938 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
939 }
940
941 /* Call IRDA Error Call back function if need be --------------------------*/
942 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
943 {
944 /* IRDA in mode Receiver ---------------------------------------------------*/
945 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
946 {
947 IRDA_Receive_IT(hirda);
948 }
949
950 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
951 consider error as blocking */
952 if (((hirda->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
953 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)))
954 {
955 /* Blocking error : transfer is aborted
956 Set the IRDA state ready to be able to start again the process,
957 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
958 IRDA_EndRxTransfer(hirda);
959
960 /* Disable the IRDA DMA Rx request if enabled */
961 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
962 {
963 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
964
965 /* Abort the IRDA DMA Rx channel */
966 if(hirda->hdmarx != NULL)
967 {
968 /* Set the IRDA DMA Abort callback :
969 will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
970 hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
971
972 /* Abort DMA RX */
973 if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
974 {
975 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
976 hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
977 }
978 }
979 else
980 {
981 /* Call user error callback */
982 HAL_IRDA_ErrorCallback(hirda);
983 }
984 }
985 else
986 {
987 /* Call user error callback */
988 HAL_IRDA_ErrorCallback(hirda);
989 }
990 }
991 else
992 {
993 /* Non Blocking error : transfer could go on.
994 Error is notified to user through user error callback */
995 HAL_IRDA_ErrorCallback(hirda);
996 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
997 }
998 }
999 return;
1000
1001 } /* End if some error occurs */
1002
1003 /* IRDA in mode Transmitter ------------------------------------------------*/
1004 if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
1005 {
1006 IRDA_Transmit_IT(hirda);
1007 return;
1008 }
1009
1010 /* IRDA in mode Transmitter (transmission end) -----------------------------*/
1011 if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
1012 {
1013 IRDA_EndTransmit_IT(hirda);
1014 return;
1015 }
1016 }
1017
1018 /**
1019 * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
1020 * @param hirda: IRDA handle.
1021 * @retval None
1022 */
1023 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
1024 {
1025 /* Disable TXEIE and TCIE interrupts */
1026 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1027
1028 /* At end of Tx process, restore hirda->gState to Ready */
1029 hirda->gState = HAL_IRDA_STATE_READY;
1030 }
1031
1032 /**
1033 * @brief End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
1034 * @param hirda: IRDA handle.
1035 * @retval None
1036 */
1037 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
1038 {
1039 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1040 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1041 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1042
1043 /* At end of Rx process, restore huart->RxState to Ready */
1044 hirda->RxState = HAL_IRDA_STATE_READY;
1045 }
1046
1047 /**
1048 * @brief Tx Transfer complete callbacks.
1049 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1050 * the configuration information for the specified IRDA module.
1051 * @retval None
1052 */
1053 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1054 {
1055 /* Prevent unused argument(s) compilation warning */
1056 UNUSED(hirda);
1057
1058 /* NOTE : This function should not be modified, when the callback is needed,
1059 the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file
1060 */
1061 }
1062
1063 /**
1064 * @brief Tx Half Transfer completed callbacks.
1065 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1066 * the configuration information for the specified USART module.
1067 * @retval None
1068 */
1069 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
1070 {
1071 /* Prevent unused argument(s) compilation warning */
1072 UNUSED(hirda);
1073
1074 /* NOTE : This function should not be modified, when the callback is needed,
1075 the HAL_IRDA_TxCpltCallback can be implemented in the user file
1076 */
1077 }
1078
1079 /**
1080 * @brief Rx Transfer complete callbacks.
1081 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1082 * the configuration information for the specified IRDA module.
1083 * @retval None
1084 */
1085 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
1086 {
1087 /* Prevent unused argument(s) compilation warning */
1088 UNUSED(hirda);
1089
1090 /* NOTE : This function should not be modified, when the callback is needed,
1091 the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file
1092 */
1093 }
1094
1095 /**
1096 * @brief Rx Half Transfer complete callbacks.
1097 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1098 * the configuration information for the specified IRDA module.
1099 * @retval None
1100 */
1101 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
1102 {
1103 /* Prevent unused argument(s) compilation warning */
1104 UNUSED(hirda);
1105
1106 /* NOTE : This function should not be modified, when the callback is needed,
1107 the HAL_IRDA_RxCpltCallback can be implemented in the user file
1108 */
1109 }
1110
1111 /**
1112 * @brief IRDA error callbacks.
1113 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1114 * the configuration information for the specified IRDA module.
1115 * @retval None
1116 */
1117 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
1118 {
1119 /* Prevent unused argument(s) compilation warning */
1120 UNUSED(hirda);
1121
1122 /* NOTE : This function should not be modified, when the callback is needed,
1123 the HAL_IRDA_ErrorCallback can be implemented in the user file
1124 */
1125 }
1126
1127 /**
1128 * @}
1129 */
1130
1131 /** @defgroup IRDA_Exported_Functions_Group3 Peripheral Control functions
1132 * @brief IRDA control functions
1133 *
1134 @verbatim
1135 ===============================================================================
1136 ##### Peripheral Control functions #####
1137 ===============================================================================
1138 [..]
1139 This subsection provides a set of functions allowing to control the IRDA.
1140 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IRDA peripheral.
1141 (+) IRDA_SetConfig() API is used to configure the IRDA communications parameters.
1142 @endverbatim
1143 * @{
1144 */
1145
1146 /**
1147 * @brief Returns the IRDA state.
1148 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1149 * the configuration information for the specified IRDA module.
1150 * @retval HAL state
1151 */
1152 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
1153 {
1154 uint32_t temp1 = 0x00U, temp2 = 0x00U;
1155 temp1 = hirda->gState;
1156 temp2 = hirda->RxState;
1157
1158 return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
1159 }
1160
1161 /**
1162 * @brief Return the IRDA error code
1163 * @param hirda : pointer to a IRDA_HandleTypeDef structure that contains
1164 * the configuration information for the specified IRDA.
1165 * @retval IRDA Error Code
1166 */
1167 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
1168 {
1169 uint32_t temp1 = 0x00U, temp2 = 0x00U;
1170 temp1 = hirda->gState;
1171 temp2 = hirda->RxState;
1172
1173 return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
1174 }
1175
1176 /**
1177 * @}
1178 */
1179
1180 /**
1181 * @brief Configure the IRDA peripheral
1182 * @param hirda: irda handle
1183 * @retval None
1184 */
1185 static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
1186 {
1187 uint32_t tmpreg = 0x00000000U;
1188 uint32_t clocksource = 0x00000000U;
1189
1190 /* Check the communication parameters */
1191 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
1192 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
1193 assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
1194 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
1195 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
1196 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
1197 /*-------------------------- USART CR1 Configuration -----------------------*/
1198 /* Configure the IRDA Word Length, Parity and transfer Mode:
1199 Set the M bits according to hirda->Init.WordLength value
1200 Set PCE and PS bits according to hirda->Init.Parity value
1201 Set TE and RE bits according to hirda->Init.Mode value */
1202 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
1203
1204 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
1205
1206 /*-------------------------- USART CR3 Configuration -----------------------*/
1207 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
1208
1209 /*-------------------------- USART GTPR Configuration ----------------------*/
1210 MODIFY_REG(hirda->Instance->GTPR, (uint32_t)USART_GTPR_PSC, hirda->Init.Prescaler);
1211
1212 /*-------------------------- USART BRR Configuration -----------------------*/
1213 IRDA_GETCLOCKSOURCE(hirda, clocksource);
1214 switch (clocksource)
1215 {
1216 case IRDA_CLOCKSOURCE_PCLK1:
1217 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hirda->Init.BaudRate/2))/ hirda->Init.BaudRate);
1218 break;
1219 case IRDA_CLOCKSOURCE_PCLK2:
1220 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hirda->Init.BaudRate/2))/ hirda->Init.BaudRate);
1221 break;
1222 case IRDA_CLOCKSOURCE_HSI:
1223 hirda->Instance->BRR = (uint16_t)((HSI_VALUE + (hirda->Init.BaudRate/2))/ hirda->Init.BaudRate);
1224 break;
1225 case IRDA_CLOCKSOURCE_SYSCLK:
1226 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hirda->Init.BaudRate/2))/ hirda->Init.BaudRate);
1227 break;
1228 case IRDA_CLOCKSOURCE_LSE:
1229 hirda->Instance->BRR = (uint16_t)((LSE_VALUE + (hirda->Init.BaudRate/2))/ hirda->Init.BaudRate);
1230 break;
1231 default:
1232 break;
1233 }
1234 }
1235
1236 /**
1237 * @brief Check the IRDA Idle State
1238 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1239 * the configuration information for the specified IRDA module.
1240 * @retval HAL status
1241 */
1242 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
1243 {
1244 uint32_t tickstart = 0U;
1245
1246 /* Initialize the IRDA ErrorCode */
1247 hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1248
1249 /* Init tickstart for timeout managment*/
1250 tickstart = HAL_GetTick();
1251
1252 /* Check if the Transmitter is enabled */
1253 if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1254 {
1255 /* Wait until TEACK flag is set */
1256 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, TEACK_REACK_TIMEOUT) != HAL_OK)
1257 {
1258 return HAL_TIMEOUT;
1259 }
1260 }
1261 /* Check if the Receiver is enabled */
1262 if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1263 {
1264 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, TEACK_REACK_TIMEOUT) != HAL_OK)
1265 {
1266 return HAL_TIMEOUT;
1267 }
1268 }
1269 /* Process Unlocked */
1270 __HAL_UNLOCK(hirda);
1271
1272 /* Initialize the IRDA state*/
1273 hirda->gState= HAL_IRDA_STATE_READY;
1274 hirda->RxState= HAL_IRDA_STATE_READY;
1275
1276 return HAL_OK;
1277 }
1278
1279 /**
1280 * @brief This function handles IRDA Communication Timeout.
1281 * @param hirda pointer to a IRDA_HandleTypeDef structure that contains
1282 * the configuration information for the specified IRDA module.
1283 * @param Flag specifies the IRDA flag to check.
1284 * @param Status The new Flag status (SET or RESET).
1285 * @param Tickstart Tick start value
1286 * @param Timeout Timeout duration
1287 * @retval HAL status
1288 */
1289 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
1290 {
1291 /* Wait until flag is set */
1292 while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
1293 {
1294 /* Check for the Timeout */
1295 if(Timeout != HAL_MAX_DELAY)
1296 {
1297 if((Timeout == 0)||((HAL_GetTick() - Tickstart ) > Timeout))
1298 {
1299 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1300 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
1301 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1302
1303 hirda->gState= HAL_IRDA_STATE_READY;
1304 hirda->RxState= HAL_IRDA_STATE_READY;
1305
1306 /* Process Unlocked */
1307 __HAL_UNLOCK(hirda);
1308
1309 return HAL_TIMEOUT;
1310 }
1311 }
1312 }
1313 return HAL_OK;
1314 }
1315
1316 /**
1317 * @brief Send an amount of data in non blocking mode.
1318 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1319 * the configuration information for the specified IRDA module.
1320 * @retval HAL status
1321 */
1322 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
1323 {
1324 uint16_t* tmp;
1325
1326 /* Check that a Tx process is ongoing */
1327 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1328 {
1329 if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
1330 {
1331 tmp = (uint16_t*) hirda->pTxBuffPtr;
1332 hirda->Instance->RDR = (uint16_t)(*tmp & (uint16_t)0x01FFU);
1333 if(hirda->Init.Parity == IRDA_PARITY_NONE)
1334 {
1335 hirda->pTxBuffPtr += 2U;
1336 }
1337 else
1338 {
1339 hirda->pTxBuffPtr += 1U;
1340 }
1341 }
1342 else
1343 {
1344 hirda->Instance->RDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FFU);
1345 }
1346
1347 if(--hirda->TxXferCount == 0U)
1348 {
1349 /* Disable the IRDA Transmit Data Register Empty Interrupt */
1350 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
1351
1352 /* Enable the IRDA Transmit Complete Interrupt */
1353 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1354 }
1355
1356 return HAL_OK;
1357 }
1358 else
1359 {
1360 return HAL_BUSY;
1361 }
1362 }
1363
1364 /**
1365 * @brief Wraps up transmission in non blocking mode.
1366 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1367 * the configuration information for the specified IRDA module.
1368 * @retval HAL status
1369 */
1370 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
1371 {
1372 /* Disable the IRDA Transmit Complete Interrupt */
1373 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1374
1375 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1376 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1377
1378 /* Tx process is ended, restore hirda->gState to Ready */
1379 hirda->gState = HAL_IRDA_STATE_READY;
1380
1381 HAL_IRDA_TxCpltCallback(hirda);
1382
1383 return HAL_OK;
1384 }
1385
1386 /**
1387 * @brief Receive an amount of data in non blocking mode.
1388 * Function called under interruption only, once
1389 * interruptions have been enabled by HAL_IRDA_Receive_IT()
1390 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
1391 * the configuration information for the specified IRDA module.
1392 * @retval HAL status
1393 */
1394 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
1395 {
1396 uint16_t* tmp;
1397 uint16_t uhdata;
1398 uint16_t uhMask = hirda->Mask;
1399
1400 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1401 {
1402 uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
1403 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1404 {
1405 tmp = (uint16_t*) hirda->pRxBuffPtr ;
1406 *tmp = (uint16_t)(uhdata & uhMask);
1407 hirda->pRxBuffPtr +=2U;
1408 }
1409 else
1410 {
1411 *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask);
1412 }
1413
1414 if(--hirda->RxXferCount == 0U)
1415 {
1416 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
1417
1418 /* Disable the IRDA Parity Error Interrupt */
1419 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1420
1421 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1422 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1423
1424 /* Rx process is completed, restore hirda->RxState to Ready */
1425 hirda->RxState = HAL_IRDA_STATE_READY;
1426
1427 HAL_IRDA_RxCpltCallback(hirda);
1428
1429 return HAL_OK;
1430 }
1431 return HAL_OK;
1432 }
1433 else
1434 {
1435 /* Clear RXNE interrupt flag */
1436 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
1437 return HAL_BUSY;
1438 }
1439 }
1440
1441 /**
1442 * @brief DMA IRDA Tx transfer completed callback
1443 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1444 * the configuration information for the specified DMA module.
1445 * @retval None
1446 */
1447 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1448 {
1449 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1450
1451 /* DMA Normal mode*/
1452 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1453 {
1454 hirda->TxXferCount = 0U;
1455
1456 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1457 in the IRDA CR3 register */
1458 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1459
1460 /* Enable the IRDA Transmit Complete Interrupt */
1461 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
1462 }
1463 /* DMA Circular mode */
1464 else
1465 {
1466 HAL_IRDA_TxCpltCallback(hirda);
1467 }
1468 }
1469
1470 /**
1471 * @brief DMA IRDA receive process half complete callback
1472 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1473 * the configuration information for the specified DMA module.
1474 * @retval None
1475 */
1476 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
1477 {
1478 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1479
1480 HAL_IRDA_TxHalfCpltCallback(hirda);
1481 }
1482
1483 /**
1484 * @brief DMA IRDA Rx Transfer completed callback
1485 * @param hdma: DMA handle
1486 * @retval None
1487 */
1488 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1489 {
1490 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1491
1492 /* DMA Normal mode */
1493 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1494 {
1495 hirda->RxXferCount = 0U;
1496
1497 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1498 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1499 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1500
1501 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1502 in the IRDA CR3 register */
1503 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1504
1505 /* At end of Rx process, restore hirda->RxState to Ready */
1506 hirda->RxState = HAL_IRDA_STATE_READY;
1507 }
1508
1509 HAL_IRDA_RxCpltCallback(hirda);
1510 }
1511
1512 /**
1513 * @brief DMA IRDA receive process half complete callback
1514 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1515 * the configuration information for the specified DMA module.
1516 * @retval None
1517 */
1518 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
1519 {
1520 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1521
1522 HAL_IRDA_RxHalfCpltCallback(hirda);
1523 }
1524
1525 /**
1526 * @brief DMA IRDA communication error callback
1527 * @param hdma: DMA handle
1528 * @retval None
1529 */
1530 static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
1531 {
1532 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1533
1534 hirda->RxXferCount = 0U;
1535 hirda->TxXferCount = 0U;
1536
1537 /* Stop IRDA DMA Tx request if ongoing */
1538 if ( (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1539 &&(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) )
1540 {
1541 IRDA_EndTxTransfer(hirda);
1542 }
1543
1544 /* Stop IRDA DMA Rx request if ongoing */
1545 if ( (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1546 &&(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) )
1547 {
1548 IRDA_EndRxTransfer(hirda);
1549 }
1550
1551 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
1552
1553 HAL_IRDA_ErrorCallback(hirda);
1554 }
1555
1556 /**
1557 * @}
1558 */
1559
1560 /**
1561 * @}
1562 */
1563
1564 #endif /* HAL_IRDA_MODULE_ENABLED */
1565
1566 /**
1567 * @}
1568 */
1569
1570 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1571