Subversion Repositories DashDisplay

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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