Subversion Repositories FuelGauge

Rev

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