Subversion Repositories LedShow

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_i2s.c
4
  * @author  MCD Application Team
5
  * @brief   I2S HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
8
  *           + Initialization and de-initialization functions
9
  *           + IO operation functions
10
  *           + Peripheral State and Errors functions
11
  @verbatim
12
 ===============================================================================
13
                  ##### How to use this driver #####
14
 ===============================================================================
15
 [..]
16
    The I2S HAL driver can be used as follow:
17
 
18
    (#) Declare a I2S_HandleTypeDef handle structure.
19
    (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
20
        (##) Enable the SPIx interface clock.
21
        (##) I2S pins configuration:
22
            (+++) Enable the clock for the I2S GPIOs.
9 mjames 23
            (+++) Configure these I2S pins as alternate function pull-up.
2 mjames 24
        (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
25
             and HAL_I2S_Receive_IT() APIs).
26
            (+++) Configure the I2Sx interrupt priority.
27
            (+++) Enable the NVIC I2S IRQ handle.
28
        (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
29
             and HAL_I2S_Receive_DMA() APIs:
9 mjames 30
            (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
2 mjames 31
            (+++) Enable the DMAx interface clock.
9 mjames 32
            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
33
            (+++) Configure the DMA Tx/Rx Stream/Channel.
2 mjames 34
            (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
9 mjames 35
            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
36
                  DMA Tx/Rx Stream/Channel.
2 mjames 37
 
38
   (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
39
       using HAL_I2S_Init() function.
40
 
41
   -@- The specific I2S interrupts (Transmission complete interrupt,
42
       RXNE interrupt and Error Interrupts) will be managed using the macros
43
       __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
9 mjames 44
   -@- The I2SxCLK source is the system clock (provided by the HSI, the HSE or the PLL, and sourcing the AHB clock).
45
       For connectivity line devices, the I2SxCLK source can be either SYSCLK or the PLL3 VCO (2 x PLL3CLK) clock
2 mjames 46
       in order to achieve the maximum accuracy.
47
   -@- Make sure that either:
9 mjames 48
        (+@) External clock source is configured after setting correctly
49
             the define constant HSE_VALUE in the stm32f1xx_hal_conf.h file.
2 mjames 50
 
9 mjames 51
    (#) Three mode of operations are available within this driver :
2 mjames 52
 
53
   *** Polling mode IO operation ***
54
   =================================
55
   [..]
56
     (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
57
     (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
58
 
59
   *** Interrupt mode IO operation ***
60
   ===================================
61
   [..]
62
     (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
63
     (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
64
         add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
65
     (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
66
         add his own code by customization of function pointer HAL_I2S_TxCpltCallback
67
     (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
68
     (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
69
         add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
70
     (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
71
         add his own code by customization of function pointer HAL_I2S_RxCpltCallback
72
     (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
73
         add his own code by customization of function pointer HAL_I2S_ErrorCallback
74
 
75
   *** DMA mode IO operation ***
76
   ==============================
77
   [..]
78
     (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
79
     (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
80
         add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
81
     (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
82
         add his own code by customization of function pointer HAL_I2S_TxCpltCallback
83
     (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
84
     (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
85
         add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
86
     (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
87
         add his own code by customization of function pointer HAL_I2S_RxCpltCallback
88
     (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
89
         add his own code by customization of function pointer HAL_I2S_ErrorCallback
90
     (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
91
     (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
92
     (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
9 mjames 93
         In Slave mode, if HAL_I2S_DMAStop is used to stop the communication, an error
94
         HAL_I2S_ERROR_BUSY_LINE_RX is raised as the master continue to transmit data.
95
         In this case __HAL_I2S_FLUSH_RX_DR macro must be used to flush the remaining data
96
         inside DR register and avoid using DeInit/Init process for the next transfer.
2 mjames 97
 
98
   *** I2S HAL driver macros list ***
9 mjames 99
   ===================================
2 mjames 100
   [..]
101
     Below the list of most used macros in I2S HAL driver.
102
 
103
      (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
104
      (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
105
      (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
106
      (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
107
      (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
9 mjames 108
      (+) __HAL_I2S_FLUSH_RX_DR: Read DR Register to Flush RX Data
2 mjames 109
 
110
    [..]
111
      (@) You can refer to the I2S HAL driver header file for more useful macros
112
 
9 mjames 113
   *** I2S HAL driver macros list ***
114
   ===================================
115
   [..]
116
       Callback registration:
2 mjames 117
 
9 mjames 118
      (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1U
119
          allows the user to configure dynamically the driver callbacks.
120
          Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
121
 
122
          Function HAL_I2S_RegisterCallback() allows to register following callbacks:
123
            (++) TxCpltCallback        : I2S Tx Completed callback
124
            (++) RxCpltCallback        : I2S Rx Completed callback
125
            (++) TxHalfCpltCallback    : I2S Tx Half Completed callback
126
            (++) RxHalfCpltCallback    : I2S Rx Half Completed callback
127
            (++) ErrorCallback         : I2S Error callback
128
            (++) MspInitCallback       : I2S Msp Init callback
129
            (++) MspDeInitCallback     : I2S Msp DeInit callback
130
          This function takes as parameters the HAL peripheral handle, the Callback ID
131
          and a pointer to the user callback function.
132
 
133
 
134
      (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
135
          weak function.
136
          HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
137
          and the Callback ID.
138
          This function allows to reset following callbacks:
139
            (++) TxCpltCallback        : I2S Tx Completed callback
140
            (++) RxCpltCallback        : I2S Rx Completed callback
141
            (++) TxHalfCpltCallback    : I2S Tx Half Completed callback
142
            (++) RxHalfCpltCallback    : I2S Rx Half Completed callback
143
            (++) ErrorCallback         : I2S Error callback
144
            (++) MspInitCallback       : I2S Msp Init callback
145
            (++) MspDeInitCallback     : I2S Msp DeInit callback
146
 
147
       [..]
148
       By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
149
       all callbacks are set to the corresponding weak functions:
150
       examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
151
       Exception done for MspInit and MspDeInit functions that are
152
       reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
153
       these callbacks are null (not registered beforehand).
154
       If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
155
       keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
156
 
157
       [..]
158
       Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
159
       Exception done MspInit/MspDeInit functions that can be registered/unregistered
160
       in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
161
       thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
162
       Then, the user first registers the MspInit/MspDeInit user callbacks
163
       using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
164
       or HAL_I2S_Init() function.
165
 
166
       [..]
167
       When the compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
168
       not defined, the callback registering feature is not available
169
       and weak (surcharged) callbacks are used.
170
 
171
   *** I2S Workarounds linked to Silicon Limitation ***
172
   ====================================================
173
   [..]
174
       (@) Only the 16-bit mode with no data extension can be used when the I2S
2 mjames 175
           is in Master and used the PCM long synchronization mode.
176
 
177
  @endverbatim
178
  ******************************************************************************
179
  * @attention
180
  *
9 mjames 181
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
182
  * All rights reserved.</center></h2>
2 mjames 183
  *
9 mjames 184
  * This software component is licensed by ST under BSD 3-Clause license,
185
  * the "License"; You may not use this file except in compliance with the
186
  * License. You may obtain a copy of the License at:
187
  *                        opensource.org/licenses/BSD-3-Clause
2 mjames 188
  *
189
  ******************************************************************************
190
  */
191
 
192
/* Includes ------------------------------------------------------------------*/
193
#include "stm32f1xx_hal.h"
194
 
9 mjames 195
#ifdef HAL_I2S_MODULE_ENABLED
196
 
197
#if defined(SPI_I2S_SUPPORT)
2 mjames 198
/** @addtogroup STM32F1xx_HAL_Driver
199
  * @{
200
  */
201
 
202
/** @defgroup I2S I2S
203
  * @brief I2S HAL module driver
204
  * @{
205
  */
206
 
207
/* Private typedef -----------------------------------------------------------*/
208
/* Private define ------------------------------------------------------------*/
9 mjames 209
#define I2S_TIMEOUT_FLAG          100U         /*!< Timeout 100 ms            */
2 mjames 210
/* Private macro -------------------------------------------------------------*/
211
/* Private variables ---------------------------------------------------------*/
212
/* Private function prototypes -----------------------------------------------*/
9 mjames 213
/** @defgroup I2S_Private_Functions I2S Private Functions
2 mjames 214
  * @{
215
  */
216
static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
217
static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
218
static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
219
static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
220
static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
221
static void               I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
222
static void               I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
9 mjames 223
static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
2 mjames 224
                                                        uint32_t Timeout);
225
/**
226
  * @}
227
  */
228
 
229
/* Exported functions ---------------------------------------------------------*/
9 mjames 230
 
2 mjames 231
/** @defgroup I2S_Exported_Functions I2S Exported Functions
232
  * @{
233
  */
234
 
9 mjames 235
/** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
2 mjames 236
  *  @brief    Initialization and Configuration functions
237
  *
238
@verbatim
239
 ===============================================================================
240
              ##### Initialization and de-initialization functions #####
241
 ===============================================================================
242
    [..]  This subsection provides a set of functions allowing to initialize and
243
          de-initialize the I2Sx peripheral in simplex mode:
244
 
245
      (+) User must Implement HAL_I2S_MspInit() function in which he configures
246
          all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
247
 
248
      (+) Call the function HAL_I2S_Init() to configure the selected device with
249
          the selected configuration:
250
        (++) Mode
251
        (++) Standard
252
        (++) Data Format
253
        (++) MCLK Output
254
        (++) Audio frequency
255
        (++) Polarity
256
 
9 mjames 257
     (+) Call the function HAL_I2S_DeInit() to restore the default configuration
2 mjames 258
          of the selected I2Sx peripheral.
9 mjames 259
  @endverbatim
2 mjames 260
  * @{
261
  */
262
 
263
/**
9 mjames 264
  * @brief  Initializes the I2S according to the specified parameters
2 mjames 265
  *         in the I2S_InitTypeDef and create the associated handle.
9 mjames 266
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 267
  *         the configuration information for I2S module
268
  * @retval HAL status
269
  */
270
HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
271
{
9 mjames 272
  uint32_t i2sdiv;
273
  uint32_t i2sodd;
274
  uint32_t packetlength;
275
  uint32_t tmp;
276
  uint32_t i2sclk;
2 mjames 277
 
278
  /* Check the I2S handle allocation */
9 mjames 279
  if (hi2s == NULL)
2 mjames 280
  {
281
    return HAL_ERROR;
282
  }
283
 
284
  /* Check the I2S parameters */
285
  assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
286
  assert_param(IS_I2S_MODE(hi2s->Init.Mode));
287
  assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
288
  assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
289
  assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
290
  assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
291
  assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
292
 
9 mjames 293
  if (hi2s->State == HAL_I2S_STATE_RESET)
294
  {
295
    /* Allocate lock resource and initialize it */
296
    hi2s->Lock = HAL_UNLOCKED;
2 mjames 297
 
9 mjames 298
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
299
    /* Init the I2S Callback settings */
300
    hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
301
    hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
302
    hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
303
    hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
304
    hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
2 mjames 305
 
9 mjames 306
    if (hi2s->MspInitCallback == NULL)
307
    {
308
      hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
309
    }
2 mjames 310
 
9 mjames 311
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
312
    hi2s->MspInitCallback(hi2s);
313
#else
314
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
315
    HAL_I2S_MspInit(hi2s);
316
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
317
  }
318
 
319
  hi2s->State = HAL_I2S_STATE_BUSY;
320
 
321
  /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
2 mjames 322
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
9 mjames 323
  CLEAR_BIT(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
324
                                      SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
325
                                      SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
2 mjames 326
  hi2s->Instance->I2SPR = 0x0002U;
327
 
9 mjames 328
  /*----------------------- I2SPR: I2SDIV and ODD Calculation -----------------*/
2 mjames 329
  /* If the requested audio frequency is not the default, compute the prescaler */
9 mjames 330
  if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
2 mjames 331
  {
9 mjames 332
    /* Check the frame length (For the Prescaler computing) ********************/
333
    if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
2 mjames 334
    {
9 mjames 335
      /* Packet length is 16 bits */
336
      packetlength = 16U;
2 mjames 337
    }
338
    else
339
    {
9 mjames 340
      /* Packet length is 32 bits */
341
      packetlength = 32U;
2 mjames 342
    }
343
 
344
    /* I2S standard */
9 mjames 345
    if (hi2s->Init.Standard <= I2S_STANDARD_LSB)
2 mjames 346
    {
9 mjames 347
      /* In I2S standard packet length is multiplied by 2 */
2 mjames 348
      packetlength = packetlength * 2U;
349
    }
350
 
9 mjames 351
    /* Get the source clock value **********************************************/
352
    if (hi2s->Instance == SPI2)
2 mjames 353
    {
354
      /* Get the source clock value: based on SPI2 Instance */
355
      i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S2);
356
    }
9 mjames 357
    else if (hi2s->Instance == SPI3)
2 mjames 358
    {
359
      /* Get the source clock value: based on SPI3 Instance */
360
      i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S3);
361
    }
362
    else
363
    {
364
      /* Get the source clock value: based on System Clock value */
365
      i2sclk = HAL_RCC_GetSysClockFreq();
366
    }
367
    /* Compute the Real divider depending on the MCLK output state, with a floating point */
9 mjames 368
    if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
2 mjames 369
    {
370
      /* MCLK output is enabled */
371
      if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
372
      {
9 mjames 373
        tmp = (uint32_t)(((((i2sclk / (packetlength * 4U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
2 mjames 374
      }
375
      else
376
      {
9 mjames 377
        tmp = (uint32_t)(((((i2sclk / (packetlength * 8U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
2 mjames 378
      }
379
    }
380
    else
381
    {
382
      /* MCLK output is disabled */
9 mjames 383
      tmp = (uint32_t)(((((i2sclk / packetlength) * 10U) / hi2s->Init.AudioFreq)) + 5U);
2 mjames 384
    }
385
 
386
    /* Remove the flatting point */
387
    tmp = tmp / 10U;
388
 
389
    /* Check the parity of the divider */
9 mjames 390
    i2sodd = (uint32_t)(tmp & (uint32_t)1U);
2 mjames 391
 
392
    /* Compute the i2sdiv prescaler */
9 mjames 393
    i2sdiv = (uint32_t)((tmp - i2sodd) / 2U);
2 mjames 394
 
395
    /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
9 mjames 396
    i2sodd = (uint32_t)(i2sodd << 8U);
2 mjames 397
  }
9 mjames 398
  else
2 mjames 399
  {
400
    /* Set the default values */
401
    i2sdiv = 2U;
402
    i2sodd = 0U;
9 mjames 403
  }
2 mjames 404
 
9 mjames 405
  /* Test if the divider is 1 or 0 or greater than 0xFF */
406
  if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
407
  {
2 mjames 408
    /* Set the error code and execute error callback*/
409
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
410
    return  HAL_ERROR;
411
  }
412
 
9 mjames 413
  /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
414
 
2 mjames 415
  /* Write to SPIx I2SPR register the computed value */
416
  hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
417
 
9 mjames 418
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
419
  /* And configure the I2S with the I2S_InitStruct values                      */
420
  MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
421
                                       SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
422
                                       SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
423
                                       SPI_I2SCFGR_I2SE  | SPI_I2SCFGR_I2SMOD), \
424
             (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \
425
              hi2s->Init.Standard | hi2s->Init.DataFormat | \
426
              hi2s->Init.CPOL));
427
 
428
#if defined(SPI_I2SCFGR_ASTRTEN)
429
  if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || ((hi2s->Init.Standard == I2S_STANDARD_PCM_LONG)))
430
  {
431
    /* Write to SPIx I2SCFGR */
432
    SET_BIT(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_ASTRTEN);
433
  }
434
#endif /* SPI_I2SCFGR_ASTRTEN */
435
 
2 mjames 436
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
437
  hi2s->State     = HAL_I2S_STATE_READY;
438
 
439
  return HAL_OK;
440
}
441
 
442
/**
443
  * @brief DeInitializes the I2S peripheral
9 mjames 444
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 445
  *         the configuration information for I2S module
446
  * @retval HAL status
447
  */
448
HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
449
{
450
  /* Check the I2S handle allocation */
9 mjames 451
  if (hi2s == NULL)
2 mjames 452
  {
453
    return HAL_ERROR;
454
  }
455
 
9 mjames 456
  /* Check the parameters */
457
  assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
458
 
2 mjames 459
  hi2s->State = HAL_I2S_STATE_BUSY;
460
 
9 mjames 461
  /* Disable the I2S Peripheral Clock */
462
  __HAL_I2S_DISABLE(hi2s);
463
 
464
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
465
  if (hi2s->MspDeInitCallback == NULL)
466
  {
467
    hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
468
  }
469
 
2 mjames 470
  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
9 mjames 471
  hi2s->MspDeInitCallback(hi2s);
472
#else
473
  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
2 mjames 474
  HAL_I2S_MspDeInit(hi2s);
9 mjames 475
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 476
 
477
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
478
  hi2s->State     = HAL_I2S_STATE_RESET;
479
 
480
  /* Release Lock */
481
  __HAL_UNLOCK(hi2s);
482
 
483
  return HAL_OK;
484
}
485
 
486
/**
487
  * @brief I2S MSP Init
9 mjames 488
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 489
  *         the configuration information for I2S module
490
  * @retval None
491
  */
9 mjames 492
__weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
2 mjames 493
{
494
  /* Prevent unused argument(s) compilation warning */
495
  UNUSED(hi2s);
9 mjames 496
 
2 mjames 497
  /* NOTE : This function Should not be modified, when the callback is needed,
498
            the HAL_I2S_MspInit could be implemented in the user file
499
   */
500
}
501
 
502
/**
503
  * @brief I2S MSP DeInit
9 mjames 504
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 505
  *         the configuration information for I2S module
506
  * @retval None
507
  */
9 mjames 508
__weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
2 mjames 509
{
510
  /* Prevent unused argument(s) compilation warning */
511
  UNUSED(hi2s);
9 mjames 512
 
2 mjames 513
  /* NOTE : This function Should not be modified, when the callback is needed,
514
            the HAL_I2S_MspDeInit could be implemented in the user file
515
   */
516
}
9 mjames 517
 
518
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2 mjames 519
/**
9 mjames 520
  * @brief  Register a User I2S Callback
521
  *         To be used instead of the weak predefined callback
522
  * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
523
  *                the configuration information for the specified I2S.
524
  * @param  CallbackID ID of the callback to be registered
525
  * @param  pCallback pointer to the Callback function
526
  * @retval HAL status
527
  */
528
HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
529
                                           pI2S_CallbackTypeDef pCallback)
530
{
531
  HAL_StatusTypeDef status = HAL_OK;
532
 
533
  if (pCallback == NULL)
534
  {
535
    /* Update the error code */
536
    hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
537
 
538
    return HAL_ERROR;
539
  }
540
  /* Process locked */
541
  __HAL_LOCK(hi2s);
542
 
543
  if (HAL_I2S_STATE_READY == hi2s->State)
544
  {
545
    switch (CallbackID)
546
    {
547
      case HAL_I2S_TX_COMPLETE_CB_ID :
548
        hi2s->TxCpltCallback = pCallback;
549
        break;
550
 
551
      case HAL_I2S_RX_COMPLETE_CB_ID :
552
        hi2s->RxCpltCallback = pCallback;
553
        break;
554
 
555
      case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
556
        hi2s->TxHalfCpltCallback = pCallback;
557
        break;
558
 
559
      case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
560
        hi2s->RxHalfCpltCallback = pCallback;
561
        break;
562
 
563
      case HAL_I2S_ERROR_CB_ID :
564
        hi2s->ErrorCallback = pCallback;
565
        break;
566
 
567
      case HAL_I2S_MSPINIT_CB_ID :
568
        hi2s->MspInitCallback = pCallback;
569
        break;
570
 
571
      case HAL_I2S_MSPDEINIT_CB_ID :
572
        hi2s->MspDeInitCallback = pCallback;
573
        break;
574
 
575
      default :
576
        /* Update the error code */
577
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
578
 
579
        /* Return error status */
580
        status =  HAL_ERROR;
581
        break;
582
    }
583
  }
584
  else if (HAL_I2S_STATE_RESET == hi2s->State)
585
  {
586
    switch (CallbackID)
587
    {
588
      case HAL_I2S_MSPINIT_CB_ID :
589
        hi2s->MspInitCallback = pCallback;
590
        break;
591
 
592
      case HAL_I2S_MSPDEINIT_CB_ID :
593
        hi2s->MspDeInitCallback = pCallback;
594
        break;
595
 
596
      default :
597
        /* Update the error code */
598
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
599
 
600
        /* Return error status */
601
        status =  HAL_ERROR;
602
        break;
603
    }
604
  }
605
  else
606
  {
607
    /* Update the error code */
608
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
609
 
610
    /* Return error status */
611
    status =  HAL_ERROR;
612
  }
613
 
614
  /* Release Lock */
615
  __HAL_UNLOCK(hi2s);
616
  return status;
617
}
618
 
619
/**
620
  * @brief  Unregister an I2S Callback
621
  *         I2S callback is redirected to the weak predefined callback
622
  * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
623
  *                the configuration information for the specified I2S.
624
  * @param  CallbackID ID of the callback to be unregistered
625
  * @retval HAL status
626
  */
627
HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
628
{
629
  HAL_StatusTypeDef status = HAL_OK;
630
 
631
  /* Process locked */
632
  __HAL_LOCK(hi2s);
633
 
634
  if (HAL_I2S_STATE_READY == hi2s->State)
635
  {
636
    switch (CallbackID)
637
    {
638
      case HAL_I2S_TX_COMPLETE_CB_ID :
639
        hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
640
        break;
641
 
642
      case HAL_I2S_RX_COMPLETE_CB_ID :
643
        hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
644
        break;
645
 
646
      case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
647
        hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
648
        break;
649
 
650
      case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
651
        hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
652
        break;
653
 
654
      case HAL_I2S_ERROR_CB_ID :
655
        hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
656
        break;
657
 
658
      case HAL_I2S_MSPINIT_CB_ID :
659
        hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
660
        break;
661
 
662
      case HAL_I2S_MSPDEINIT_CB_ID :
663
        hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
664
        break;
665
 
666
      default :
667
        /* Update the error code */
668
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
669
 
670
        /* Return error status */
671
        status =  HAL_ERROR;
672
        break;
673
    }
674
  }
675
  else if (HAL_I2S_STATE_RESET == hi2s->State)
676
  {
677
    switch (CallbackID)
678
    {
679
      case HAL_I2S_MSPINIT_CB_ID :
680
        hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
681
        break;
682
 
683
      case HAL_I2S_MSPDEINIT_CB_ID :
684
        hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
685
        break;
686
 
687
      default :
688
        /* Update the error code */
689
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
690
 
691
        /* Return error status */
692
        status =  HAL_ERROR;
693
        break;
694
    }
695
  }
696
  else
697
  {
698
    /* Update the error code */
699
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
700
 
701
    /* Return error status */
702
    status =  HAL_ERROR;
703
  }
704
 
705
  /* Release Lock */
706
  __HAL_UNLOCK(hi2s);
707
  return status;
708
}
709
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
710
/**
2 mjames 711
  * @}
712
  */
713
 
9 mjames 714
/** @defgroup I2S_Exported_Functions_Group2 IO operation functions
715
  *  @brief Data transfers functions
2 mjames 716
  *
717
@verbatim
718
 ===============================================================================
719
                      ##### IO operation functions #####
720
 ===============================================================================
721
    [..]
722
    This subsection provides a set of functions allowing to manage the I2S data
723
    transfers.
724
 
725
    (#) There are two modes of transfer:
726
       (++) Blocking mode : The communication is performed in the polling mode.
727
            The status of all data processing is returned by the same function
728
            after finishing transfer.
729
       (++) No-Blocking mode : The communication is performed using Interrupts
730
            or DMA. These functions return the status of the transfer startup.
731
            The end of the data processing will be indicated through the
732
            dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
733
            using DMA mode.
734
 
735
    (#) Blocking mode functions are :
736
        (++) HAL_I2S_Transmit()
737
        (++) HAL_I2S_Receive()
738
 
739
    (#) No-Blocking mode functions with Interrupt are :
740
        (++) HAL_I2S_Transmit_IT()
741
        (++) HAL_I2S_Receive_IT()
742
 
743
    (#) No-Blocking mode functions with DMA are :
744
        (++) HAL_I2S_Transmit_DMA()
745
        (++) HAL_I2S_Receive_DMA()
746
 
747
    (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
748
        (++) HAL_I2S_TxCpltCallback()
749
        (++) HAL_I2S_RxCpltCallback()
750
        (++) HAL_I2S_ErrorCallback()
751
 
752
@endverbatim
753
  * @{
754
  */
755
 
756
/**
9 mjames 757
  * @brief  Transmit an amount of data in blocking mode
758
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 759
  *         the configuration information for I2S module
9 mjames 760
  * @param  pData a 16-bit pointer to data buffer.
761
  * @param  Size number of data sample to be sent:
762
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
763
  *         configuration phase, the Size parameter means the number of 16-bit data length
764
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
765
  *         the Size parameter means the number of 16-bit data length.
766
  * @param  Timeout Timeout duration
767
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
768
  *         between Master and Slave(example: audio streaming).
2 mjames 769
  * @retval HAL status
770
  */
771
HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
772
{
9 mjames 773
  uint32_t tmpreg_cfgr;
2 mjames 774
 
9 mjames 775
  if ((pData == NULL) || (Size == 0U))
2 mjames 776
  {
777
    return  HAL_ERROR;
778
  }
779
 
9 mjames 780
  /* Process Locked */
781
  __HAL_LOCK(hi2s);
782
 
783
  if (hi2s->State != HAL_I2S_STATE_READY)
2 mjames 784
  {
9 mjames 785
    __HAL_UNLOCK(hi2s);
786
    return HAL_BUSY;
787
  }
2 mjames 788
 
9 mjames 789
  /* Set state and reset error code */
790
  hi2s->State = HAL_I2S_STATE_BUSY_TX;
791
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
792
  hi2s->pTxBuffPtr = pData;
2 mjames 793
 
9 mjames 794
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 795
 
9 mjames 796
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
797
  {
798
    hi2s->TxXferSize = (Size << 1U);
799
    hi2s->TxXferCount = (Size << 1U);
800
  }
801
  else
802
  {
803
    hi2s->TxXferSize = Size;
804
    hi2s->TxXferCount = Size;
805
  }
2 mjames 806
 
9 mjames 807
  tmpreg_cfgr = hi2s->Instance->I2SCFGR;
2 mjames 808
 
9 mjames 809
  /* Check if the I2S is already enabled */
810
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
811
  {
812
    /* Enable I2S peripheral */
813
    __HAL_I2S_ENABLE(hi2s);
814
  }
2 mjames 815
 
9 mjames 816
  /* Wait until TXE flag is set */
817
  if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
818
  {
819
    /* Set the error code */
820
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
821
    hi2s->State = HAL_I2S_STATE_READY;
822
    __HAL_UNLOCK(hi2s);
823
    return HAL_ERROR;
824
  }
2 mjames 825
 
9 mjames 826
  while (hi2s->TxXferCount > 0U)
827
  {
828
    hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
829
    hi2s->pTxBuffPtr++;
830
    hi2s->TxXferCount--;
2 mjames 831
 
9 mjames 832
    /* Wait until TXE flag is set */
833
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
834
    {
835
      /* Set the error code */
836
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
837
      hi2s->State = HAL_I2S_STATE_READY;
838
      __HAL_UNLOCK(hi2s);
839
      return HAL_ERROR;
840
    }
2 mjames 841
 
9 mjames 842
    /* Check if an underrun occurs */
843
    if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
844
    {
845
      /* Clear underrun flag */
846
      __HAL_I2S_CLEAR_UDRFLAG(hi2s);
2 mjames 847
 
9 mjames 848
      /* Set the error code */
849
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
2 mjames 850
    }
9 mjames 851
  }
2 mjames 852
 
9 mjames 853
  /* Check if Slave mode is selected */
854
  if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
855
      || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
2 mjames 856
  {
9 mjames 857
    /* Wait until Busy flag is reset */
858
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
859
    {
860
      /* Set the error code */
861
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
862
      hi2s->State = HAL_I2S_STATE_READY;
863
      __HAL_UNLOCK(hi2s);
864
      return HAL_ERROR;
865
    }
2 mjames 866
  }
9 mjames 867
 
868
  hi2s->State = HAL_I2S_STATE_READY;
869
  __HAL_UNLOCK(hi2s);
870
  return HAL_OK;
2 mjames 871
}
872
 
873
/**
9 mjames 874
  * @brief  Receive an amount of data in blocking mode
875
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 876
  *         the configuration information for I2S module
9 mjames 877
  * @param  pData a 16-bit pointer to data buffer.
878
  * @param  Size number of data sample to be sent:
879
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
880
  *         configuration phase, the Size parameter means the number of 16-bit data length
881
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
882
  *         the Size parameter means the number of 16-bit data length.
883
  * @param  Timeout Timeout duration
884
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
885
  *         between Master and Slave(example: audio streaming).
886
  * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
887
  *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
2 mjames 888
  * @retval HAL status
889
  */
890
HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
891
{
9 mjames 892
  uint32_t tmpreg_cfgr;
2 mjames 893
 
9 mjames 894
  if ((pData == NULL) || (Size == 0U))
2 mjames 895
  {
896
    return  HAL_ERROR;
897
  }
898
 
9 mjames 899
  /* Process Locked */
900
  __HAL_LOCK(hi2s);
901
 
902
  if (hi2s->State != HAL_I2S_STATE_READY)
2 mjames 903
  {
9 mjames 904
    __HAL_UNLOCK(hi2s);
905
    return HAL_BUSY;
906
  }
2 mjames 907
 
9 mjames 908
  /* Set state and reset error code */
909
  hi2s->State = HAL_I2S_STATE_BUSY_RX;
910
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
911
  hi2s->pRxBuffPtr = pData;
2 mjames 912
 
9 mjames 913
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 914
 
9 mjames 915
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
916
  {
917
    hi2s->RxXferSize = (Size << 1U);
918
    hi2s->RxXferCount = (Size << 1U);
919
  }
920
  else
921
  {
922
    hi2s->RxXferSize = Size;
923
    hi2s->RxXferCount = Size;
924
  }
2 mjames 925
 
9 mjames 926
  /* Check if the I2S is already enabled */
927
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
928
  {
929
    /* Enable I2S peripheral */
930
    __HAL_I2S_ENABLE(hi2s);
931
  }
2 mjames 932
 
9 mjames 933
  /* Check if Master Receiver mode is selected */
934
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
935
  {
936
    /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
937
    access to the SPI_SR register. */
938
    __HAL_I2S_CLEAR_OVRFLAG(hi2s);
939
  }
2 mjames 940
 
9 mjames 941
  /* Receive data */
942
  while (hi2s->RxXferCount > 0U)
943
  {
944
    /* Wait until RXNE flag is set */
945
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
946
    {
947
      /* Set the error code */
948
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
949
      hi2s->State = HAL_I2S_STATE_READY;
950
      __HAL_UNLOCK(hi2s);
951
      return HAL_ERROR;
952
    }
2 mjames 953
 
9 mjames 954
    (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
955
    hi2s->pRxBuffPtr++;
956
    hi2s->RxXferCount--;
2 mjames 957
 
9 mjames 958
    /* Check if an overrun occurs */
959
    if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
960
    {
961
      /* Clear overrun flag */
962
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);
2 mjames 963
 
9 mjames 964
      /* Set the error code */
965
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
2 mjames 966
    }
9 mjames 967
  }
2 mjames 968
 
9 mjames 969
  hi2s->State = HAL_I2S_STATE_READY;
970
  __HAL_UNLOCK(hi2s);
971
  return HAL_OK;
2 mjames 972
}
973
 
974
/**
9 mjames 975
  * @brief  Transmit an amount of data in non-blocking mode with Interrupt
976
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 977
  *         the configuration information for I2S module
9 mjames 978
  * @param  pData a 16-bit pointer to data buffer.
979
  * @param  Size number of data sample to be sent:
980
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
981
  *         configuration phase, the Size parameter means the number of 16-bit data length
982
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
983
  *         the Size parameter means the number of 16-bit data length.
984
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
985
  *         between Master and Slave(example: audio streaming).
2 mjames 986
  * @retval HAL status
987
  */
988
HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
989
{
9 mjames 990
  uint32_t tmpreg_cfgr;
2 mjames 991
 
9 mjames 992
  if ((pData == NULL) || (Size == 0U))
2 mjames 993
  {
9 mjames 994
    return  HAL_ERROR;
995
  }
2 mjames 996
 
9 mjames 997
  /* Process Locked */
998
  __HAL_LOCK(hi2s);
2 mjames 999
 
9 mjames 1000
  if (hi2s->State != HAL_I2S_STATE_READY)
1001
  {
1002
    __HAL_UNLOCK(hi2s);
1003
    return HAL_BUSY;
1004
  }
2 mjames 1005
 
9 mjames 1006
  /* Set state and reset error code */
1007
  hi2s->State = HAL_I2S_STATE_BUSY_TX;
1008
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1009
  hi2s->pTxBuffPtr = pData;
2 mjames 1010
 
9 mjames 1011
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 1012
 
9 mjames 1013
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1014
  {
1015
    hi2s->TxXferSize = (Size << 1U);
1016
    hi2s->TxXferCount = (Size << 1U);
2 mjames 1017
  }
1018
  else
1019
  {
9 mjames 1020
    hi2s->TxXferSize = Size;
1021
    hi2s->TxXferCount = Size;
2 mjames 1022
  }
9 mjames 1023
 
1024
  /* Enable TXE and ERR interrupt */
1025
  __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1026
 
1027
  /* Check if the I2S is already enabled */
1028
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1029
  {
1030
    /* Enable I2S peripheral */
1031
    __HAL_I2S_ENABLE(hi2s);
1032
  }
1033
 
1034
  __HAL_UNLOCK(hi2s);
1035
  return HAL_OK;
2 mjames 1036
}
1037
 
1038
/**
9 mjames 1039
  * @brief  Receive an amount of data in non-blocking mode with Interrupt
1040
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1041
  *         the configuration information for I2S module
9 mjames 1042
  * @param  pData a 16-bit pointer to the Receive data buffer.
1043
  * @param  Size number of data sample to be sent:
1044
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1045
  *         configuration phase, the Size parameter means the number of 16-bit data length
1046
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1047
  *         the Size parameter means the number of 16-bit data length.
1048
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1049
  *         between Master and Slave(example: audio streaming).
1050
  * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
2 mjames 1051
  * between Master and Slave otherwise the I2S interrupt should be optimized.
1052
  * @retval HAL status
1053
  */
1054
HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1055
{
9 mjames 1056
  uint32_t tmpreg_cfgr;
2 mjames 1057
 
9 mjames 1058
  if ((pData == NULL) || (Size == 0U))
2 mjames 1059
  {
9 mjames 1060
    return  HAL_ERROR;
1061
  }
2 mjames 1062
 
9 mjames 1063
  /* Process Locked */
1064
  __HAL_LOCK(hi2s);
2 mjames 1065
 
9 mjames 1066
  if (hi2s->State != HAL_I2S_STATE_READY)
1067
  {
1068
    __HAL_UNLOCK(hi2s);
1069
    return HAL_BUSY;
1070
  }
2 mjames 1071
 
9 mjames 1072
  /* Set state and reset error code */
1073
  hi2s->State = HAL_I2S_STATE_BUSY_RX;
1074
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1075
  hi2s->pRxBuffPtr = pData;
2 mjames 1076
 
9 mjames 1077
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 1078
 
9 mjames 1079
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1080
  {
1081
    hi2s->RxXferSize = (Size << 1U);
1082
    hi2s->RxXferCount = (Size << 1U);
2 mjames 1083
  }
1084
  else
1085
  {
9 mjames 1086
    hi2s->RxXferSize = Size;
1087
    hi2s->RxXferCount = Size;
2 mjames 1088
  }
9 mjames 1089
 
1090
  /* Enable RXNE and ERR interrupt */
1091
  __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1092
 
1093
  /* Check if the I2S is already enabled */
1094
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1095
  {
1096
    /* Enable I2S peripheral */
1097
    __HAL_I2S_ENABLE(hi2s);
1098
  }
1099
 
1100
  __HAL_UNLOCK(hi2s);
1101
  return HAL_OK;
2 mjames 1102
}
1103
 
1104
/**
9 mjames 1105
  * @brief  Transmit an amount of data in non-blocking mode with DMA
1106
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1107
  *         the configuration information for I2S module
9 mjames 1108
  * @param  pData a 16-bit pointer to the Transmit data buffer.
1109
  * @param  Size number of data sample to be sent:
1110
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1111
  *         configuration phase, the Size parameter means the number of 16-bit data length
1112
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1113
  *         the Size parameter means the number of 16-bit data length.
1114
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1115
  *         between Master and Slave(example: audio streaming).
2 mjames 1116
  * @retval HAL status
1117
  */
1118
HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1119
{
9 mjames 1120
  uint32_t tmpreg_cfgr;
2 mjames 1121
 
9 mjames 1122
  if ((pData == NULL) || (Size == 0U))
2 mjames 1123
  {
1124
    return  HAL_ERROR;
1125
  }
1126
 
9 mjames 1127
  /* Process Locked */
1128
  __HAL_LOCK(hi2s);
1129
 
1130
  if (hi2s->State != HAL_I2S_STATE_READY)
2 mjames 1131
  {
9 mjames 1132
    __HAL_UNLOCK(hi2s);
1133
    return HAL_BUSY;
1134
  }
2 mjames 1135
 
9 mjames 1136
  /* Set state and reset error code */
1137
  hi2s->State = HAL_I2S_STATE_BUSY_TX;
1138
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1139
  hi2s->pTxBuffPtr = pData;
2 mjames 1140
 
9 mjames 1141
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 1142
 
9 mjames 1143
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1144
  {
1145
    hi2s->TxXferSize = (Size << 1U);
1146
    hi2s->TxXferCount = (Size << 1U);
1147
  }
1148
  else
1149
  {
1150
    hi2s->TxXferSize = Size;
1151
    hi2s->TxXferCount = Size;
1152
  }
2 mjames 1153
 
9 mjames 1154
  /* Set the I2S Tx DMA Half transfer complete callback */
1155
  hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
2 mjames 1156
 
9 mjames 1157
  /* Set the I2S Tx DMA transfer complete callback */
1158
  hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
2 mjames 1159
 
9 mjames 1160
  /* Set the DMA error callback */
1161
  hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
2 mjames 1162
 
9 mjames 1163
  /* Enable the Tx DMA Stream/Channel */
1164
  if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx,
1165
                                 (uint32_t)hi2s->pTxBuffPtr,
1166
                                 (uint32_t)&hi2s->Instance->DR,
1167
                                 hi2s->TxXferSize))
1168
  {
1169
    /* Update SPI error code */
1170
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1171
    hi2s->State = HAL_I2S_STATE_READY;
2 mjames 1172
 
1173
    __HAL_UNLOCK(hi2s);
9 mjames 1174
    return HAL_ERROR;
1175
  }
2 mjames 1176
 
9 mjames 1177
  /* Check if the I2S is already enabled */
1178
  if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1179
  {
1180
    /* Enable I2S peripheral */
1181
    __HAL_I2S_ENABLE(hi2s);
2 mjames 1182
  }
9 mjames 1183
 
1184
  /* Check if the I2S Tx request is already enabled */
1185
  if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
2 mjames 1186
  {
9 mjames 1187
    /* Enable Tx DMA Request */
1188
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
2 mjames 1189
  }
9 mjames 1190
 
1191
  __HAL_UNLOCK(hi2s);
1192
  return HAL_OK;
2 mjames 1193
}
1194
 
1195
/**
9 mjames 1196
  * @brief  Receive an amount of data in non-blocking mode with DMA
1197
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1198
  *         the configuration information for I2S module
9 mjames 1199
  * @param  pData a 16-bit pointer to the Receive data buffer.
1200
  * @param  Size number of data sample to be sent:
1201
  * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1202
  *         configuration phase, the Size parameter means the number of 16-bit data length
1203
  *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1204
  *         the Size parameter means the number of 16-bit data length.
1205
  * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1206
  *         between Master and Slave(example: audio streaming).
2 mjames 1207
  * @retval HAL status
1208
  */
1209
HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1210
{
9 mjames 1211
  uint32_t tmpreg_cfgr;
2 mjames 1212
 
9 mjames 1213
  if ((pData == NULL) || (Size == 0U))
2 mjames 1214
  {
1215
    return  HAL_ERROR;
1216
  }
1217
 
9 mjames 1218
  /* Process Locked */
1219
  __HAL_LOCK(hi2s);
1220
 
1221
  if (hi2s->State != HAL_I2S_STATE_READY)
2 mjames 1222
  {
9 mjames 1223
    __HAL_UNLOCK(hi2s);
1224
    return HAL_BUSY;
1225
  }
2 mjames 1226
 
9 mjames 1227
  /* Set state and reset error code */
1228
  hi2s->State = HAL_I2S_STATE_BUSY_RX;
1229
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1230
  hi2s->pRxBuffPtr = pData;
2 mjames 1231
 
9 mjames 1232
  tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
2 mjames 1233
 
9 mjames 1234
  if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1235
  {
1236
    hi2s->RxXferSize = (Size << 1U);
1237
    hi2s->RxXferCount = (Size << 1U);
1238
  }
1239
  else
1240
  {
1241
    hi2s->RxXferSize = Size;
1242
    hi2s->RxXferCount = Size;
1243
  }
2 mjames 1244
 
9 mjames 1245
  /* Set the I2S Rx DMA Half transfer complete callback */
1246
  hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
2 mjames 1247
 
9 mjames 1248
  /* Set the I2S Rx DMA transfer complete callback */
1249
  hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
2 mjames 1250
 
9 mjames 1251
  /* Set the DMA error callback */
1252
  hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
2 mjames 1253
 
9 mjames 1254
  /* Check if Master Receiver mode is selected */
1255
  if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1256
  {
1257
    /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
1258
    access to the SPI_SR register. */
1259
    __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1260
  }
2 mjames 1261
 
9 mjames 1262
  /* Enable the Rx DMA Stream/Channel */
1263
  if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr,
1264
                                 hi2s->RxXferSize))
1265
  {
1266
    /* Update SPI error code */
1267
    SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1268
    hi2s->State = HAL_I2S_STATE_READY;
2 mjames 1269
 
1270
    __HAL_UNLOCK(hi2s);
9 mjames 1271
    return HAL_ERROR;
1272
  }
2 mjames 1273
 
9 mjames 1274
  /* Check if the I2S is already enabled */
1275
  if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1276
  {
1277
    /* Enable I2S peripheral */
1278
    __HAL_I2S_ENABLE(hi2s);
2 mjames 1279
  }
9 mjames 1280
 
1281
  /* Check if the I2S Rx request is already enabled */
1282
  if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
2 mjames 1283
  {
9 mjames 1284
    /* Enable Rx DMA Request */
1285
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
2 mjames 1286
  }
9 mjames 1287
 
1288
  __HAL_UNLOCK(hi2s);
1289
  return HAL_OK;
2 mjames 1290
}
1291
 
1292
/**
9 mjames 1293
  * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1294
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1295
  *         the configuration information for I2S module
1296
  * @retval HAL status
1297
  */
1298
HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1299
{
1300
  /* Process Locked */
1301
  __HAL_LOCK(hi2s);
1302
 
9 mjames 1303
  if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
2 mjames 1304
  {
1305
    /* Disable the I2S DMA Tx request */
9 mjames 1306
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
2 mjames 1307
  }
9 mjames 1308
  else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
2 mjames 1309
  {
1310
    /* Disable the I2S DMA Rx request */
9 mjames 1311
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
2 mjames 1312
  }
9 mjames 1313
  else
1314
  {
1315
    /* nothing to do */
1316
  }
2 mjames 1317
 
1318
  /* Process Unlocked */
1319
  __HAL_UNLOCK(hi2s);
1320
 
1321
  return HAL_OK;
1322
}
1323
 
1324
/**
9 mjames 1325
  * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1326
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1327
  *         the configuration information for I2S module
1328
  * @retval HAL status
1329
  */
1330
HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1331
{
1332
  /* Process Locked */
1333
  __HAL_LOCK(hi2s);
1334
 
9 mjames 1335
  if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
2 mjames 1336
  {
1337
    /* Enable the I2S DMA Tx request */
9 mjames 1338
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
2 mjames 1339
  }
9 mjames 1340
  else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
2 mjames 1341
  {
1342
    /* Enable the I2S DMA Rx request */
9 mjames 1343
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
2 mjames 1344
  }
9 mjames 1345
  else
1346
  {
1347
    /* nothing to do */
1348
  }
1349
 
2 mjames 1350
  /* If the I2S peripheral is still not enabled, enable it */
9 mjames 1351
  if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
2 mjames 1352
  {
1353
    /* Enable I2S peripheral */
1354
    __HAL_I2S_ENABLE(hi2s);
1355
  }
1356
 
1357
  /* Process Unlocked */
1358
  __HAL_UNLOCK(hi2s);
1359
 
1360
  return HAL_OK;
1361
}
1362
 
1363
/**
9 mjames 1364
  * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1365
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1366
  *         the configuration information for I2S module
1367
  * @retval HAL status
1368
  */
1369
HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1370
{
9 mjames 1371
  HAL_StatusTypeDef errorcode = HAL_OK;
1372
  /* The Lock is not implemented on this API to allow the user application
1373
     to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1374
     when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1375
     and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1376
     */
2 mjames 1377
 
9 mjames 1378
  if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
2 mjames 1379
  {
9 mjames 1380
    /* Abort the I2S DMA tx Stream/Channel */
1381
    if (hi2s->hdmatx != NULL)
1382
    {
1383
      /* Disable the I2S DMA tx Stream/Channel */
1384
      if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1385
      {
1386
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1387
        errorcode = HAL_ERROR;
1388
      }
1389
    }
2 mjames 1390
 
9 mjames 1391
    /* Wait until TXE flag is set */
1392
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, I2S_TIMEOUT_FLAG) != HAL_OK)
1393
    {
1394
      /* Set the error code */
1395
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1396
      hi2s->State = HAL_I2S_STATE_READY;
1397
      errorcode   = HAL_ERROR;
1398
    }
1399
 
1400
    /* Wait until BSY flag is Reset */
1401
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, I2S_TIMEOUT_FLAG) != HAL_OK)
1402
    {
1403
      /* Set the error code */
1404
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1405
      hi2s->State = HAL_I2S_STATE_READY;
1406
      errorcode   = HAL_ERROR;
1407
    }
1408
 
1409
    /* Disable I2S peripheral */
1410
    __HAL_I2S_DISABLE(hi2s);
1411
 
1412
    /* Clear UDR flag */
1413
    __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1414
 
1415
    /* Disable the I2S Tx DMA requests */
1416
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1417
 
2 mjames 1418
  }
9 mjames 1419
 
1420
  else if ((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX))
2 mjames 1421
  {
9 mjames 1422
    /* Abort the I2S DMA rx Stream/Channel */
1423
    if (hi2s->hdmarx != NULL)
1424
    {
1425
      /* Disable the I2S DMA rx Stream/Channel */
1426
      if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1427
      {
1428
        SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1429
        errorcode = HAL_ERROR;
1430
      }
1431
    }
2 mjames 1432
 
9 mjames 1433
    /* Disable I2S peripheral */
1434
    __HAL_I2S_DISABLE(hi2s);
1435
 
1436
    /* Clear OVR flag */
1437
    __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1438
 
1439
    /* Disable the I2S Rx DMA request */
1440
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1441
 
1442
    if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1443
    {
1444
      /* Set the error code */
1445
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX);
1446
 
1447
      /* Set the I2S State ready */
1448
      hi2s->State = HAL_I2S_STATE_READY;
1449
      errorcode = HAL_ERROR;
1450
    }
1451
    else
1452
    {
1453
      /* Read DR to Flush RX Data */
1454
      READ_REG((hi2s->Instance)->DR);
1455
    }
2 mjames 1456
  }
1457
 
1458
  hi2s->State = HAL_I2S_STATE_READY;
1459
 
9 mjames 1460
  return errorcode;
2 mjames 1461
}
1462
 
1463
/**
1464
  * @brief  This function handles I2S interrupt request.
9 mjames 1465
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1466
  *         the configuration information for I2S module
1467
  * @retval None
1468
  */
1469
void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1470
{
9 mjames 1471
  uint32_t itsource = hi2s->Instance->CR2;
1472
  uint32_t itflag   = hi2s->Instance->SR;
1473
 
1474
  /* I2S in mode Receiver ------------------------------------------------*/
1475
  if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) &&
1476
      (I2S_CHECK_FLAG(itflag, I2S_FLAG_RXNE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_RXNE) != RESET))
1477
  {
1478
    I2S_Receive_IT(hi2s);
1479
    return;
1480
  }
1481
 
1482
  /* I2S in mode Tramitter -----------------------------------------------*/
1483
  if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_TXE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_TXE) != RESET))
1484
  {
1485
    I2S_Transmit_IT(hi2s);
1486
    return;
1487
  }
1488
 
1489
  /* I2S interrupt error -------------------------------------------------*/
1490
  if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1491
  {
1492
    /* I2S Overrun error interrupt occurred ---------------------------------*/
1493
    if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1494
    {
1495
      /* Disable RXNE and ERR interrupt */
1496
      __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1497
 
1498
      /* Set the error code and execute error callback*/
1499
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1500
    }
1501
 
1502
    /* I2S Underrun error interrupt occurred --------------------------------*/
1503
    if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1504
    {
1505
      /* Disable TXE and ERR interrupt */
1506
      __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1507
 
1508
      /* Set the error code and execute error callback*/
1509
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1510
    }
1511
 
1512
    /* Set the I2S State ready */
1513
    hi2s->State = HAL_I2S_STATE_READY;
1514
 
1515
    /* Call user error callback */
1516
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1517
    hi2s->ErrorCallback(hi2s);
1518
#else
1519
    HAL_I2S_ErrorCallback(hi2s);
1520
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1521
  }
2 mjames 1522
}
1523
 
1524
/**
9 mjames 1525
  * @brief  Tx Transfer Half completed callbacks
1526
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1527
  *         the configuration information for I2S module
1528
  * @retval None
1529
  */
9 mjames 1530
__weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2 mjames 1531
{
1532
  /* Prevent unused argument(s) compilation warning */
1533
  UNUSED(hi2s);
9 mjames 1534
 
2 mjames 1535
  /* NOTE : This function Should not be modified, when the callback is needed,
1536
            the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1537
   */
1538
}
1539
 
1540
/**
9 mjames 1541
  * @brief  Tx Transfer completed callbacks
1542
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1543
  *         the configuration information for I2S module
1544
  * @retval None
1545
  */
9 mjames 1546
__weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
2 mjames 1547
{
1548
  /* Prevent unused argument(s) compilation warning */
1549
  UNUSED(hi2s);
9 mjames 1550
 
2 mjames 1551
  /* NOTE : This function Should not be modified, when the callback is needed,
1552
            the HAL_I2S_TxCpltCallback could be implemented in the user file
1553
   */
1554
}
1555
 
1556
/**
9 mjames 1557
  * @brief  Rx Transfer half completed callbacks
1558
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1559
  *         the configuration information for I2S module
1560
  * @retval None
1561
  */
1562
__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1563
{
1564
  /* Prevent unused argument(s) compilation warning */
1565
  UNUSED(hi2s);
9 mjames 1566
 
2 mjames 1567
  /* NOTE : This function Should not be modified, when the callback is needed,
1568
            the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1569
   */
1570
}
1571
 
1572
/**
9 mjames 1573
  * @brief  Rx Transfer completed callbacks
1574
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1575
  *         the configuration information for I2S module
1576
  * @retval None
1577
  */
1578
__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1579
{
1580
  /* Prevent unused argument(s) compilation warning */
1581
  UNUSED(hi2s);
9 mjames 1582
 
2 mjames 1583
  /* NOTE : This function Should not be modified, when the callback is needed,
1584
            the HAL_I2S_RxCpltCallback could be implemented in the user file
1585
   */
1586
}
1587
 
1588
/**
9 mjames 1589
  * @brief  I2S error callbacks
1590
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1591
  *         the configuration information for I2S module
1592
  * @retval None
1593
  */
9 mjames 1594
__weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
2 mjames 1595
{
1596
  /* Prevent unused argument(s) compilation warning */
1597
  UNUSED(hi2s);
9 mjames 1598
 
2 mjames 1599
  /* NOTE : This function Should not be modified, when the callback is needed,
1600
            the HAL_I2S_ErrorCallback could be implemented in the user file
1601
   */
1602
}
1603
 
1604
/**
1605
  * @}
1606
  */
1607
 
9 mjames 1608
/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1609
  *  @brief   Peripheral State functions
2 mjames 1610
  *
1611
@verbatim
1612
 ===============================================================================
1613
                      ##### Peripheral State and Errors functions #####
1614
 ===============================================================================
1615
    [..]
1616
    This subsection permits to get in run-time the status of the peripheral
1617
    and the data flow.
1618
 
1619
@endverbatim
1620
  * @{
1621
  */
1622
 
1623
/**
1624
  * @brief  Return the I2S state
9 mjames 1625
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1626
  *         the configuration information for I2S module
1627
  * @retval HAL state
1628
  */
1629
HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1630
{
1631
  return hi2s->State;
1632
}
1633
 
1634
/**
1635
  * @brief  Return the I2S error code
9 mjames 1636
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1637
  *         the configuration information for I2S module
1638
  * @retval I2S Error Code
1639
  */
1640
uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1641
{
1642
  return hi2s->ErrorCode;
1643
}
1644
/**
1645
  * @}
1646
  */
1647
 
1648
/**
1649
  * @}
1650
  */
1651
 
1652
/** @addtogroup I2S_Private_Functions I2S Private Functions
1653
  * @{
1654
  */
1655
/**
9 mjames 1656
  * @brief  DMA I2S transmit process complete callback
1657
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2 mjames 1658
  *                the configuration information for the specified DMA module.
1659
  * @retval None
1660
  */
1661
static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1662
{
9 mjames 1663
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
2 mjames 1664
 
9 mjames 1665
  /* if DMA is configured in DMA_NORMAL Mode */
1666
  if (hdma->Init.Mode == DMA_NORMAL)
2 mjames 1667
  {
1668
    /* Disable Tx DMA Request */
9 mjames 1669
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
2 mjames 1670
 
1671
    hi2s->TxXferCount = 0U;
9 mjames 1672
    hi2s->State = HAL_I2S_STATE_READY;
2 mjames 1673
  }
9 mjames 1674
  /* Call user Tx complete callback */
1675
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1676
  hi2s->TxCpltCallback(hi2s);
1677
#else
2 mjames 1678
  HAL_I2S_TxCpltCallback(hi2s);
9 mjames 1679
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1680
}
9 mjames 1681
 
2 mjames 1682
/**
9 mjames 1683
  * @brief  DMA I2S transmit process half complete callback
1684
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2 mjames 1685
  *                the configuration information for the specified DMA module.
1686
  * @retval None
1687
  */
1688
static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1689
{
9 mjames 1690
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
2 mjames 1691
 
9 mjames 1692
  /* Call user Tx half complete callback */
1693
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1694
  hi2s->TxHalfCpltCallback(hi2s);
1695
#else
2 mjames 1696
  HAL_I2S_TxHalfCpltCallback(hi2s);
9 mjames 1697
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1698
}
1699
 
1700
/**
9 mjames 1701
  * @brief  DMA I2S receive process complete callback
1702
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2 mjames 1703
  *                the configuration information for the specified DMA module.
1704
  * @retval None
1705
  */
1706
static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1707
{
9 mjames 1708
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
2 mjames 1709
 
9 mjames 1710
  /* if DMA is configured in DMA_NORMAL Mode */
1711
  if (hdma->Init.Mode == DMA_NORMAL)
2 mjames 1712
  {
1713
    /* Disable Rx DMA Request */
9 mjames 1714
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
2 mjames 1715
    hi2s->RxXferCount = 0U;
9 mjames 1716
    hi2s->State = HAL_I2S_STATE_READY;
2 mjames 1717
  }
9 mjames 1718
  /* Call user Rx complete callback */
1719
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1720
  hi2s->RxCpltCallback(hi2s);
1721
#else
2 mjames 1722
  HAL_I2S_RxCpltCallback(hi2s);
9 mjames 1723
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1724
}
1725
 
1726
/**
9 mjames 1727
  * @brief  DMA I2S receive process half complete callback
1728
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2 mjames 1729
  *                the configuration information for the specified DMA module.
1730
  * @retval None
1731
  */
1732
static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1733
{
9 mjames 1734
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
2 mjames 1735
 
9 mjames 1736
  /* Call user Rx half complete callback */
1737
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1738
  hi2s->RxHalfCpltCallback(hi2s);
1739
#else
2 mjames 1740
  HAL_I2S_RxHalfCpltCallback(hi2s);
9 mjames 1741
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1742
}
1743
 
1744
/**
9 mjames 1745
  * @brief  DMA I2S communication error callback
1746
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2 mjames 1747
  *                the configuration information for the specified DMA module.
1748
  * @retval None
1749
  */
1750
static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1751
{
9 mjames 1752
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
2 mjames 1753
 
1754
  /* Disable Rx and Tx DMA Request */
9 mjames 1755
  CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
2 mjames 1756
  hi2s->TxXferCount = 0U;
1757
  hi2s->RxXferCount = 0U;
1758
 
9 mjames 1759
  hi2s->State = HAL_I2S_STATE_READY;
2 mjames 1760
 
9 mjames 1761
  /* Set the error code and execute error callback*/
1762
  SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1763
  /* Call user error callback */
1764
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1765
  hi2s->ErrorCallback(hi2s);
1766
#else
2 mjames 1767
  HAL_I2S_ErrorCallback(hi2s);
9 mjames 1768
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1769
}
1770
 
1771
/**
9 mjames 1772
  * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1773
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1774
  *         the configuration information for I2S module
9 mjames 1775
  * @retval None
2 mjames 1776
  */
1777
static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1778
{
1779
  /* Transmit data */
9 mjames 1780
  hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
1781
  hi2s->pTxBuffPtr++;
2 mjames 1782
  hi2s->TxXferCount--;
1783
 
9 mjames 1784
  if (hi2s->TxXferCount == 0U)
2 mjames 1785
  {
1786
    /* Disable TXE and ERR interrupt */
1787
    __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1788
 
1789
    hi2s->State = HAL_I2S_STATE_READY;
9 mjames 1790
    /* Call user Tx complete callback */
1791
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1792
    hi2s->TxCpltCallback(hi2s);
1793
#else
2 mjames 1794
    HAL_I2S_TxCpltCallback(hi2s);
9 mjames 1795
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1796
  }
1797
}
1798
 
1799
/**
9 mjames 1800
  * @brief  Receive an amount of data in non-blocking mode with Interrupt
1801
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1802
  *         the configuration information for I2S module
9 mjames 1803
  * @retval None
2 mjames 1804
  */
1805
static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1806
{
1807
  /* Receive data */
9 mjames 1808
  (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
1809
  hi2s->pRxBuffPtr++;
2 mjames 1810
  hi2s->RxXferCount--;
1811
 
9 mjames 1812
  if (hi2s->RxXferCount == 0U)
2 mjames 1813
  {
1814
    /* Disable RXNE and ERR interrupt */
1815
    __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1816
 
1817
    hi2s->State = HAL_I2S_STATE_READY;
9 mjames 1818
    /* Call user Rx complete callback */
1819
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1820
    hi2s->RxCpltCallback(hi2s);
1821
#else
2 mjames 1822
    HAL_I2S_RxCpltCallback(hi2s);
9 mjames 1823
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2 mjames 1824
  }
1825
}
1826
 
1827
/**
9 mjames 1828
  * @brief  This function handles I2S Communication Timeout.
1829
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2 mjames 1830
  *         the configuration information for I2S module
9 mjames 1831
  * @param  Flag Flag checked
1832
  * @param  State Value of the flag expected
1833
  * @param  Timeout Duration of the timeout
1834
  * @retval HAL status
2 mjames 1835
  */
9 mjames 1836
static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
1837
                                                       uint32_t Timeout)
2 mjames 1838
{
9 mjames 1839
  uint32_t tickstart;
2 mjames 1840
 
9 mjames 1841
  /* Get tick */
1842
  tickstart = HAL_GetTick();
2 mjames 1843
 
9 mjames 1844
  /* Wait until flag is set to status*/
1845
  while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
2 mjames 1846
  {
9 mjames 1847
    if (Timeout != HAL_MAX_DELAY)
2 mjames 1848
    {
9 mjames 1849
      if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
2 mjames 1850
      {
1851
        /* Set the I2S State ready */
1852
        hi2s->State = HAL_I2S_STATE_READY;
1853
 
1854
        /* Process Unlocked */
1855
        __HAL_UNLOCK(hi2s);
1856
 
1857
        return HAL_TIMEOUT;
1858
      }
1859
    }
1860
  }
1861
  return HAL_OK;
1862
}
1863
 
1864
/**
1865
  * @}
1866
  */
1867
 
1868
/**
1869
  * @}
1870
  */
1871
 
1872
/**
1873
  * @}
1874
  */
9 mjames 1875
#endif /* SPI_I2S_SUPPORT */
2 mjames 1876
 
9 mjames 1877
#endif /* HAL_I2S_MODULE_ENABLED */
1878
 
2 mjames 1879
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/