Subversion Repositories FuelGauge

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_hal_irda.c
4
  * @author  MCD Application Team
5
  * @brief   IRDA HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the IrDA (Infrared Data Association) Peripheral
8
  *          (IRDA)
9
  *           + Initialization and de-initialization functions
10
  *           + IO operation functions
11
  *           + Peripheral State and Errors functions
12
  *           + Peripheral Control functions
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 (eg. IRDA_HandleTypeDef hirda).
22
    (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API
23
        in setting the associated USART or UART in IRDA mode:
24
        (++) Enable the USARTx/UARTx interface clock.
25
        (++) USARTx/UARTx pins configuration:
26
            (+++) Enable the clock for the USARTx/UARTx GPIOs.
27
            (+++) Configure these USARTx/UARTx 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/UARTx interrupt priority.
31
            (+++) Enable the NVIC USARTx/UARTx IRQ handle.
32
            (+++) The specific IRDA interrupts (Transmission complete interrupt,
33
                  RXNE interrupt and Error Interrupts) will be managed using the macros
34
                  __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
35
 
36
        (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
37
             and HAL_IRDA_Receive_DMA() APIs):
38
            (+++) Declare a DMA handle structure for the Tx/Rx channel.
39
            (+++) Enable the DMAx interface clock.
40
            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
41
            (+++) Configure the DMA Tx/Rx channel.
42
            (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
6 mjames 43
            (+++) Configure the priority and enable the NVIC for the transfer
44
                  complete interrupt on the DMA Tx/Rx channel.
2 mjames 45
 
46
    (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter),
47
        the normal or low power mode and the clock prescaler in the hirda handle Init structure.
48
 
49
    (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
50
        (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
51
             by calling the customized HAL_IRDA_MspInit() API.
52
 
53
         -@@- The specific IRDA interrupts (Transmission complete interrupt,
54
             RXNE interrupt and Error Interrupts) will be managed using the macros
55
             __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
56
 
57
    (#) Three operation modes are available within this driver :
58
 
59
     *** Polling mode IO operation ***
60
     =================================
61
     [..]
62
       (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
63
       (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
64
 
65
     *** Interrupt mode IO operation ***
66
     ===================================
67
     [..]
68
       (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT()
69
       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
70
            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
71
       (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT()
72
       (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
73
            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
74
       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
75
            add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
76
 
77
     *** DMA mode IO operation ***
78
     ==============================
79
     [..]
80
       (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
81
       (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can
82
            add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback()
83
       (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can
84
            add his own code by customization of function pointer HAL_IRDA_TxCpltCallback()
85
       (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA()
86
       (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can
87
            add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback()
88
       (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can
89
            add his own code by customization of function pointer HAL_IRDA_RxCpltCallback()
90
       (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
91
            add his own code by customization of function pointer HAL_IRDA_ErrorCallback()
92
 
93
     *** IRDA HAL driver macros list ***
94
     ====================================
95
     [..]
96
       Below the list of most used macros in IRDA HAL driver.
97
 
98
       (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
99
       (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
100
       (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
101
       (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
102
       (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
103
       (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
104
       (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled
105
 
106
     [..]
107
       (@) You can refer to the IRDA HAL driver header file for more useful macros
108
 
109
    ##### Callback registration #####
110
    ==================================
111
 
112
    [..]
113
    The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1
114
    allows the user to configure dynamically the driver callbacks.
115
 
116
    [..]
6 mjames 117
    Use Function HAL_IRDA_RegisterCallback() to register a user callback.
118
    Function HAL_IRDA_RegisterCallback() allows to register following callbacks:
2 mjames 119
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
120
    (+) TxCpltCallback            : Tx Complete Callback.
121
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
122
    (+) RxCpltCallback            : Rx Complete Callback.
123
    (+) ErrorCallback             : Error Callback.
124
    (+) AbortCpltCallback         : Abort Complete Callback.
125
    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
126
    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
127
    (+) MspInitCallback           : IRDA MspInit.
128
    (+) MspDeInitCallback         : IRDA MspDeInit.
129
    This function takes as parameters the HAL peripheral handle, the Callback ID
130
    and a pointer to the user callback function.
131
 
132
    [..]
6 mjames 133
    Use function HAL_IRDA_UnRegisterCallback() to reset a callback to the default
2 mjames 134
    weak (surcharged) function.
6 mjames 135
    HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle,
2 mjames 136
    and the Callback ID.
137
    This function allows to reset following callbacks:
138
    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
139
    (+) TxCpltCallback            : Tx Complete Callback.
140
    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
141
    (+) RxCpltCallback            : Rx Complete Callback.
142
    (+) ErrorCallback             : Error Callback.
143
    (+) AbortCpltCallback         : Abort Complete Callback.
144
    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
145
    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
146
    (+) MspInitCallback           : IRDA MspInit.
147
    (+) MspDeInitCallback         : IRDA MspDeInit.
148
 
149
    [..]
6 mjames 150
    By default, after the HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET
2 mjames 151
    all callbacks are set to the corresponding weak (surcharged) functions:
6 mjames 152
    examples HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxHalfCpltCallback().
2 mjames 153
    Exception done for MspInit and MspDeInit functions that are respectively
6 mjames 154
    reset to the legacy weak (surcharged) functions in the HAL_IRDA_Init()
155
    and HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand).
156
    If not, MspInit or MspDeInit are not null, the HAL_IRDA_Init() and HAL_IRDA_DeInit()
2 mjames 157
    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
158
 
159
    [..]
160
    Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only.
161
    Exception done MspInit/MspDeInit that can be registered/unregistered
162
    in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user)
163
    MspInit/DeInit callbacks can be used during the Init/DeInit.
164
    In that case first register the MspInit/MspDeInit user callbacks
6 mjames 165
    using HAL_IRDA_RegisterCallback() before calling HAL_IRDA_DeInit()
166
    or HAL_IRDA_Init() function.
2 mjames 167
 
168
    [..]
169
    When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or
170
    not defined, the callback registration feature is not available
171
    and weak (surcharged) callbacks are used.
172
 
173
  @endverbatim
174
  ******************************************************************************
175
  * @attention
176
  *
177
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
178
  * All rights reserved.</center></h2>
179
  *
180
  * This software component is licensed by ST under BSD 3-Clause license,
181
  * the "License"; You may not use this file except in compliance with the
182
  * License. You may obtain a copy of the License at:
183
  *                        opensource.org/licenses/BSD-3-Clause
184
  *
185
  ******************************************************************************
186
  */
187
 
188
/* Includes ------------------------------------------------------------------*/
189
#include "stm32f0xx_hal.h"
190
 
191
#if defined(USART_IRDA_SUPPORT)
192
/** @addtogroup STM32F0xx_HAL_Driver
193
  * @{
194
  */
195
 
196
/** @defgroup IRDA IRDA
197
  * @brief HAL IRDA module driver
198
  * @{
199
  */
200
 
201
#ifdef HAL_IRDA_MODULE_ENABLED
202
 
203
/* Private typedef -----------------------------------------------------------*/
204
/* Private define ------------------------------------------------------------*/
205
/** @defgroup IRDA_Private_Constants IRDA Private Constants
206
  * @{
207
  */
208
#define IRDA_TEACK_REACK_TIMEOUT            1000U                                   /*!< IRDA TX or RX enable acknowledge time-out value  */
209
 
210
#define IRDA_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE \
211
                                     | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE))  /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */
212
 
213
#define USART_BRR_MIN    0x10U        /*!< USART BRR minimum authorized value */
214
 
215
#define USART_BRR_MAX    0x0000FFFFU  /*!< USART BRR maximum authorized value */
216
/**
217
  * @}
218
  */
219
 
220
/* Private macros ------------------------------------------------------------*/
221
/** @defgroup IRDA_Private_Macros IRDA Private Macros
222
  * @{
223
  */
224
/** @brief  BRR division operation to set BRR register in 16-bit oversampling mode.
225
  * @param  __PCLK__ IRDA clock source.
226
  * @param  __BAUD__ Baud rate set by the user.
227
  * @retval Division result
228
  */
229
#define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__)  (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__))
230
/**
231
  * @}
232
  */
233
 
234
/* Private variables ---------------------------------------------------------*/
235
/* Private function prototypes -----------------------------------------------*/
236
/** @addtogroup IRDA_Private_Functions
237
  * @{
238
  */
239
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
240
void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda);
241
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
242
static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
243
static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda);
244
static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
245
                                                     uint32_t Tickstart, uint32_t Timeout);
246
static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
247
static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
248
static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
249
static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
250
static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
251
static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
252
static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
253
static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
254
static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
255
static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
256
static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
257
static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
258
static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
259
static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
260
static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
261
/**
262
  * @}
263
  */
264
 
265
/* Exported functions --------------------------------------------------------*/
266
 
267
/** @defgroup IRDA_Exported_Functions IRDA Exported Functions
268
  * @{
269
  */
270
 
271
/** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions
272
  *  @brief    Initialization and Configuration functions
273
  *
274
@verbatim
275
  ==============================================================================
276
              ##### Initialization and Configuration functions #####
277
  ==============================================================================
278
  [..]
279
  This subsection provides a set of functions allowing to initialize the USARTx
280
  in asynchronous IRDA mode.
281
  (+) For the asynchronous mode only these parameters can be configured:
282
      (++) Baud Rate
283
      (++) Word Length
284
      (++) Parity: If the parity is enabled, then the MSB bit of the data written
285
           in the data register is transmitted but is changed by the parity bit.
286
      (++) Power mode
287
      (++) Prescaler setting
288
      (++) Receiver/transmitter modes
289
 
290
  [..]
291
  The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures
292
  (details for the procedures are available in reference manual).
293
 
294
@endverbatim
295
 
296
  Depending on the frame length defined either by the M bit (8-bits or 9-bits)
6 mjames 297
  or by the M1 and M0 bits (7-bit, 8-bit or 9-bit), the possible IRDA frame
2 mjames 298
  formats are listed in the following table.
299
 
300
    Table 1. IRDA frame format.
301
    +-----------------------------------------------------------------------+
302
    |       M bit       |  PCE bit  |             IRDA frame                |
303
    |-------------------|-----------|---------------------------------------|
304
    |         0         |     0     |    | SB |    8-bit data   | STB |     |
305
    |-------------------|-----------|---------------------------------------|
306
    |         0         |     1     |    | SB | 7-bit data | PB | STB |     |
307
    |-------------------|-----------|---------------------------------------|
308
    |         1         |     0     |    | SB |    9-bit data   | STB |     |
309
    |-------------------|-----------|---------------------------------------|
310
    |         1         |     1     |    | SB | 8-bit data | PB | STB |     |
311
    +-----------------------------------------------------------------------+
312
    |  M1 bit |  M0 bit |  PCE bit  |             IRDA frame                |
313
    |---------|---------|-----------|---------------------------------------|
314
    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
315
    |---------|---------|-----------|---------------------------------------|
316
    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
317
    |---------|---------|-----------|---------------------------------------|
318
    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
319
    |---------|---------|-----------|---------------------------------------|
320
    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
321
    |---------|---------|-----------|---------------------------------------|
322
    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
323
    |---------|---------|-----------|---------------------------------------|
324
    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
325
    +-----------------------------------------------------------------------+
326
 
327
  * @{
328
  */
329
 
330
/**
331
  * @brief Initialize the IRDA mode according to the specified
332
  *        parameters in the IRDA_InitTypeDef and initialize the associated handle.
333
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
334
  *               the configuration information for the specified IRDA module.
335
  * @retval HAL status
336
  */
337
HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
338
{
339
  /* Check the IRDA handle allocation */
340
  if (hirda == NULL)
341
  {
342
    return HAL_ERROR;
343
  }
344
 
345
  /* Check the USART/UART associated to the IRDA handle */
346
  assert_param(IS_IRDA_INSTANCE(hirda->Instance));
347
 
348
  if (hirda->gState == HAL_IRDA_STATE_RESET)
349
  {
350
    /* Allocate lock resource and initialize it */
351
    hirda->Lock = HAL_UNLOCKED;
352
 
353
#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
354
    IRDA_InitCallbacksToDefault(hirda);
355
 
356
    if (hirda->MspInitCallback == NULL)
357
    {
358
      hirda->MspInitCallback = HAL_IRDA_MspInit;
359
    }
360
 
361
    /* Init the low level hardware */
362
    hirda->MspInitCallback(hirda);
363
#else
364
    /* Init the low level hardware : GPIO, CLOCK */
365
    HAL_IRDA_MspInit(hirda);
366
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
367
  }
368
 
369
  hirda->gState = HAL_IRDA_STATE_BUSY;
370
 
371
  /* Disable the Peripheral to update the configuration registers */
372
  __HAL_IRDA_DISABLE(hirda);
373
 
374
  /* Set the IRDA Communication parameters */
375
  if (IRDA_SetConfig(hirda) == HAL_ERROR)
376
  {
377
    return HAL_ERROR;
378
  }
379
 
380
  /* In IRDA mode, the following bits must be kept cleared:
381
  - LINEN, STOP and CLKEN bits in the USART_CR2 register,
382
  - SCEN and HDSEL bits in the USART_CR3 register.*/
383
  CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
384
  CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
385
 
386
  /* set the UART/USART in IRDA mode */
387
  hirda->Instance->CR3 |= USART_CR3_IREN;
388
 
389
  /* Enable the Peripheral */
390
  __HAL_IRDA_ENABLE(hirda);
391
 
392
  /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */
393
  return (IRDA_CheckIdleState(hirda));
394
}
395
 
396
/**
397
  * @brief DeInitialize the IRDA peripheral.
398
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
399
  *               the configuration information for the specified IRDA module.
400
  * @retval HAL status
401
  */
402
HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
403
{
404
  /* Check the IRDA handle allocation */
405
  if (hirda == NULL)
406
  {
407
    return HAL_ERROR;
408
  }
409
 
410
  /* Check the USART/UART associated to the IRDA handle */
411
  assert_param(IS_IRDA_INSTANCE(hirda->Instance));
412
 
413
  hirda->gState = HAL_IRDA_STATE_BUSY;
414
 
415
  /* DeInit the low level hardware */
416
#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
417
  if (hirda->MspDeInitCallback == NULL)
418
  {
419
    hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
420
  }
421
  /* DeInit the low level hardware */
422
  hirda->MspDeInitCallback(hirda);
423
#else
424
  HAL_IRDA_MspDeInit(hirda);
425
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
426
  /* Disable the Peripheral */
427
  __HAL_IRDA_DISABLE(hirda);
428
 
429
  hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
430
  hirda->gState    = HAL_IRDA_STATE_RESET;
431
  hirda->RxState   = HAL_IRDA_STATE_RESET;
432
 
433
  /* Process Unlock */
434
  __HAL_UNLOCK(hirda);
435
 
436
  return HAL_OK;
437
}
438
 
439
/**
440
  * @brief Initialize the IRDA MSP.
441
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
442
  *               the configuration information for the specified IRDA module.
443
  * @retval None
444
  */
445
__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
446
{
447
  /* Prevent unused argument(s) compilation warning */
448
  UNUSED(hirda);
449
 
450
  /* NOTE: This function should not be modified, when the callback is needed,
451
           the HAL_IRDA_MspInit can be implemented in the user file
452
   */
453
}
454
 
455
/**
456
  * @brief DeInitialize the IRDA MSP.
457
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
458
  *               the configuration information for the specified IRDA module.
459
  * @retval None
460
  */
461
__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
462
{
463
  /* Prevent unused argument(s) compilation warning */
464
  UNUSED(hirda);
465
 
466
  /* NOTE: This function should not be modified, when the callback is needed,
467
           the HAL_IRDA_MspDeInit can be implemented in the user file
468
   */
469
}
470
 
471
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
472
/**
473
  * @brief  Register a User IRDA Callback
474
  *         To be used instead of the weak predefined callback
475
  * @param  hirda irda handle
476
  * @param  CallbackID ID of the callback to be registered
477
  *         This parameter can be one of the following values:
478
  *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
479
  *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
480
  *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
481
  *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
482
  *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
483
  *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
484
  *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
485
  *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
486
  *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
487
  *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
488
  * @param  pCallback pointer to the Callback function
489
  * @retval HAL status
490
  */
491
HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID,
492
                                            pIRDA_CallbackTypeDef pCallback)
493
{
494
  HAL_StatusTypeDef status = HAL_OK;
495
 
496
  if (pCallback == NULL)
497
  {
498
    /* Update the error code */
499
    hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
500
 
501
    return HAL_ERROR;
502
  }
503
  /* Process locked */
504
  __HAL_LOCK(hirda);
505
 
506
  if (hirda->gState == HAL_IRDA_STATE_READY)
507
  {
508
    switch (CallbackID)
509
    {
510
      case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
511
        hirda->TxHalfCpltCallback = pCallback;
512
        break;
513
 
514
      case HAL_IRDA_TX_COMPLETE_CB_ID :
515
        hirda->TxCpltCallback = pCallback;
516
        break;
517
 
518
      case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
519
        hirda->RxHalfCpltCallback = pCallback;
520
        break;
521
 
522
      case HAL_IRDA_RX_COMPLETE_CB_ID :
523
        hirda->RxCpltCallback = pCallback;
524
        break;
525
 
526
      case HAL_IRDA_ERROR_CB_ID :
527
        hirda->ErrorCallback = pCallback;
528
        break;
529
 
530
      case HAL_IRDA_ABORT_COMPLETE_CB_ID :
531
        hirda->AbortCpltCallback = pCallback;
532
        break;
533
 
534
      case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
535
        hirda->AbortTransmitCpltCallback = pCallback;
536
        break;
537
 
538
      case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
539
        hirda->AbortReceiveCpltCallback = pCallback;
540
        break;
541
 
542
      case HAL_IRDA_MSPINIT_CB_ID :
543
        hirda->MspInitCallback = pCallback;
544
        break;
545
 
546
      case HAL_IRDA_MSPDEINIT_CB_ID :
547
        hirda->MspDeInitCallback = pCallback;
548
        break;
549
 
550
      default :
551
        /* Update the error code */
552
        hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
553
 
554
        /* Return error status */
555
        status =  HAL_ERROR;
556
        break;
557
    }
558
  }
559
  else if (hirda->gState == HAL_IRDA_STATE_RESET)
560
  {
561
    switch (CallbackID)
562
    {
563
      case HAL_IRDA_MSPINIT_CB_ID :
564
        hirda->MspInitCallback = pCallback;
565
        break;
566
 
567
      case HAL_IRDA_MSPDEINIT_CB_ID :
568
        hirda->MspDeInitCallback = pCallback;
569
        break;
570
 
571
      default :
572
        /* Update the error code */
573
        hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
574
 
575
        /* Return error status */
576
        status =  HAL_ERROR;
577
        break;
578
    }
579
  }
580
  else
581
  {
582
    /* Update the error code */
583
    hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
584
 
585
    /* Return error status */
586
    status =  HAL_ERROR;
587
  }
588
 
589
  /* Release Lock */
590
  __HAL_UNLOCK(hirda);
591
 
592
  return status;
593
}
594
 
595
/**
596
  * @brief  Unregister an IRDA callback
597
  *         IRDA callback is redirected to the weak predefined callback
598
  * @param  hirda irda handle
599
  * @param  CallbackID ID of the callback to be unregistered
600
  *         This parameter can be one of the following values:
601
  *           @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
602
  *           @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
603
  *           @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
604
  *           @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
605
  *           @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
606
  *           @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
607
  *           @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
608
  *           @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
609
  *           @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
610
  *           @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
611
  * @retval HAL status
612
  */
613
HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID)
614
{
615
  HAL_StatusTypeDef status = HAL_OK;
616
 
617
  /* Process locked */
618
  __HAL_LOCK(hirda);
619
 
620
  if (HAL_IRDA_STATE_READY == hirda->gState)
621
  {
622
    switch (CallbackID)
623
    {
624
      case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
6 mjames 625
        hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback    */
2 mjames 626
        break;
627
 
628
      case HAL_IRDA_TX_COMPLETE_CB_ID :
6 mjames 629
        hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback;                       /* Legacy weak TxCpltCallback         */
2 mjames 630
        break;
631
 
632
      case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
6 mjames 633
        hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback     */
2 mjames 634
        break;
635
 
636
      case HAL_IRDA_RX_COMPLETE_CB_ID :
6 mjames 637
        hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback;                       /* Legacy weak RxCpltCallback         */
2 mjames 638
        break;
639
 
640
      case HAL_IRDA_ERROR_CB_ID :
6 mjames 641
        hirda->ErrorCallback = HAL_IRDA_ErrorCallback;                         /* Legacy weak ErrorCallback          */
2 mjames 642
        break;
643
 
644
      case HAL_IRDA_ABORT_COMPLETE_CB_ID :
6 mjames 645
        hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback      */
2 mjames 646
        break;
647
 
648
      case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
6 mjames 649
        hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak
650
                                                                                  AbortTransmitCpltCallback          */
2 mjames 651
        break;
652
 
653
      case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
6 mjames 654
        hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback;   /* Legacy weak
655
                                                                                  AbortReceiveCpltCallback           */
2 mjames 656
        break;
657
 
658
      case HAL_IRDA_MSPINIT_CB_ID :
6 mjames 659
        hirda->MspInitCallback = HAL_IRDA_MspInit;                             /* Legacy weak MspInitCallback        */
2 mjames 660
        break;
661
 
662
      case HAL_IRDA_MSPDEINIT_CB_ID :
6 mjames 663
        hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;                         /* Legacy weak MspDeInitCallback      */
2 mjames 664
        break;
665
 
666
      default :
667
        /* Update the error code */
668
        hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
669
 
670
        /* Return error status */
671
        status =  HAL_ERROR;
672
        break;
673
    }
674
  }
675
  else if (HAL_IRDA_STATE_RESET == hirda->gState)
676
  {
677
    switch (CallbackID)
678
    {
679
      case HAL_IRDA_MSPINIT_CB_ID :
680
        hirda->MspInitCallback = HAL_IRDA_MspInit;
681
        break;
682
 
683
      case HAL_IRDA_MSPDEINIT_CB_ID :
684
        hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
685
        break;
686
 
687
      default :
688
        /* Update the error code */
689
        hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
690
 
691
        /* Return error status */
692
        status =  HAL_ERROR;
693
        break;
694
    }
695
  }
696
  else
697
  {
698
    /* Update the error code */
699
    hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
700
 
701
    /* Return error status */
702
    status =  HAL_ERROR;
703
  }
704
 
705
  /* Release Lock */
706
  __HAL_UNLOCK(hirda);
707
 
708
  return status;
709
}
710
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
711
 
712
/**
713
  * @}
714
  */
715
 
716
/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
717
  *  @brief   IRDA Transmit and Receive functions
718
  *
719
@verbatim
720
 ===============================================================================
721
                         ##### IO operation functions #####
722
 ===============================================================================
723
  [..]
724
    This subsection provides a set of functions allowing to manage the IRDA data transfers.
725
 
726
  [..]
727
    IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
728
    on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
729
    is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
730
    While receiving data, transmission should be avoided as the data to be transmitted
731
    could be corrupted.
732
 
733
  [..]
734
    (#) There are two modes of transfer:
735
        (++) Blocking mode: the communication is performed in polling mode.
736
             The HAL status of all data processing is returned by the same function
737
             after finishing transfer.
738
        (++) Non-Blocking mode: the communication is performed using Interrupts
739
             or DMA, these API's return the HAL status.
740
             The end of the data processing will be indicated through the
741
             dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
742
             using DMA mode.
743
             The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
744
             will be executed respectively at the end of the Transmit or Receive process
745
             The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
746
 
747
    (#) Blocking mode APIs are :
748
        (++) HAL_IRDA_Transmit()
749
        (++) HAL_IRDA_Receive()
750
 
751
    (#) Non Blocking mode APIs with Interrupt are :
752
        (++) HAL_IRDA_Transmit_IT()
753
        (++) HAL_IRDA_Receive_IT()
754
        (++) HAL_IRDA_IRQHandler()
755
 
756
    (#) Non Blocking mode functions with DMA are :
757
        (++) HAL_IRDA_Transmit_DMA()
758
        (++) HAL_IRDA_Receive_DMA()
759
        (++) HAL_IRDA_DMAPause()
760
        (++) HAL_IRDA_DMAResume()
761
        (++) HAL_IRDA_DMAStop()
762
 
763
    (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
764
        (++) HAL_IRDA_TxHalfCpltCallback()
765
        (++) HAL_IRDA_TxCpltCallback()
766
        (++) HAL_IRDA_RxHalfCpltCallback()
767
        (++) HAL_IRDA_RxCpltCallback()
768
        (++) HAL_IRDA_ErrorCallback()
769
 
770
    (#) Non-Blocking mode transfers could be aborted using Abort API's :
771
        (++) HAL_IRDA_Abort()
772
        (++) HAL_IRDA_AbortTransmit()
773
        (++) HAL_IRDA_AbortReceive()
774
        (++) HAL_IRDA_Abort_IT()
775
        (++) HAL_IRDA_AbortTransmit_IT()
776
        (++) HAL_IRDA_AbortReceive_IT()
777
 
778
    (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
779
        (++) HAL_IRDA_AbortCpltCallback()
780
        (++) HAL_IRDA_AbortTransmitCpltCallback()
781
        (++) HAL_IRDA_AbortReceiveCpltCallback()
782
 
783
    (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
784
        Errors are handled as follows :
785
        (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
6 mjames 786
             to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
787
             in Interrupt mode reception .
788
             Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
789
             to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed.
790
             Transfer is kept ongoing on IRDA side.
2 mjames 791
             If user wants to abort it, Abort services should be called by user.
792
        (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
793
             This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
6 mjames 794
             Error code is set to allow user to identify error type, and
795
             HAL_IRDA_ErrorCallback() user callback is executed.
2 mjames 796
 
797
@endverbatim
798
  * @{
799
  */
800
 
801
/**
802
  * @brief Send an amount of data in blocking mode.
803
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
804
  *        the sent data is handled as a set of u16. In this case, Size must reflect the number
805
  *        of u16 available through pData.
806
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
807
  *               the configuration information for the specified IRDA module.
808
  * @param pData Pointer to data buffer (u8 or u16 data elements).
809
  * @param Size Amount of data elements (u8 or u16) to be sent.
810
  * @param Timeout Specify timeout value.
811
  * @retval HAL status
812
  */
813
/**
814
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
815
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
816
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
817
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
818
  */
819
HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
820
{
821
  uint8_t  *pdata8bits;
822
  uint16_t *pdata16bits;
823
  uint32_t tickstart;
824
 
825
  /* Check that a Tx process is not already ongoing */
826
  if (hirda->gState == HAL_IRDA_STATE_READY)
827
  {
828
    if ((pData == NULL) || (Size == 0U))
829
    {
830
      return  HAL_ERROR;
831
    }
832
 
6 mjames 833
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 834
       should be aligned on a u16 frontier, as data to be filled into TDR will be
835
       handled through a u16 cast. */
836
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
837
    {
838
      if ((((uint32_t)pData) & 1U) != 0U)
839
      {
840
        return  HAL_ERROR;
841
      }
842
    }
843
 
844
    /* Process Locked */
845
    __HAL_LOCK(hirda);
846
 
847
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
848
    hirda->gState = HAL_IRDA_STATE_BUSY_TX;
849
 
6 mjames 850
    /* Init tickstart for timeout management */
2 mjames 851
    tickstart = HAL_GetTick();
852
 
853
    hirda->TxXferSize = Size;
854
    hirda->TxXferCount = Size;
855
 
856
    /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
857
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
858
    {
859
      pdata8bits  = NULL;
860
      pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */
861
    }
862
    else
863
    {
864
      pdata8bits  = pData;
865
      pdata16bits = NULL;
866
    }
867
 
868
    while (hirda->TxXferCount > 0U)
869
    {
870
      hirda->TxXferCount--;
871
 
872
      if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
873
      {
874
        return HAL_TIMEOUT;
875
      }
876
      if (pdata8bits == NULL)
877
      {
878
        hirda->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
879
        pdata16bits++;
880
      }
881
      else
882
      {
883
        hirda->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
884
        pdata8bits++;
885
      }
886
    }
887
 
888
    if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
889
    {
890
      return HAL_TIMEOUT;
891
    }
892
 
893
    /* At end of Tx process, restore hirda->gState to Ready */
894
    hirda->gState = HAL_IRDA_STATE_READY;
895
 
896
    /* Process Unlocked */
897
    __HAL_UNLOCK(hirda);
898
 
899
    return HAL_OK;
900
  }
901
  else
902
  {
903
    return HAL_BUSY;
904
  }
905
}
906
 
907
/**
908
  * @brief Receive an amount of data in blocking mode.
909
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
910
  *        the received data is handled as a set of u16. In this case, Size must reflect the number
911
  *        of u16 available through pData.
912
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
913
  *                the configuration information for the specified IRDA module.
914
  * @param pData Pointer to data buffer (u8 or u16 data elements).
915
  * @param Size Amount of data elements (u8 or u16) to be received.
916
  * @param Timeout Specify timeout value.
917
  * @retval HAL status
918
  */
919
/**
920
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
921
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
922
  *         (as received data will be handled using u16 pointer cast). Depending on compilation chain,
923
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
924
  */
925
HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
926
{
927
  uint8_t  *pdata8bits;
928
  uint16_t *pdata16bits;
929
  uint16_t uhMask;
930
  uint32_t tickstart;
931
 
932
  /* Check that a Rx process is not already ongoing */
933
  if (hirda->RxState == HAL_IRDA_STATE_READY)
934
  {
935
    if ((pData == NULL) || (Size == 0U))
936
    {
937
      return  HAL_ERROR;
938
    }
939
 
6 mjames 940
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 941
       should be aligned on a u16 frontier, as data to be received from RDR will be
942
       handled through a u16 cast. */
943
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
944
    {
945
      if ((((uint32_t)pData) & 1U) != 0U)
946
      {
947
        return  HAL_ERROR;
948
      }
949
    }
950
 
951
    /* Process Locked */
952
    __HAL_LOCK(hirda);
953
 
954
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
955
    hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
956
 
6 mjames 957
    /* Init tickstart for timeout management */
2 mjames 958
    tickstart = HAL_GetTick();
959
 
960
    hirda->RxXferSize = Size;
961
    hirda->RxXferCount = Size;
962
 
963
    /* Computation of the mask to apply to RDR register
964
       of the UART associated to the IRDA */
965
    IRDA_MASK_COMPUTATION(hirda);
966
    uhMask = hirda->Mask;
967
 
968
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
969
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
970
    {
971
      pdata8bits  = NULL;
972
      pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */
973
    }
974
    else
975
    {
976
      pdata8bits  = pData;
977
      pdata16bits = NULL;
978
    }
979
 
980
    /* Check data remaining to be received */
981
    while (hirda->RxXferCount > 0U)
982
    {
983
      hirda->RxXferCount--;
984
 
985
      if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
986
      {
987
        return HAL_TIMEOUT;
988
      }
989
      if (pdata8bits == NULL)
990
      {
991
        *pdata16bits = (uint16_t)(hirda->Instance->RDR & uhMask);
992
        pdata16bits++;
993
      }
994
      else
995
      {
996
        *pdata8bits = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask);
997
        pdata8bits++;
998
      }
999
    }
1000
 
1001
    /* At end of Rx process, restore hirda->RxState to Ready */
1002
    hirda->RxState = HAL_IRDA_STATE_READY;
1003
 
1004
    /* Process Unlocked */
1005
    __HAL_UNLOCK(hirda);
1006
 
1007
    return HAL_OK;
1008
  }
1009
  else
1010
  {
1011
    return HAL_BUSY;
1012
  }
1013
}
1014
 
1015
/**
1016
  * @brief Send an amount of data in interrupt mode.
1017
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1018
  *        the sent data is handled as a set of u16. In this case, Size must reflect the number
1019
  *        of u16 available through pData.
1020
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1021
  *                the configuration information for the specified IRDA module.
1022
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1023
  * @param Size Amount of data elements (u8 or u16) to be sent.
1024
  * @retval HAL status
1025
  */
1026
/**
1027
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1028
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1029
  *         (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1030
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
1031
  */
1032
HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1033
{
1034
  /* Check that a Tx process is not already ongoing */
1035
  if (hirda->gState == HAL_IRDA_STATE_READY)
1036
  {
1037
    if ((pData == NULL) || (Size == 0U))
1038
    {
1039
      return HAL_ERROR;
1040
    }
1041
 
6 mjames 1042
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 1043
       should be aligned on a u16 frontier, as data to be filled into TDR will be
1044
       handled through a u16 cast. */
1045
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1046
    {
1047
      if ((((uint32_t)pData) & 1U) != 0U)
1048
      {
1049
        return  HAL_ERROR;
1050
      }
1051
    }
1052
 
1053
    /* Process Locked */
1054
    __HAL_LOCK(hirda);
1055
 
1056
    hirda->pTxBuffPtr = pData;
1057
    hirda->TxXferSize = Size;
1058
    hirda->TxXferCount = Size;
1059
 
1060
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1061
    hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1062
 
1063
    /* Process Unlocked */
1064
    __HAL_UNLOCK(hirda);
1065
 
1066
    /* Enable the IRDA Transmit Data Register Empty Interrupt */
1067
    SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
1068
 
1069
    return HAL_OK;
1070
  }
1071
  else
1072
  {
1073
    return HAL_BUSY;
1074
  }
1075
}
1076
 
1077
/**
1078
  * @brief Receive an amount of data in interrupt mode.
1079
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1080
  *        the received data is handled as a set of u16. In this case, Size must reflect the number
1081
  *        of u16 available through pData.
1082
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1083
  *                the configuration information for the specified IRDA module.
1084
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1085
  * @param Size Amount of data elements (u8 or u16) to be received.
1086
  * @retval HAL status
1087
  */
1088
/**
1089
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1090
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
1091
  *         (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1092
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
1093
  */
1094
HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1095
{
1096
  /* Check that a Rx process is not already ongoing */
1097
  if (hirda->RxState == HAL_IRDA_STATE_READY)
1098
  {
1099
    if ((pData == NULL) || (Size == 0U))
1100
    {
1101
      return HAL_ERROR;
1102
    }
1103
 
6 mjames 1104
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 1105
       should be aligned on a u16 frontier, as data to be received from RDR will be
1106
       handled through a u16 cast. */
1107
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1108
    {
1109
      if ((((uint32_t)pData) & 1U) != 0U)
1110
      {
1111
        return  HAL_ERROR;
1112
      }
1113
    }
1114
 
1115
    /* Process Locked */
1116
    __HAL_LOCK(hirda);
1117
 
1118
    hirda->pRxBuffPtr = pData;
1119
    hirda->RxXferSize = Size;
1120
    hirda->RxXferCount = Size;
1121
 
1122
    /* Computation of the mask to apply to the RDR register
1123
       of the UART associated to the IRDA */
1124
    IRDA_MASK_COMPUTATION(hirda);
1125
 
1126
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1127
    hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1128
 
1129
    /* Process Unlocked */
1130
    __HAL_UNLOCK(hirda);
1131
 
1132
    /* Enable the IRDA Parity Error and Data Register not empty Interrupts */
1133
    SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1134
 
1135
    /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
1136
    SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1137
 
1138
    return HAL_OK;
1139
  }
1140
  else
1141
  {
1142
    return HAL_BUSY;
1143
  }
1144
}
1145
 
1146
/**
1147
  * @brief Send an amount of data in DMA mode.
1148
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1149
  *        the sent data is handled as a set of u16. In this case, Size must reflect the number
1150
  *        of u16 available through pData.
1151
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1152
  *               the configuration information for the specified IRDA module.
1153
  * @param pData pointer to data buffer (u8 or u16 data elements).
1154
  * @param Size Amount of data elements (u8 or u16) to be sent.
1155
  * @retval HAL status
1156
  */
1157
/**
1158
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1159
  *         address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1160
  *         (as sent data will be handled by DMA from halfword frontier). Depending on compilation chain,
1161
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
1162
  */
1163
HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1164
{
1165
  /* Check that a Tx process is not already ongoing */
1166
  if (hirda->gState == HAL_IRDA_STATE_READY)
1167
  {
1168
    if ((pData == NULL) || (Size == 0U))
1169
    {
1170
      return HAL_ERROR;
1171
    }
1172
 
6 mjames 1173
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 1174
       should be aligned on a u16 frontier, as data copy into TDR will be
1175
       handled by DMA from a u16 frontier. */
1176
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1177
    {
1178
      if ((((uint32_t)pData) & 1U) != 0U)
1179
      {
1180
        return  HAL_ERROR;
1181
      }
1182
    }
1183
 
1184
    /* Process Locked */
1185
    __HAL_LOCK(hirda);
1186
 
1187
    hirda->pTxBuffPtr = pData;
1188
    hirda->TxXferSize = Size;
1189
    hirda->TxXferCount = Size;
1190
 
1191
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1192
    hirda->gState = HAL_IRDA_STATE_BUSY_TX;
1193
 
1194
    /* Set the IRDA DMA transfer complete callback */
1195
    hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
1196
 
1197
    /* Set the IRDA DMA half transfer complete callback */
1198
    hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
1199
 
1200
    /* Set the DMA error callback */
1201
    hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
1202
 
1203
    /* Set the DMA abort callback */
1204
    hirda->hdmatx->XferAbortCallback = NULL;
1205
 
1206
    /* Enable the IRDA transmit DMA channel */
1207
    if (HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, Size) == HAL_OK)
1208
    {
1209
      /* Clear the TC flag in the ICR register */
1210
      __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);
1211
 
1212
      /* Process Unlocked */
1213
      __HAL_UNLOCK(hirda);
1214
 
1215
      /* Enable the DMA transfer for transmit request by setting the DMAT bit
1216
         in the USART CR3 register */
1217
      SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1218
 
1219
      return HAL_OK;
1220
    }
1221
    else
1222
    {
1223
      /* Set error code to DMA */
1224
      hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1225
 
1226
      /* Process Unlocked */
1227
      __HAL_UNLOCK(hirda);
1228
 
1229
      /* Restore hirda->gState to ready */
1230
      hirda->gState = HAL_IRDA_STATE_READY;
1231
 
1232
      return HAL_ERROR;
1233
    }
1234
  }
1235
  else
1236
  {
1237
    return HAL_BUSY;
1238
  }
1239
}
1240
 
1241
/**
1242
  * @brief Receive an amount of data in DMA mode.
1243
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1244
  *        the received data is handled as a set of u16. In this case, Size must reflect the number
1245
  *        of u16 available through pData.
1246
  * @note   When the IRDA parity is enabled (PCE = 1), the received data contains
1247
  *         the parity bit (MSB position).
1248
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
1249
  *               the configuration information for the specified IRDA module.
1250
  * @param pData Pointer to data buffer (u8 or u16 data elements).
1251
  * @param Size Amount of data elements (u8 or u16) to be received.
1252
  * @retval HAL status
1253
  */
1254
/**
1255
  * @note   When IRDA parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1256
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits)
1257
  *         (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1258
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData.
1259
  */
1260
HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
1261
{
1262
  /* Check that a Rx process is not already ongoing */
1263
  if (hirda->RxState == HAL_IRDA_STATE_READY)
1264
  {
1265
    if ((pData == NULL) || (Size == 0U))
1266
    {
1267
      return HAL_ERROR;
1268
    }
1269
 
6 mjames 1270
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
2 mjames 1271
       should be aligned on a u16 frontier, as data copy from RDR will be
1272
       handled by DMA from a u16 frontier. */
1273
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
1274
    {
1275
      if ((((uint32_t)pData) & 1U) != 0U)
1276
      {
1277
        return  HAL_ERROR;
1278
      }
1279
    }
1280
 
1281
    /* Process Locked */
1282
    __HAL_LOCK(hirda);
1283
 
1284
    hirda->pRxBuffPtr = pData;
1285
    hirda->RxXferSize = Size;
1286
 
1287
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1288
    hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
1289
 
1290
    /* Set the IRDA DMA transfer complete callback */
1291
    hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
1292
 
1293
    /* Set the IRDA DMA half transfer complete callback */
1294
    hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
1295
 
1296
    /* Set the DMA error callback */
1297
    hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
1298
 
1299
    /* Set the DMA abort callback */
1300
    hirda->hdmarx->XferAbortCallback = NULL;
1301
 
1302
    /* Enable the DMA channel */
1303
    if (HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, Size) == HAL_OK)
1304
    {
1305
      /* Process Unlocked */
1306
      __HAL_UNLOCK(hirda);
1307
 
1308
      /* Enable the UART Parity Error Interrupt */
1309
      SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1310
 
1311
      /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1312
      SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1313
 
1314
      /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1315
         in the USART CR3 register */
1316
      SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1317
 
1318
      return HAL_OK;
1319
    }
1320
    else
1321
    {
1322
      /* Set error code to DMA */
1323
      hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1324
 
1325
      /* Process Unlocked */
1326
      __HAL_UNLOCK(hirda);
1327
 
1328
      /* Restore hirda->RxState to ready */
1329
      hirda->RxState = HAL_IRDA_STATE_READY;
1330
 
1331
      return HAL_ERROR;
1332
    }
1333
  }
1334
  else
1335
  {
1336
    return HAL_BUSY;
1337
  }
1338
}
1339
 
1340
 
1341
/**
1342
  * @brief Pause the DMA Transfer.
1343
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1344
  *                the configuration information for the specified IRDA module.
1345
  * @retval HAL status
1346
  */
1347
HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
1348
{
1349
  /* Process Locked */
1350
  __HAL_LOCK(hirda);
1351
 
1352
  if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1353
  {
1354
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1355
    {
1356
      /* Disable the IRDA DMA Tx request */
1357
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1358
    }
1359
  }
1360
  if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1361
  {
1362
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1363
    {
1364
      /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1365
      CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1366
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1367
 
1368
      /* Disable the IRDA DMA Rx request */
1369
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1370
    }
1371
  }
1372
 
1373
  /* Process Unlocked */
1374
  __HAL_UNLOCK(hirda);
1375
 
1376
  return HAL_OK;
1377
}
1378
 
1379
/**
1380
  * @brief Resume the DMA Transfer.
1381
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1382
  *                the configuration information for the specified UART module.
1383
  * @retval HAL status
1384
  */
1385
HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
1386
{
1387
  /* Process Locked */
1388
  __HAL_LOCK(hirda);
1389
 
1390
  if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1391
  {
1392
    /* Enable the IRDA DMA Tx request */
1393
    SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1394
  }
1395
  if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1396
  {
1397
    /* Clear the Overrun flag before resuming the Rx transfer*/
1398
    __HAL_IRDA_CLEAR_OREFLAG(hirda);
1399
 
6 mjames 1400
    /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
2 mjames 1401
    SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
1402
    SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1403
 
1404
    /* Enable the IRDA DMA Rx request */
1405
    SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1406
  }
1407
 
1408
  /* Process Unlocked */
1409
  __HAL_UNLOCK(hirda);
1410
 
1411
  return HAL_OK;
1412
}
1413
 
1414
/**
1415
  * @brief Stop the DMA Transfer.
1416
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1417
  *                the configuration information for the specified UART module.
1418
  * @retval HAL status
1419
  */
1420
HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
1421
{
1422
  /* The Lock is not implemented on this API to allow the user application
1423
     to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() /
1424
     HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback:
1425
     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1426
     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1427
     the stream and the corresponding call back is executed. */
1428
 
1429
  /* Stop IRDA DMA Tx request if ongoing */
1430
  if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
1431
  {
1432
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1433
    {
1434
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1435
 
1436
      /* Abort the IRDA DMA Tx channel */
1437
      if (hirda->hdmatx != NULL)
1438
      {
1439
        if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1440
        {
1441
          if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1442
          {
1443
            /* Set error code to DMA */
1444
            hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1445
 
1446
            return HAL_TIMEOUT;
1447
          }
1448
        }
1449
      }
1450
 
1451
      IRDA_EndTxTransfer(hirda);
1452
    }
1453
  }
1454
 
1455
  /* Stop IRDA DMA Rx request if ongoing */
1456
  if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
1457
  {
1458
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1459
    {
1460
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1461
 
1462
      /* Abort the IRDA DMA Rx channel */
1463
      if (hirda->hdmarx != NULL)
1464
      {
1465
        if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1466
        {
1467
          if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1468
          {
1469
            /* Set error code to DMA */
1470
            hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1471
 
1472
            return HAL_TIMEOUT;
1473
          }
1474
        }
1475
      }
1476
 
1477
      IRDA_EndRxTransfer(hirda);
1478
    }
1479
  }
1480
 
1481
  return HAL_OK;
1482
}
1483
 
1484
/**
1485
  * @brief  Abort ongoing transfers (blocking mode).
1486
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1487
  *               the configuration information for the specified UART module.
1488
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1489
  *         This procedure performs following operations :
1490
  *           - Disable IRDA Interrupts (Tx and Rx)
1491
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1492
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1493
  *           - Set handle State to READY
1494
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1495
  * @retval HAL status
1496
  */
1497
HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
1498
{
1499
  /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1500
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1501
  CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1502
 
1503
  /* Disable the IRDA DMA Tx request if enabled */
1504
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1505
  {
1506
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1507
 
1508
    /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1509
    if (hirda->hdmatx != NULL)
1510
    {
1511
      /* Set the IRDA DMA Abort callback to Null.
1512
         No call back execution at end of DMA abort procedure */
1513
      hirda->hdmatx->XferAbortCallback = NULL;
1514
 
1515
      if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1516
      {
1517
        if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1518
        {
1519
          /* Set error code to DMA */
1520
          hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1521
 
1522
          return HAL_TIMEOUT;
1523
        }
1524
      }
1525
    }
1526
  }
1527
 
1528
  /* Disable the IRDA DMA Rx request if enabled */
1529
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1530
  {
1531
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1532
 
1533
    /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1534
    if (hirda->hdmarx != NULL)
1535
    {
1536
      /* Set the IRDA DMA Abort callback to Null.
1537
         No call back execution at end of DMA abort procedure */
1538
      hirda->hdmarx->XferAbortCallback = NULL;
1539
 
1540
      if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1541
      {
1542
        if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1543
        {
1544
          /* Set error code to DMA */
1545
          hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1546
 
1547
          return HAL_TIMEOUT;
1548
        }
1549
      }
1550
    }
1551
  }
1552
 
1553
  /* Reset Tx and Rx transfer counters */
1554
  hirda->TxXferCount = 0U;
1555
  hirda->RxXferCount = 0U;
1556
 
1557
  /* Clear the Error flags in the ICR register */
1558
  __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1559
 
1560
  /* Restore hirda->gState and hirda->RxState to Ready */
1561
  hirda->gState  = HAL_IRDA_STATE_READY;
1562
  hirda->RxState = HAL_IRDA_STATE_READY;
1563
 
1564
  /* Reset Handle ErrorCode to No Error */
1565
  hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1566
 
1567
  return HAL_OK;
1568
}
1569
 
1570
/**
1571
  * @brief  Abort ongoing Transmit transfer (blocking mode).
1572
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1573
  *               the configuration information for the specified UART module.
1574
  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1575
  *         This procedure performs following operations :
1576
  *           - Disable IRDA Interrupts (Tx)
1577
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1578
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1579
  *           - Set handle State to READY
1580
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1581
  * @retval HAL status
1582
  */
1583
HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
1584
{
1585
  /* Disable TXEIE and TCIE interrupts */
1586
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1587
 
1588
  /* Disable the IRDA DMA Tx request if enabled */
1589
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1590
  {
1591
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1592
 
1593
    /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
1594
    if (hirda->hdmatx != NULL)
1595
    {
1596
      /* Set the IRDA DMA Abort callback to Null.
1597
         No call back execution at end of DMA abort procedure */
1598
      hirda->hdmatx->XferAbortCallback = NULL;
1599
 
1600
      if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK)
1601
      {
1602
        if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1603
        {
1604
          /* Set error code to DMA */
1605
          hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1606
 
1607
          return HAL_TIMEOUT;
1608
        }
1609
      }
1610
    }
1611
  }
1612
 
1613
  /* Reset Tx transfer counter */
1614
  hirda->TxXferCount = 0U;
1615
 
1616
  /* Restore hirda->gState to Ready */
1617
  hirda->gState = HAL_IRDA_STATE_READY;
1618
 
1619
  return HAL_OK;
1620
}
1621
 
1622
/**
1623
  * @brief  Abort ongoing Receive transfer (blocking mode).
1624
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1625
  *               the configuration information for the specified UART module.
1626
  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1627
  *         This procedure performs following operations :
1628
  *           - Disable IRDA Interrupts (Rx)
1629
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1630
  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1631
  *           - Set handle State to READY
1632
  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1633
  * @retval HAL status
1634
  */
1635
HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
1636
{
1637
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1638
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1639
  CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1640
 
1641
  /* Disable the IRDA DMA Rx request if enabled */
1642
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1643
  {
1644
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1645
 
1646
    /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
1647
    if (hirda->hdmarx != NULL)
1648
    {
1649
      /* Set the IRDA DMA Abort callback to Null.
1650
         No call back execution at end of DMA abort procedure */
1651
      hirda->hdmarx->XferAbortCallback = NULL;
1652
 
1653
      if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK)
1654
      {
1655
        if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1656
        {
1657
          /* Set error code to DMA */
1658
          hirda->ErrorCode = HAL_IRDA_ERROR_DMA;
1659
 
1660
          return HAL_TIMEOUT;
1661
        }
1662
      }
1663
    }
1664
  }
1665
 
1666
  /* Reset Rx transfer counter */
1667
  hirda->RxXferCount = 0U;
1668
 
1669
  /* Clear the Error flags in the ICR register */
1670
  __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1671
 
1672
  /* Restore hirda->RxState to Ready */
1673
  hirda->RxState = HAL_IRDA_STATE_READY;
1674
 
1675
  return HAL_OK;
1676
}
1677
 
1678
/**
1679
  * @brief  Abort ongoing transfers (Interrupt mode).
1680
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1681
  *               the configuration information for the specified UART module.
1682
  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1683
  *         This procedure performs following operations :
1684
  *           - Disable IRDA Interrupts (Tx and Rx)
1685
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1686
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1687
  *           - Set handle State to READY
1688
  *           - At abort completion, call user abort complete callback
1689
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1690
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
1691
  * @retval HAL status
1692
  */
1693
HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
1694
{
1695
  uint32_t abortcplt = 1U;
1696
 
1697
  /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1698
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1699
  CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1700
 
1701
  /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
1702
     before any call to DMA Abort functions */
1703
  /* DMA Tx Handle is valid */
1704
  if (hirda->hdmatx != NULL)
1705
  {
1706
    /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
1707
       Otherwise, set it to NULL */
1708
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1709
    {
1710
      hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
1711
    }
1712
    else
1713
    {
1714
      hirda->hdmatx->XferAbortCallback = NULL;
1715
    }
1716
  }
1717
  /* DMA Rx Handle is valid */
1718
  if (hirda->hdmarx != NULL)
1719
  {
1720
    /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
1721
       Otherwise, set it to NULL */
1722
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1723
    {
1724
      hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
1725
    }
1726
    else
1727
    {
1728
      hirda->hdmarx->XferAbortCallback = NULL;
1729
    }
1730
  }
1731
 
1732
  /* Disable the IRDA DMA Tx request if enabled */
1733
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1734
  {
1735
    /* Disable DMA Tx at UART level */
1736
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1737
 
1738
    /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1739
    if (hirda->hdmatx != NULL)
1740
    {
1741
      /* IRDA Tx DMA Abort callback has already been initialised :
1742
         will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1743
 
1744
      /* Abort DMA TX */
1745
      if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1746
      {
1747
        hirda->hdmatx->XferAbortCallback = NULL;
1748
      }
1749
      else
1750
      {
1751
        abortcplt = 0U;
1752
      }
1753
    }
1754
  }
1755
 
1756
  /* Disable the IRDA DMA Rx request if enabled */
1757
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1758
  {
1759
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1760
 
1761
    /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1762
    if (hirda->hdmarx != NULL)
1763
    {
1764
      /* IRDA Rx DMA Abort callback has already been initialised :
1765
         will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1766
 
1767
      /* Abort DMA RX */
1768
      if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1769
      {
1770
        hirda->hdmarx->XferAbortCallback = NULL;
1771
        abortcplt = 1U;
1772
      }
1773
      else
1774
      {
1775
        abortcplt = 0U;
1776
      }
1777
    }
1778
  }
1779
 
1780
  /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1781
  if (abortcplt == 1U)
1782
  {
1783
    /* Reset Tx and Rx transfer counters */
1784
    hirda->TxXferCount = 0U;
1785
    hirda->RxXferCount = 0U;
1786
 
1787
    /* Reset errorCode */
1788
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
1789
 
1790
    /* Clear the Error flags in the ICR register */
1791
    __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1792
 
1793
    /* Restore hirda->gState and hirda->RxState to Ready */
1794
    hirda->gState  = HAL_IRDA_STATE_READY;
1795
    hirda->RxState = HAL_IRDA_STATE_READY;
1796
 
1797
    /* As no DMA to be aborted, call directly user Abort complete callback */
1798
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1799
    /* Call registered Abort complete callback */
1800
    hirda->AbortCpltCallback(hirda);
1801
#else
1802
    /* Call legacy weak Abort complete callback */
1803
    HAL_IRDA_AbortCpltCallback(hirda);
1804
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1805
  }
1806
 
1807
  return HAL_OK;
1808
}
1809
 
1810
/**
1811
  * @brief  Abort ongoing Transmit transfer (Interrupt mode).
1812
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1813
  *               the configuration information for the specified UART module.
1814
  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1815
  *         This procedure performs following operations :
1816
  *           - Disable IRDA Interrupts (Tx)
1817
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1818
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1819
  *           - Set handle State to READY
1820
  *           - At abort completion, call user abort complete callback
1821
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1822
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
1823
  * @retval HAL status
1824
  */
1825
HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
1826
{
1827
  /* Disable TXEIE and TCIE interrupts */
1828
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1829
 
1830
  /* Disable the IRDA DMA Tx request if enabled */
1831
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
1832
  {
1833
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
1834
 
1835
    /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
1836
    if (hirda->hdmatx != NULL)
1837
    {
1838
      /* Set the IRDA DMA Abort callback :
1839
         will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1840
      hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
1841
 
1842
      /* Abort DMA TX */
1843
      if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
1844
      {
1845
        /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
1846
        hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
1847
      }
1848
    }
1849
    else
1850
    {
1851
      /* Reset Tx transfer counter */
1852
      hirda->TxXferCount = 0U;
1853
 
1854
      /* Restore hirda->gState to Ready */
1855
      hirda->gState = HAL_IRDA_STATE_READY;
1856
 
1857
      /* As no DMA to be aborted, call directly user Abort complete callback */
1858
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1859
      /* Call registered Abort Transmit Complete Callback */
1860
      hirda->AbortTransmitCpltCallback(hirda);
1861
#else
1862
      /* Call legacy weak Abort Transmit Complete Callback */
1863
      HAL_IRDA_AbortTransmitCpltCallback(hirda);
1864
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1865
    }
1866
  }
1867
  else
1868
  {
1869
    /* Reset Tx transfer counter */
1870
    hirda->TxXferCount = 0U;
1871
 
1872
    /* Restore hirda->gState to Ready */
1873
    hirda->gState = HAL_IRDA_STATE_READY;
1874
 
1875
    /* As no DMA to be aborted, call directly user Abort complete callback */
1876
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1877
    /* Call registered Abort Transmit Complete Callback */
1878
    hirda->AbortTransmitCpltCallback(hirda);
1879
#else
1880
    /* Call legacy weak Abort Transmit Complete Callback */
1881
    HAL_IRDA_AbortTransmitCpltCallback(hirda);
1882
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1883
  }
1884
 
1885
  return HAL_OK;
1886
}
1887
 
1888
/**
1889
  * @brief  Abort ongoing Receive transfer (Interrupt mode).
1890
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
1891
  *               the configuration information for the specified UART module.
1892
  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1893
  *         This procedure performs following operations :
1894
  *           - Disable IRDA Interrupts (Rx)
1895
  *           - Disable the DMA transfer in the peripheral register (if enabled)
1896
  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1897
  *           - Set handle State to READY
1898
  *           - At abort completion, call user abort complete callback
1899
  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1900
  *         considered as completed only when user abort complete callback is executed (not when exiting function).
1901
  * @retval HAL status
1902
  */
1903
HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
1904
{
1905
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1906
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1907
  CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
1908
 
1909
  /* Disable the IRDA DMA Rx request if enabled */
1910
  if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
1911
  {
1912
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
1913
 
1914
    /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
1915
    if (hirda->hdmarx != NULL)
1916
    {
1917
      /* Set the IRDA DMA Abort callback :
1918
         will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
1919
      hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
1920
 
1921
      /* Abort DMA RX */
1922
      if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
1923
      {
1924
        /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
1925
        hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
1926
      }
1927
    }
1928
    else
1929
    {
1930
      /* Reset Rx transfer counter */
1931
      hirda->RxXferCount = 0U;
1932
 
1933
      /* Clear the Error flags in the ICR register */
1934
      __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1935
 
1936
      /* Restore hirda->RxState to Ready */
1937
      hirda->RxState = HAL_IRDA_STATE_READY;
1938
 
1939
      /* As no DMA to be aborted, call directly user Abort complete callback */
1940
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1941
      /* Call registered Abort Receive Complete Callback */
1942
      hirda->AbortReceiveCpltCallback(hirda);
1943
#else
1944
      /* Call legacy weak Abort Receive Complete Callback */
1945
      HAL_IRDA_AbortReceiveCpltCallback(hirda);
1946
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1947
    }
1948
  }
1949
  else
1950
  {
1951
    /* Reset Rx transfer counter */
1952
    hirda->RxXferCount = 0U;
1953
 
1954
    /* Clear the Error flags in the ICR register */
1955
    __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
1956
 
1957
    /* Restore hirda->RxState to Ready */
1958
    hirda->RxState = HAL_IRDA_STATE_READY;
1959
 
1960
    /* As no DMA to be aborted, call directly user Abort complete callback */
1961
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
1962
    /* Call registered Abort Receive Complete Callback */
1963
    hirda->AbortReceiveCpltCallback(hirda);
1964
#else
1965
    /* Call legacy weak Abort Receive Complete Callback */
1966
    HAL_IRDA_AbortReceiveCpltCallback(hirda);
1967
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
1968
  }
1969
 
1970
  return HAL_OK;
1971
}
1972
 
1973
/**
1974
  * @brief Handle IRDA interrupt request.
1975
  * @param hirda  Pointer to a IRDA_HandleTypeDef structure that contains
1976
  *               the configuration information for the specified IRDA module.
1977
  * @retval None
1978
  */
1979
void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
1980
{
1981
  uint32_t isrflags   = READ_REG(hirda->Instance->ISR);
1982
  uint32_t cr1its     = READ_REG(hirda->Instance->CR1);
1983
  uint32_t cr3its;
1984
  uint32_t errorflags;
1985
  uint32_t errorcode;
1986
 
1987
  /* If no error occurs */
1988
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
1989
  if (errorflags == 0U)
1990
  {
1991
    /* IRDA in mode Receiver ---------------------------------------------------*/
1992
    if (((isrflags & USART_ISR_RXNE) != 0U) && ((cr1its & USART_CR1_RXNEIE) != 0U))
1993
    {
1994
      IRDA_Receive_IT(hirda);
1995
      return;
1996
    }
1997
  }
1998
 
1999
  /* If some errors occur */
2000
  cr3its = READ_REG(hirda->Instance->CR3);
2001
  if ((errorflags != 0U)
2002
      && (((cr3its & USART_CR3_EIE) != 0U)
2003
          || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != 0U)))
2004
  {
2005
    /* IRDA parity error interrupt occurred -------------------------------------*/
2006
    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2007
    {
2008
      __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF);
2009
 
2010
      hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
2011
    }
2012
 
2013
    /* IRDA frame error interrupt occurred --------------------------------------*/
2014
    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2015
    {
2016
      __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF);
2017
 
2018
      hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
2019
    }
2020
 
2021
    /* IRDA noise error interrupt occurred --------------------------------------*/
2022
    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2023
    {
2024
      __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF);
2025
 
2026
      hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
2027
    }
2028
 
2029
    /* IRDA Over-Run interrupt occurred -----------------------------------------*/
2030
    if (((isrflags & USART_ISR_ORE) != 0U) &&
2031
        (((cr1its & USART_CR1_RXNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U)))
2032
    {
2033
      __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF);
2034
 
2035
      hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
2036
    }
2037
 
2038
    /* Call IRDA Error Call back function if need be --------------------------*/
2039
    if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
2040
    {
2041
      /* IRDA in mode Receiver ---------------------------------------------------*/
2042
      if (((isrflags & USART_ISR_RXNE) != 0U) && ((cr1its & USART_CR1_RXNEIE) != 0U))
2043
      {
2044
        IRDA_Receive_IT(hirda);
2045
      }
2046
 
2047
      /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2048
         consider error as blocking */
2049
      errorcode = hirda->ErrorCode;
2050
      if ((HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) ||
2051
          ((errorcode & HAL_IRDA_ERROR_ORE) != 0U))
2052
      {
2053
        /* Blocking error : transfer is aborted
2054
           Set the IRDA state ready to be able to start again the process,
2055
           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2056
        IRDA_EndRxTransfer(hirda);
2057
 
2058
        /* Disable the IRDA DMA Rx request if enabled */
2059
        if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2060
        {
2061
          CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2062
 
2063
          /* Abort the IRDA DMA Rx channel */
2064
          if (hirda->hdmarx != NULL)
2065
          {
2066
            /* Set the IRDA DMA Abort callback :
2067
               will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
2068
            hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
2069
 
2070
            /* Abort DMA RX */
2071
            if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
2072
            {
2073
              /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
2074
              hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
2075
            }
2076
          }
2077
          else
2078
          {
2079
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2080
            /* Call registered user error callback */
2081
            hirda->ErrorCallback(hirda);
2082
#else
2083
            /* Call legacy weak user error callback */
2084
            HAL_IRDA_ErrorCallback(hirda);
2085
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2086
          }
2087
        }
2088
        else
2089
        {
2090
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2091
          /* Call registered user error callback */
2092
          hirda->ErrorCallback(hirda);
2093
#else
2094
          /* Call legacy weak user error callback */
2095
          HAL_IRDA_ErrorCallback(hirda);
2096
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2097
        }
2098
      }
2099
      else
2100
      {
2101
        /* Non Blocking error : transfer could go on.
2102
           Error is notified to user through user error callback */
2103
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2104
        /* Call registered user error callback */
2105
        hirda->ErrorCallback(hirda);
2106
#else
2107
        /* Call legacy weak user error callback */
2108
        HAL_IRDA_ErrorCallback(hirda);
2109
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2110
        hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2111
      }
2112
    }
2113
    return;
2114
 
2115
  } /* End if some error occurs */
2116
 
2117
  /* IRDA in mode Transmitter ------------------------------------------------*/
2118
  if (((isrflags & USART_ISR_TXE) != 0U) && ((cr1its & USART_CR1_TXEIE) != 0U))
2119
  {
2120
    IRDA_Transmit_IT(hirda);
2121
    return;
2122
  }
2123
 
2124
  /* IRDA in mode Transmitter (transmission end) -----------------------------*/
2125
  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2126
  {
2127
    IRDA_EndTransmit_IT(hirda);
2128
    return;
2129
  }
2130
 
2131
}
2132
 
2133
/**
2134
  * @brief  Tx Transfer completed callback.
2135
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2136
  *               the configuration information for the specified IRDA module.
2137
  * @retval None
2138
  */
2139
__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
2140
{
2141
  /* Prevent unused argument(s) compilation warning */
2142
  UNUSED(hirda);
2143
 
2144
  /* NOTE : This function should not be modified, when the callback is needed,
2145
            the HAL_IRDA_TxCpltCallback can be implemented in the user file.
2146
   */
2147
}
2148
 
2149
/**
2150
  * @brief  Tx Half Transfer completed callback.
2151
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2152
  *               the configuration information for the specified USART module.
2153
  * @retval None
2154
  */
2155
__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2156
{
2157
  /* Prevent unused argument(s) compilation warning */
2158
  UNUSED(hirda);
2159
 
2160
  /* NOTE : This function should not be modified, when the callback is needed,
2161
            the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
2162
   */
2163
}
2164
 
2165
/**
2166
  * @brief  Rx Transfer completed callback.
2167
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2168
  *               the configuration information for the specified IRDA module.
2169
  * @retval None
2170
  */
2171
__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
2172
{
2173
  /* Prevent unused argument(s) compilation warning */
2174
  UNUSED(hirda);
2175
 
2176
  /* NOTE : This function should not be modified, when the callback is needed,
2177
            the HAL_IRDA_RxCpltCallback can be implemented in the user file.
2178
   */
2179
}
2180
 
2181
/**
2182
  * @brief  Rx Half Transfer complete callback.
2183
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2184
  *               the configuration information for the specified IRDA module.
2185
  * @retval None
2186
  */
2187
__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
2188
{
2189
  /* Prevent unused argument(s) compilation warning */
2190
  UNUSED(hirda);
2191
 
2192
  /* NOTE : This function should not be modified, when the callback is needed,
2193
            the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
2194
   */
2195
}
2196
 
2197
/**
2198
  * @brief  IRDA error callback.
2199
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2200
  *               the configuration information for the specified IRDA module.
2201
  * @retval None
2202
  */
2203
__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
2204
{
2205
  /* Prevent unused argument(s) compilation warning */
2206
  UNUSED(hirda);
2207
 
2208
  /* NOTE : This function should not be modified, when the callback is needed,
2209
            the HAL_IRDA_ErrorCallback can be implemented in the user file.
2210
   */
2211
}
2212
 
2213
/**
2214
  * @brief  IRDA Abort Complete callback.
2215
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2216
  *               the configuration information for the specified IRDA module.
2217
  * @retval None
2218
  */
2219
__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
2220
{
2221
  /* Prevent unused argument(s) compilation warning */
2222
  UNUSED(hirda);
2223
 
2224
  /* NOTE : This function should not be modified, when the callback is needed,
2225
            the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
2226
   */
2227
}
2228
 
2229
/**
2230
  * @brief  IRDA Abort Complete callback.
2231
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2232
  *               the configuration information for the specified IRDA module.
2233
  * @retval None
2234
  */
2235
__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
2236
{
2237
  /* Prevent unused argument(s) compilation warning */
2238
  UNUSED(hirda);
2239
 
2240
  /* NOTE : This function should not be modified, when the callback is needed,
2241
            the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
2242
   */
2243
}
2244
 
2245
/**
2246
  * @brief  IRDA Abort Receive Complete callback.
2247
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2248
  *               the configuration information for the specified IRDA module.
2249
  * @retval None
2250
  */
2251
__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
2252
{
2253
  /* Prevent unused argument(s) compilation warning */
2254
  UNUSED(hirda);
2255
 
2256
  /* NOTE : This function should not be modified, when the callback is needed,
2257
            the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
2258
   */
2259
}
2260
 
2261
/**
2262
  * @}
2263
  */
2264
 
2265
/** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions
2266
  *  @brief   IRDA State and Errors functions
2267
  *
2268
@verbatim
2269
  ==============================================================================
2270
            ##### Peripheral State and Error functions #####
2271
  ==============================================================================
2272
  [..]
2273
    This subsection provides a set of functions allowing to return the State of IrDA
2274
    communication process and also return Peripheral Errors occurred during communication process
2275
     (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state
2276
         of the IRDA peripheral handle.
2277
     (+) HAL_IRDA_GetError() checks in run-time errors that could occur during
2278
         communication.
2279
 
2280
@endverbatim
2281
  * @{
2282
  */
2283
 
2284
/**
2285
  * @brief Return the IRDA handle state.
2286
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2287
  *                the configuration information for the specified IRDA module.
2288
  * @retval HAL state
2289
  */
2290
HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
2291
{
2292
  /* Return IRDA handle state */
2293
  uint32_t temp1;
2294
  uint32_t temp2;
2295
  temp1 = (uint32_t)hirda->gState;
2296
  temp2 = (uint32_t)hirda->RxState;
2297
 
2298
  return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
2299
}
2300
 
2301
/**
2302
  * @brief Return the IRDA handle error code.
2303
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2304
  *               the configuration information for the specified IRDA module.
2305
  * @retval IRDA Error Code
2306
  */
2307
uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
2308
{
2309
  return hirda->ErrorCode;
2310
}
2311
 
2312
/**
2313
  * @}
2314
  */
2315
 
2316
/**
2317
  * @}
2318
  */
2319
 
2320
/** @defgroup IRDA_Private_Functions IRDA Private Functions
2321
  * @{
2322
  */
2323
 
2324
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2325
/**
2326
  * @brief  Initialize the callbacks to their default values.
2327
  * @param  hirda IRDA handle.
2328
  * @retval none
2329
  */
2330
void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
2331
{
2332
  /* Init the IRDA Callback settings */
2333
  hirda->TxHalfCpltCallback        = HAL_IRDA_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2334
  hirda->TxCpltCallback            = HAL_IRDA_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2335
  hirda->RxHalfCpltCallback        = HAL_IRDA_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2336
  hirda->RxCpltCallback            = HAL_IRDA_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2337
  hirda->ErrorCallback             = HAL_IRDA_ErrorCallback;             /* Legacy weak ErrorCallback             */
2338
  hirda->AbortCpltCallback         = HAL_IRDA_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2339
  hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2340
  hirda->AbortReceiveCpltCallback  = HAL_IRDA_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
2341
 
2342
}
2343
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2344
 
2345
/**
2346
  * @brief Configure the IRDA peripheral.
2347
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2348
  *               the configuration information for the specified IRDA module.
2349
  * @retval HAL status
2350
  */
2351
static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
2352
{
2353
  uint32_t tmpreg;
2354
  IRDA_ClockSourceTypeDef clocksource;
2355
  HAL_StatusTypeDef ret = HAL_OK;
2356
  uint32_t pclk;
2357
 
2358
  /* Check the communication parameters */
2359
  assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
2360
  assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
2361
  assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
2362
  assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode));
2363
  assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler));
2364
  assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode));
2365
 
2366
  /*-------------------------- USART CR1 Configuration -----------------------*/
2367
  /* Configure the IRDA Word Length, Parity and transfer Mode:
2368
     Set the M bits according to hirda->Init.WordLength value
2369
     Set PCE and PS bits according to hirda->Init.Parity value
2370
     Set TE and RE bits according to hirda->Init.Mode value */
2371
  tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ;
2372
 
2373
  MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg);
2374
 
2375
  /*-------------------------- USART CR3 Configuration -----------------------*/
2376
  MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode);
2377
 
2378
 
2379
  /*-------------------------- USART GTPR Configuration ----------------------*/
2380
  MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler);
2381
 
2382
  /*-------------------------- USART BRR Configuration -----------------------*/
2383
  IRDA_GETCLOCKSOURCE(hirda, clocksource);
2384
  tmpreg =   0U;
2385
  switch (clocksource)
2386
  {
2387
    case IRDA_CLOCKSOURCE_PCLK1:
2388
      pclk = HAL_RCC_GetPCLK1Freq();
2389
      tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate));
2390
      break;
2391
    case IRDA_CLOCKSOURCE_HSI:
2392
      tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate));
2393
      break;
2394
    case IRDA_CLOCKSOURCE_SYSCLK:
2395
      pclk = HAL_RCC_GetSysClockFreq();
2396
      tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate));
2397
      break;
2398
    case IRDA_CLOCKSOURCE_LSE:
2399
      tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate));
2400
      break;
2401
    default:
2402
      ret = HAL_ERROR;
2403
      break;
2404
  }
2405
 
2406
  /* USARTDIV must be greater than or equal to 0d16 */
2407
  if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX))
2408
  {
2409
    hirda->Instance->BRR = tmpreg;
2410
  }
2411
  else
2412
  {
2413
    ret = HAL_ERROR;
2414
  }
2415
 
2416
  return ret;
2417
}
2418
 
2419
/**
2420
  * @brief Check the IRDA Idle State.
2421
  * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
2422
  *               the configuration information for the specified IRDA module.
2423
  * @retval HAL status
2424
  */
2425
static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda)
2426
{
2427
  uint32_t tickstart;
2428
 
2429
  /* Initialize the IRDA ErrorCode */
2430
  hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2431
 
6 mjames 2432
  /* Init tickstart for timeout management */
2 mjames 2433
  tickstart = HAL_GetTick();
2434
 
2435
  /* Check if the Transmitter is enabled */
2436
  if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2437
  {
2438
    /* Wait until TEACK flag is set */
2439
    if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2440
    {
2441
      /* Timeout occurred */
2442
      return HAL_TIMEOUT;
2443
    }
2444
  }
2445
  /* Check if the Receiver is enabled */
2446
  if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2447
  {
2448
    /* Wait until REACK flag is set */
2449
    if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK)
2450
    {
2451
      /* Timeout occurred */
2452
      return HAL_TIMEOUT;
2453
    }
2454
  }
2455
 
2456
  /* Initialize the IRDA state*/
2457
  hirda->gState  = HAL_IRDA_STATE_READY;
2458
  hirda->RxState = HAL_IRDA_STATE_READY;
2459
 
2460
  /* Process Unlocked */
2461
  __HAL_UNLOCK(hirda);
2462
 
2463
  return HAL_OK;
2464
}
2465
 
2466
/**
2467
  * @brief  Handle IRDA Communication Timeout.
2468
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2469
  *               the configuration information for the specified IRDA module.
2470
  * @param  Flag Specifies the IRDA flag to check.
2471
  * @param  Status Flag status (SET or RESET)
2472
  * @param  Tickstart Tick start value
2473
  * @param  Timeout Timeout duration
2474
  * @retval HAL status
2475
  */
2476
static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status,
2477
                                                     uint32_t Tickstart, uint32_t Timeout)
2478
{
2479
  /* Wait until flag is set */
2480
  while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
2481
  {
2482
    /* Check for the Timeout */
2483
    if (Timeout != HAL_MAX_DELAY)
2484
    {
2485
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2486
      {
6 mjames 2487
        /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
2488
           interrupts for the interrupt process */
2 mjames 2489
        CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
2490
        CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2491
 
2492
        hirda->gState  = HAL_IRDA_STATE_READY;
2493
        hirda->RxState = HAL_IRDA_STATE_READY;
2494
 
2495
        /* Process Unlocked */
2496
        __HAL_UNLOCK(hirda);
2497
        return HAL_TIMEOUT;
2498
      }
2499
    }
2500
  }
2501
  return HAL_OK;
2502
}
2503
 
2504
 
2505
/**
2506
  * @brief  End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
2507
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2508
  *               the configuration information for the specified IRDA module.
2509
  * @retval None
2510
  */
2511
static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
2512
{
2513
  /* Disable TXEIE and TCIE interrupts */
2514
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2515
 
2516
  /* At end of Tx process, restore hirda->gState to Ready */
2517
  hirda->gState = HAL_IRDA_STATE_READY;
2518
}
2519
 
2520
 
2521
/**
2522
  * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
2523
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2524
  *               the configuration information for the specified IRDA module.
2525
  * @retval None
2526
  */
2527
static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
2528
{
2529
  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2530
  CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2531
  CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2532
 
2533
  /* At end of Rx process, restore hirda->RxState to Ready */
2534
  hirda->RxState = HAL_IRDA_STATE_READY;
2535
}
2536
 
2537
 
2538
/**
2539
  * @brief  DMA IRDA transmit process complete callback.
2540
  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2541
  *              the configuration information for the specified DMA module.
2542
  * @retval None
2543
  */
2544
static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2545
{
2546
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2547
 
2548
  /* DMA Normal mode */
2549
  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2550
  {
2551
    hirda->TxXferCount = 0U;
2552
 
2553
    /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2554
       in the IRDA CR3 register */
2555
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
2556
 
2557
    /* Enable the IRDA Transmit Complete Interrupt */
2558
    SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2559
  }
2560
  /* DMA Circular mode */
2561
  else
2562
  {
2563
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2564
    /* Call registered Tx complete callback */
2565
    hirda->TxCpltCallback(hirda);
2566
#else
2567
    /* Call legacy weak Tx complete callback */
2568
    HAL_IRDA_TxCpltCallback(hirda);
2569
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2570
  }
2571
 
2572
}
2573
 
2574
/**
2575
  * @brief  DMA IRDA transmit process half complete callback.
2576
  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2577
  *              the configuration information for the specified DMA module.
2578
  * @retval None
2579
  */
2580
static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
2581
{
2582
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2583
 
2584
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2585
  /* Call registered Tx Half complete callback */
2586
  hirda->TxHalfCpltCallback(hirda);
2587
#else
2588
  /* Call legacy weak Tx complete callback */
2589
  HAL_IRDA_TxHalfCpltCallback(hirda);
2590
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2591
}
2592
 
2593
/**
2594
  * @brief  DMA IRDA receive process complete callback.
2595
  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
2596
  *               the configuration information for the specified DMA module.
2597
  * @retval None
2598
  */
2599
static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2600
{
2601
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2602
 
2603
  /* DMA Normal mode */
2604
  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2605
  {
2606
    hirda->RxXferCount = 0U;
2607
 
2608
    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2609
    CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
2610
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2611
 
2612
    /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2613
       in the IRDA CR3 register */
2614
    CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
2615
 
2616
    /* At end of Rx process, restore hirda->RxState to Ready */
2617
    hirda->RxState = HAL_IRDA_STATE_READY;
2618
  }
2619
 
2620
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2621
  /* Call registered Rx complete callback */
2622
  hirda->RxCpltCallback(hirda);
2623
#else
2624
  /* Call legacy weak Rx complete callback */
2625
  HAL_IRDA_RxCpltCallback(hirda);
2626
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2627
}
2628
 
2629
/**
2630
  * @brief DMA IRDA receive process half complete callback.
2631
  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2632
  *              the configuration information for the specified DMA module.
2633
  * @retval None
2634
  */
2635
static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
2636
{
2637
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2638
 
2639
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2640
  /*Call registered Rx Half complete callback*/
2641
  hirda->RxHalfCpltCallback(hirda);
2642
#else
2643
  /* Call legacy weak Rx Half complete callback */
2644
  HAL_IRDA_RxHalfCpltCallback(hirda);
2645
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2646
}
2647
 
2648
/**
2649
  * @brief DMA IRDA communication error callback.
2650
  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
2651
  *              the configuration information for the specified DMA module.
2652
  * @retval None
2653
  */
2654
static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
2655
{
2656
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2657
 
2658
  /* Stop IRDA DMA Tx request if ongoing */
2659
  if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2660
  {
2661
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
2662
    {
2663
      hirda->TxXferCount = 0U;
2664
      IRDA_EndTxTransfer(hirda);
2665
    }
2666
  }
2667
 
2668
  /* Stop IRDA DMA Rx request if ongoing */
2669
  if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2670
  {
2671
    if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
2672
    {
2673
      hirda->RxXferCount = 0U;
2674
      IRDA_EndRxTransfer(hirda);
2675
    }
2676
  }
2677
 
2678
  hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
2679
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2680
  /* Call registered user error callback */
2681
  hirda->ErrorCallback(hirda);
2682
#else
2683
  /* Call legacy weak user error callback */
2684
  HAL_IRDA_ErrorCallback(hirda);
2685
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2686
}
2687
 
2688
/**
2689
  * @brief  DMA IRDA communication abort callback, when initiated by HAL services on Error
2690
  *         (To be called at end of DMA Abort procedure following error occurrence).
2691
  * @param  hdma DMA handle.
2692
  * @retval None
2693
  */
2694
static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2695
{
2696
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2697
  hirda->RxXferCount = 0U;
2698
  hirda->TxXferCount = 0U;
2699
 
2700
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2701
  /* Call registered user error callback */
2702
  hirda->ErrorCallback(hirda);
2703
#else
2704
  /* Call legacy weak user error callback */
2705
  HAL_IRDA_ErrorCallback(hirda);
2706
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2707
}
2708
 
2709
/**
2710
  * @brief  DMA IRDA Tx communication abort callback, when initiated by user
2711
  *         (To be called at end of DMA Tx Abort procedure following user abort request).
2712
  * @note   When this callback is executed, User Abort complete call back is called only if no
2713
  *         Abort still ongoing for Rx DMA Handle.
2714
  * @param  hdma DMA handle.
2715
  * @retval None
2716
  */
2717
static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2718
{
2719
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2720
 
2721
  hirda->hdmatx->XferAbortCallback = NULL;
2722
 
2723
  /* Check if an Abort process is still ongoing */
2724
  if (hirda->hdmarx != NULL)
2725
  {
2726
    if (hirda->hdmarx->XferAbortCallback != NULL)
2727
    {
2728
      return;
2729
    }
2730
  }
2731
 
2732
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2733
  hirda->TxXferCount = 0U;
2734
  hirda->RxXferCount = 0U;
2735
 
2736
  /* Reset errorCode */
2737
  hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2738
 
2739
  /* Clear the Error flags in the ICR register */
2740
  __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2741
 
2742
  /* Restore hirda->gState and hirda->RxState to Ready */
2743
  hirda->gState  = HAL_IRDA_STATE_READY;
2744
  hirda->RxState = HAL_IRDA_STATE_READY;
2745
 
2746
  /* Call user Abort complete callback */
2747
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2748
  /* Call registered Abort complete callback */
2749
  hirda->AbortCpltCallback(hirda);
2750
#else
2751
  /* Call legacy weak Abort complete callback */
2752
  HAL_IRDA_AbortCpltCallback(hirda);
2753
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2754
}
2755
 
2756
 
2757
/**
2758
  * @brief  DMA IRDA Rx communication abort callback, when initiated by user
2759
  *         (To be called at end of DMA Rx Abort procedure following user abort request).
2760
  * @note   When this callback is executed, User Abort complete call back is called only if no
2761
  *         Abort still ongoing for Tx DMA Handle.
2762
  * @param  hdma DMA handle.
2763
  * @retval None
2764
  */
2765
static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2766
{
2767
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2768
 
2769
  hirda->hdmarx->XferAbortCallback = NULL;
2770
 
2771
  /* Check if an Abort process is still ongoing */
2772
  if (hirda->hdmatx != NULL)
2773
  {
2774
    if (hirda->hdmatx->XferAbortCallback != NULL)
2775
    {
2776
      return;
2777
    }
2778
  }
2779
 
2780
  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2781
  hirda->TxXferCount = 0U;
2782
  hirda->RxXferCount = 0U;
2783
 
2784
  /* Reset errorCode */
2785
  hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
2786
 
2787
  /* Clear the Error flags in the ICR register */
2788
  __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2789
 
2790
  /* Restore hirda->gState and hirda->RxState to Ready */
2791
  hirda->gState  = HAL_IRDA_STATE_READY;
2792
  hirda->RxState = HAL_IRDA_STATE_READY;
2793
 
2794
  /* Call user Abort complete callback */
2795
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2796
  /* Call registered Abort complete callback */
2797
  hirda->AbortCpltCallback(hirda);
2798
#else
2799
  /* Call legacy weak Abort complete callback */
2800
  HAL_IRDA_AbortCpltCallback(hirda);
2801
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2802
}
2803
 
2804
 
2805
/**
2806
  * @brief  DMA IRDA Tx communication abort callback, when initiated by user by a call to
2807
  *         HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
2808
  *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2809
  *         and leads to user Tx Abort Complete callback execution).
2810
  * @param  hdma DMA handle.
2811
  * @retval None
2812
  */
2813
static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2814
{
2815
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent);
2816
 
2817
  hirda->TxXferCount = 0U;
2818
 
2819
  /* Restore hirda->gState to Ready */
2820
  hirda->gState = HAL_IRDA_STATE_READY;
2821
 
2822
  /* Call user Abort complete callback */
2823
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2824
  /* Call registered Abort Transmit Complete Callback */
2825
  hirda->AbortTransmitCpltCallback(hirda);
2826
#else
2827
  /* Call legacy weak Abort Transmit Complete Callback */
2828
  HAL_IRDA_AbortTransmitCpltCallback(hirda);
2829
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2830
}
2831
 
2832
/**
2833
  * @brief  DMA IRDA Rx communication abort callback, when initiated by user by a call to
2834
  *         HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
2835
  *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2836
  *         and leads to user Rx Abort Complete callback execution).
2837
  * @param  hdma DMA handle.
2838
  * @retval None
2839
  */
2840
static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2841
{
2842
  IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2843
 
2844
  hirda->RxXferCount = 0U;
2845
 
2846
  /* Clear the Error flags in the ICR register */
2847
  __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF);
2848
 
2849
  /* Restore hirda->RxState to Ready */
2850
  hirda->RxState = HAL_IRDA_STATE_READY;
2851
 
2852
  /* Call user Abort complete callback */
2853
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2854
  /* Call registered Abort Receive Complete Callback */
2855
  hirda->AbortReceiveCpltCallback(hirda);
2856
#else
2857
  /* Call legacy weak Abort Receive Complete Callback */
2858
  HAL_IRDA_AbortReceiveCpltCallback(hirda);
2859
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2860
}
2861
 
2862
/**
2863
  * @brief  Send an amount of data in interrupt mode.
2864
  * @note   Function is called under interruption only, once
2865
  *         interruptions have been enabled by HAL_IRDA_Transmit_IT().
2866
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2867
  *               the configuration information for the specified IRDA module.
2868
  * @retval None
2869
  */
2870
static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
2871
{
2872
  uint16_t *tmp;
2873
 
2874
  /* Check that a Tx process is ongoing */
2875
  if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
2876
  {
2877
    if (hirda->TxXferCount == 0U)
2878
    {
2879
      /* Disable the IRDA Transmit Data Register Empty Interrupt */
2880
      CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
2881
 
2882
      /* Enable the IRDA Transmit Complete Interrupt */
2883
      SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2884
    }
2885
    else
2886
    {
2887
      if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2888
      {
2889
        tmp = (uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */
2890
        hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
2891
        hirda->pTxBuffPtr += 2U;
2892
      }
2893
      else
2894
      {
2895
        hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU);
2896
        hirda->pTxBuffPtr++;
2897
      }
2898
      hirda->TxXferCount--;
2899
    }
2900
  }
2901
}
2902
 
2903
/**
2904
  * @brief  Wrap up transmission in non-blocking mode.
2905
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2906
  *               the configuration information for the specified IRDA module.
2907
  * @retval None
2908
  */
2909
static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
2910
{
2911
  /* Disable the IRDA Transmit Complete Interrupt */
2912
  CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
2913
 
2914
  /* Tx process is ended, restore hirda->gState to Ready */
2915
  hirda->gState = HAL_IRDA_STATE_READY;
2916
 
2917
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2918
  /* Call registered Tx complete callback */
2919
  hirda->TxCpltCallback(hirda);
2920
#else
2921
  /* Call legacy weak Tx complete callback */
2922
  HAL_IRDA_TxCpltCallback(hirda);
2923
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
2924
}
2925
 
2926
/**
2927
  * @brief  Receive an amount of data in interrupt mode.
2928
  * @note   Function is called under interruption only, once
2929
  *         interruptions have been enabled by HAL_IRDA_Receive_IT()
2930
  * @param  hirda Pointer to a IRDA_HandleTypeDef structure that contains
2931
  *               the configuration information for the specified IRDA module.
2932
  * @retval None
2933
  */
2934
static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
2935
{
2936
  uint16_t *tmp;
2937
  uint16_t  uhMask = hirda->Mask;
2938
  uint16_t  uhdata;
2939
 
2940
  /* Check that a Rx process is ongoing */
2941
  if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
2942
  {
2943
    uhdata = (uint16_t) READ_REG(hirda->Instance->RDR);
2944
    if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE))
2945
    {
2946
      tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */
2947
      *tmp = (uint16_t)(uhdata & uhMask);
2948
      hirda->pRxBuffPtr  += 2U;
2949
    }
2950
    else
2951
    {
2952
      *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
2953
      hirda->pRxBuffPtr++;
2954
    }
2955
 
2956
    hirda->RxXferCount--;
2957
    if (hirda->RxXferCount == 0U)
2958
    {
2959
      /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */
2960
      CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2961
 
2962
      /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
2963
      CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
2964
 
2965
      /* Rx process is completed, restore hirda->RxState to Ready */
2966
      hirda->RxState = HAL_IRDA_STATE_READY;
2967
 
2968
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
2969
      /* Call registered Rx complete callback */
2970
      hirda->RxCpltCallback(hirda);
2971
#else
2972
      /* Call legacy weak Rx complete callback */
2973
      HAL_IRDA_RxCpltCallback(hirda);
2974
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
2975
    }
2976
  }
2977
  else
2978
  {
2979
    /* Clear RXNE interrupt flag */
2980
    __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST);
2981
  }
2982
}
2983
 
2984
/**
2985
  * @}
2986
  */
2987
 
2988
#endif /* HAL_IRDA_MODULE_ENABLED */
2989
/**
2990
  * @}
2991
  */
2992
 
2993
/**
2994
  * @}
2995
  */
2996
#endif /* USART_IRDA_SUPPORT */
2997
 
2998
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/