Subversion Repositories DashDisplay

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 mjames 5
  * @version V1.0.4
6
  * @date    29-April-2016
2 mjames 7
  * @brief   I2S HAL module driver.
8
  *          This file provides firmware functions to manage the following
9
  *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
10
  *           + Initialization and de-initialization functions
11
  *           + IO operation functions
12
  *           + Peripheral State and Errors functions
13
  @verbatim
14
 ===============================================================================
15
                  ##### How to use this driver #####
16
 ===============================================================================
17
 [..]
18
    The I2S HAL driver can be used as follow:
19
 
20
    (#) Declare a I2S_HandleTypeDef handle structure.
21
    (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
22
        (##) Enable the SPIx interface clock.                      
23
        (##) I2S pins configuration:
24
            (+++) Enable the clock for the I2S GPIOs.
25
            (+++) Configure these I2S pins as alternate function.
26
        (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
27
             and HAL_I2S_Receive_IT() APIs).
28
            (+++) Configure the I2Sx interrupt priority.
29
            (+++) Enable the NVIC I2S IRQ handle.
30
        (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
31
             and HAL_I2S_Receive_DMA() APIs:
32
            (+++) Declare a DMA handle structure for the Tx/Rx Channel.
33
            (+++) Enable the DMAx interface clock.
34
            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.                
35
            (+++) Configure the DMA Tx/Rx Channel.
36
            (+++) Associate the initilalized DMA handle to the I2S DMA Tx/Rx handle.
37
            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
38
                  DMA Tx/Rx Channel.
39
 
40
   (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
41
       using HAL_I2S_Init() function.
42
 
43
   -@- The specific I2S interrupts (Transmission complete interrupt,
44
       RXNE interrupt and Error Interrupts) will be managed using the macros
45
       __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
46
   -@- The I2SxCLK source is the system clock (provided by the HSI, the HSE or the PLL, and sourcing the AHB clock).
47
       For connectivity line devices, the I2SxCLK source can be either SYSCLK or the PLL3 VCO (2 x PLL3CLK) clock
48
       in order to achieve the maximum accuracy.
49
   -@- Make sure that either:
50
       (+@) External clock source is configured after setting correctly
51
            the define constant HSE_VALUE in the stm32f1xx_hal_conf.h file.
52
 
53
    (#) Three mode of operations are available within this driver :    
54
 
55
   *** Polling mode IO operation ***
56
   =================================
57
   [..]    
58
     (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
59
     (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
60
 
61
   *** Interrupt mode IO operation ***
62
   ===================================
63
   [..]    
64
     (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
65
     (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
66
         add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
67
     (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
68
         add his own code by customization of function pointer HAL_I2S_TxCpltCallback
69
     (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
70
     (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
71
         add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
72
     (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
73
         add his own code by customization of function pointer HAL_I2S_RxCpltCallback
74
     (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
75
         add his own code by customization of function pointer HAL_I2S_ErrorCallback
76
 
77
   *** DMA mode IO operation ***
78
   ==============================
79
   [..]
80
     (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
81
     (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
82
         add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
83
     (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
84
         add his own code by customization of function pointer HAL_I2S_TxCpltCallback
85
     (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
86
     (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
87
         add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
88
     (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
89
         add his own code by customization of function pointer HAL_I2S_RxCpltCallback
90
     (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
91
         add his own code by customization of function pointer HAL_I2S_ErrorCallback
92
     (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
93
     (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
94
     (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
95
 
96
   *** I2S HAL driver macros list ***
97
   =============================================
98
   [..]
99
     Below the list of most used macros in USART HAL driver.
100
 
101
      (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
102
      (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
103
      (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
104
      (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
105
      (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
106
 
107
    [..]
108
      (@) You can refer to the I2S HAL driver header file for more useful macros
109
 
110
 
111
     *** I2C Workarounds linked to Silicon Limitation ***
112
     ====================================================
113
     [..]
114
       (@) Only the 16-bit mode with no data extension can be used when the I2S
115
           is in Master and used the PCM long synchronization mode.
116
 
117
 
118
  @endverbatim
119
  ******************************************************************************
120
  * @attention
121
  *
5 mjames 122
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
2 mjames 123
  *
124
  * Redistribution and use in source and binary forms, with or without modification,
125
  * are permitted provided that the following conditions are met:
126
  *   1. Redistributions of source code must retain the above copyright notice,
127
  *      this list of conditions and the following disclaimer.
128
  *   2. Redistributions in binary form must reproduce the above copyright notice,
129
  *      this list of conditions and the following disclaimer in the documentation
130
  *      and/or other materials provided with the distribution.
131
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
132
  *      may be used to endorse or promote products derived from this software
133
  *      without specific prior written permission.
134
  *
135
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
136
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
137
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
138
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
139
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
140
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
141
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
142
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
143
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
  *
146
  ******************************************************************************
147
  */
148
 
149
/* Includes ------------------------------------------------------------------*/
150
#include "stm32f1xx_hal.h"
151
 
152
/** @addtogroup STM32F1xx_HAL_Driver
153
  * @{
154
  */
155
 
156
#ifdef HAL_I2S_MODULE_ENABLED
157
#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
158
 
159
/** @defgroup I2S I2S
160
  * @brief I2S HAL module driver
161
  * @{
162
  */
163
 
164
/* Private typedef -----------------------------------------------------------*/
165
/* Private define ------------------------------------------------------------*/
166
/* Private macro -------------------------------------------------------------*/
167
/* Private variables ---------------------------------------------------------*/
168
/* Private function prototypes -----------------------------------------------*/
169
/** @addtogroup I2S_Private_Functions I2S Private Functions
170
  * @{
171
  */
172
static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
173
static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
174
static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
175
static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
176
static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
177
static void               I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
178
static void               I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
179
static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t Status, uint32_t Timeout);
180
/**
181
  * @}
182
  */
183
 
184
/* Exported functions ---------------------------------------------------------*/
185
/** @defgroup I2S_Exported_Functions I2S Exported Functions
186
  * @{
187
  */
188
 
189
/** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
190
  *  @brief    Initialization and Configuration functions
191
  *
192
@verbatim    
193
 ===============================================================================
194
              ##### Initialization and de-initialization functions #####
195
 ===============================================================================
196
    [..]  This subsection provides a set of functions allowing to initialize and
197
          de-initialiaze the I2Sx peripheral in simplex mode:
198
 
199
      (+) User must Implement HAL_I2S_MspInit() function in which he configures
200
          all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
201
 
202
      (+) Call the function HAL_I2S_Init() to configure the selected device with
203
          the selected configuration:
204
        (++) Mode
205
        (++) Standard
206
        (++) Data Format
207
        (++) MCLK Output
208
        (++) Audio frequency
209
        (++) Polarity
210
 
211
     (+) Call the function HAL_I2S_DeInit() to restore the default configuration
212
         of the selected I2Sx periperal.
213
  @endverbatim
214
  * @{
215
  */
216
 
217
/**
218
  * @brief Initializes the I2S according to the specified parameters
219
  *         in the I2S_InitTypeDef and create the associated handle.
220
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
221
  *         the configuration information for I2S module
222
  * @retval HAL status
223
  */
224
HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
225
{
226
  uint32_t i2sdiv = 2, i2sodd = 0, packetlength = 1;
227
  uint32_t tmp = 0, i2sclk = 0;
228
 
229
  /* Check the I2S handle allocation */
230
  if(hi2s == NULL)
231
  {
232
    return HAL_ERROR;
233
  }
234
 
235
  /* Check the I2S parameters */
236
  assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
237
  assert_param(IS_I2S_MODE(hi2s->Init.Mode));
238
  assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
239
  assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
240
  assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
241
  assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
242
  assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));  
243
 
244
  if(hi2s->State == HAL_I2S_STATE_RESET)
245
  {
246
    /* Allocate lock resource and initialize it */
247
    hi2s->Lock = HAL_UNLOCKED;
248
 
249
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
250
    HAL_I2S_MspInit(hi2s);
251
  }
252
 
253
  hi2s->State = HAL_I2S_STATE_BUSY;
254
 
255
  /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
256
  if(hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT)
257
  {
258
    i2sodd = (uint32_t)0;
259
    i2sdiv = (uint32_t)2;  
260
  }
261
  /* If the requested audio frequency is not the default, compute the prescaler */
262
  else
263
  {
264
    /* Check the frame length (For the Prescaler computing) *******************/
265
    if(hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
266
    {
267
      /* Packet length is 16 bits */
268
      packetlength = 1;
269
    }
270
    else
271
    {
272
      /* Packet length is 32 bits */
273
      packetlength = 2;
274
    }
275
 
276
    if(hi2s->Instance == SPI2)
277
    {
278
      /* Get the source clock value: based on SPI2 Instance */
279
      i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S2);
280
    }
281
    else if(hi2s->Instance == SPI3)
282
    {
283
      /* Get the source clock value: based on SPI3 Instance */
284
      i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S3);
285
    }
286
    else
287
    {
288
      /* Get the source clock value: based on System Clock value */
289
      i2sclk = HAL_RCC_GetSysClockFreq();  
290
    }
291
    if(i2sclk == 0)
292
    {
293
      return HAL_ERROR;
294
    }
295
 
296
    /* Compute the Real divider depending on the MCLK output state, with a floating point */
297
    if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
298
    {
299
      /* MCLK output is enabled */
300
      tmp = (uint32_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5);
301
    }
302
    else
303
    {
304
      /* MCLK output is disabled */
305
      tmp = (uint32_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5);
306
    }
307
 
308
    /* Remove the flatting point */
309
    tmp = tmp / 10;  
310
 
311
    /* Check the parity of the divider */
312
    i2sodd = (uint32_t)(tmp & (uint32_t)1);
313
 
314
    /* Compute the i2sdiv prescaler */
315
    i2sdiv = (uint32_t)((tmp - i2sodd) / 2);
316
 
317
    /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
318
    i2sodd = (uint32_t) (i2sodd << 8);
319
  }
320
 
321
  /* Test if the divider is 1 or 0 or greater than 0xFF */
322
  if((i2sdiv < 2) || (i2sdiv > 0xFF))
323
  {
324
    /* Set the default values */
325
    i2sdiv = 2;
326
    i2sodd = 0;
327
  }
328
 
329
  /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
330
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
331
  /* And configure the I2S with the I2S_InitStruct values                      */
332
  MODIFY_REG( hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN |\
333
                                        SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD |\
334
                                        SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG |\
335
                                        SPI_I2SCFGR_I2SE  | SPI_I2SCFGR_I2SMOD),\
336
                                       (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode |\
337
                                        hi2s->Init.Standard | hi2s->Init.DataFormat |\
338
                                        hi2s->Init.CPOL));
339
 
340
  /* Write to SPIx I2SPR register the computed value */
341
  hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
342
 
343
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
344
  hi2s->State= HAL_I2S_STATE_READY;
345
 
346
  return HAL_OK;
347
}
348
 
349
/**
350
  * @brief DeInitializes the I2S peripheral
351
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
352
  *         the configuration information for I2S module
353
  * @retval HAL status
354
  */
355
HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
356
{
357
  /* Check the I2S handle allocation */
358
  if(hi2s == NULL)
359
  {
360
    return HAL_ERROR;
361
  }
362
 
363
  hi2s->State = HAL_I2S_STATE_BUSY;
364
 
365
  /* Disable the I2S Peripheral Clock */
366
  __HAL_I2S_DISABLE(hi2s);
367
 
368
  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
369
  HAL_I2S_MspDeInit(hi2s);
370
 
371
  hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
372
  hi2s->State = HAL_I2S_STATE_RESET;
373
 
374
  /* Release Lock */
375
  __HAL_UNLOCK(hi2s);
376
 
377
  return HAL_OK;
378
}
379
 
380
/**
381
  * @brief I2S MSP Init
382
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
383
  *         the configuration information for I2S module
384
  * @retval None
385
  */
386
 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
387
{
5 mjames 388
  /* Prevent unused argument(s) compilation warning */
389
  UNUSED(hi2s);
2 mjames 390
  /* NOTE : This function Should not be modified, when the callback is needed,
391
            the HAL_I2S_MspInit could be implemented in the user file
392
   */
393
}
394
 
395
/**
396
  * @brief I2S MSP DeInit
397
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
398
  *         the configuration information for I2S module
399
  * @retval None
400
  */
401
 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
402
{
5 mjames 403
  /* Prevent unused argument(s) compilation warning */
404
  UNUSED(hi2s);
2 mjames 405
  /* NOTE : This function Should not be modified, when the callback is needed,
406
            the HAL_I2S_MspDeInit could be implemented in the user file
407
   */
408
}
409
 
410
/**
411
  * @}
412
  */
413
 
414
/** @defgroup I2S_Exported_Functions_Group2 IO operation functions
415
  *  @brief Data transfers functions
416
  *
417
@verbatim  
418
 ===============================================================================
419
                      ##### IO operation functions #####
420
 ===============================================================================
421
    [..]
422
    This subsection provides a set of functions allowing to manage the I2S data
423
    transfers.
424
 
425
    (#) There are two modes of transfer:
426
       (++) Blocking mode : The communication is performed in the polling mode.
427
            The status of all data processing is returned by the same function
428
            after finishing transfer.  
429
       (++) No-Blocking mode : The communication is performed using Interrupts
430
            or DMA. These functions return the status of the transfer startup.
431
            The end of the data processing will be indicated through the
432
            dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
433
            using DMA mode.
434
 
435
    (#) Blocking mode functions are :
436
        (++) HAL_I2S_Transmit()
437
        (++) HAL_I2S_Receive()
438
 
439
    (#) No-Blocking mode functions with Interrupt are :
440
        (++) HAL_I2S_Transmit_IT()
441
        (++) HAL_I2S_Receive_IT()
442
 
443
    (#) No-Blocking mode functions with DMA are :
444
        (++) HAL_I2S_Transmit_DMA()
445
        (++) HAL_I2S_Receive_DMA()
446
 
447
    (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
448
        (++) HAL_I2S_TxCpltCallback()
449
        (++) HAL_I2S_RxCpltCallback()
450
        (++) HAL_I2S_ErrorCallback()
451
 
452
@endverbatim
453
  * @{
454
  */
455
 
456
/**
457
  * @brief Transmit an amount of data in blocking mode
458
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
459
  *         the configuration information for I2S module
460
  * @param pData: a 16-bit pointer to data buffer.
461
  * @param Size: number of data sample to be sent:
462
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
463
  *       configuration phase, the Size parameter means the number of 16-bit data length
464
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
465
  *       the Size parameter means the number of 16-bit data length.
466
  * @param  Timeout: Timeout duration
467
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
468
  *       between Master and Slave(example: audio streaming).
469
  * @retval HAL status
470
  */
471
HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
472
{
473
  if((pData == NULL ) || (Size == 0))
474
  {
475
    return  HAL_ERROR;                                    
476
  }
477
 
478
  /* Process Locked */
479
  __HAL_LOCK(hi2s);
480
 
481
  if(hi2s->State == HAL_I2S_STATE_READY)
482
  {
483
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
484
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
485
    {
486
      hi2s->TxXferSize = (Size << 1);
487
      hi2s->TxXferCount = (Size << 1);
488
    }
489
    else
490
    {
491
      hi2s->TxXferSize = Size;
492
      hi2s->TxXferCount = Size;
493
    }
494
 
495
    /* Set state and reset error code */
496
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
497
    hi2s->State = HAL_I2S_STATE_BUSY_TX;
498
    hi2s->pTxBuffPtr = pData;
499
 
500
    /* Check if the I2S is already enabled */
501
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
502
    {
503
      /* Enable I2S peripheral */
504
      __HAL_I2S_ENABLE(hi2s);
505
    }
506
 
507
    while(hi2s->TxXferCount > 0)
508
    {
509
      /* Wait until TXE flag is set */
510
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
511
      {
512
        return HAL_TIMEOUT;
513
      }
514
      hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
515
      hi2s->TxXferCount--;  
516
 
517
      /* Check if an underrun occurs */
518
      if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
519
      {
520
        /* Set the I2S State ready */
521
        hi2s->State = HAL_I2S_STATE_READY;
522
 
523
        /* Process Unlocked */
524
        __HAL_UNLOCK(hi2s);
525
 
526
        /* Set the error code and execute error callback*/
527
        hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
528
        return HAL_ERROR;
529
      }
530
    }
531
 
532
    /* Wait until TXE flag is set, to confirm the end of the transcation */
533
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
534
    {
535
      return HAL_TIMEOUT;
536
    }
537
    /* Check if Slave mode is selected */
538
    if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
539
    {
540
      /* Wait until Busy flag is reset */
541
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, SET, Timeout) != HAL_OK)
542
      {
543
        return HAL_TIMEOUT;
544
      }
545
    }
546
    hi2s->State = HAL_I2S_STATE_READY;
547
 
548
    /* Process Unlocked */
549
    __HAL_UNLOCK(hi2s);
550
 
551
    return HAL_OK;
552
  }
553
  else
554
  {
555
    /* Process Unlocked */
556
    __HAL_UNLOCK(hi2s);
557
    return HAL_BUSY;
558
  }
559
}
560
 
561
/**
562
  * @brief Receive an amount of data in blocking mode
563
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
564
  *         the configuration information for I2S module
565
  * @param pData: a 16-bit pointer to data buffer.
566
  * @param Size: number of data sample to be sent:
567
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
568
  *       configuration phase, the Size parameter means the number of 16-bit data length
569
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
570
  *       the Size parameter means the number of 16-bit data length.
571
  * @param Timeout: Timeout duration
572
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
573
  *       between Master and Slave(example: audio streaming).
574
  * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
575
  *       in continouse way and as the I2S is not disabled at the end of the I2S transaction.
576
  * @retval HAL status
577
  */
578
HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
579
{
580
  if((pData == NULL ) || (Size == 0))
581
  {
582
    return  HAL_ERROR;
583
  }
584
 
585
  /* Process Locked */
586
  __HAL_LOCK(hi2s);
587
 
588
  if(hi2s->State == HAL_I2S_STATE_READY)
589
  {
590
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
591
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
592
    {
593
      hi2s->RxXferSize = (Size << 1);
594
      hi2s->RxXferCount = (Size << 1);
595
    }
596
    else
597
    {
598
      hi2s->RxXferSize = Size;
599
      hi2s->RxXferCount = Size;
600
    }
601
 
602
    /* Set state and reset error code */
603
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
604
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
605
    hi2s->pRxBuffPtr = pData;
606
 
607
    /* Check if the I2S is already enabled */
608
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
609
    {
610
      /* Enable I2S peripheral */
611
      __HAL_I2S_ENABLE(hi2s);
612
    }
613
 
614
    /* Receive data */
615
    while(hi2s->RxXferCount > 0)
616
    {
617
      /* Wait until RXNE flag is reset */
618
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
619
      {
620
        return HAL_TIMEOUT;
621
      }
622
 
623
      (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
624
      hi2s->RxXferCount--;
625
 
626
      /* Check if an overrun occurs */
627
      if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
628
      {
629
        /* Set the I2S State ready */
630
        hi2s->State = HAL_I2S_STATE_READY;
631
 
632
        /* Process Unlocked */
633
        __HAL_UNLOCK(hi2s);
634
 
635
        /* Set the error code and execute error callback*/
636
        hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
637
        return HAL_ERROR;
638
      }
639
    }
640
 
641
    hi2s->State = HAL_I2S_STATE_READY;
642
 
643
    /* Process Unlocked */
644
    __HAL_UNLOCK(hi2s);
645
 
646
    return HAL_OK;
647
  }
648
  else
649
  {
650
    /* Process Unlocked */
651
    __HAL_UNLOCK(hi2s);
652
    return HAL_BUSY;
653
  }
654
}
655
 
656
/**
657
  * @brief Transmit an amount of data in non-blocking mode with Interrupt
658
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
659
  *         the configuration information for I2S module
660
  * @param pData: a 16-bit pointer to data buffer.
661
  * @param Size: number of data sample to be sent:
662
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
663
  *       configuration phase, the Size parameter means the number of 16-bit data length
664
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
665
  *       the Size parameter means the number of 16-bit data length.
666
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
667
  *       between Master and Slave(example: audio streaming).
668
  * @retval HAL status
669
  */
670
HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
671
{
672
  if((pData == NULL) || (Size == 0))
673
  {
674
    return  HAL_ERROR;
675
  }
676
 
677
  /* Process Locked */
678
  __HAL_LOCK(hi2s);
679
 
680
  if(hi2s->State == HAL_I2S_STATE_READY)
681
  {
682
    hi2s->pTxBuffPtr = pData;
683
    hi2s->State = HAL_I2S_STATE_BUSY_TX;
684
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
685
 
686
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
687
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
688
    {
689
      hi2s->TxXferSize = (Size << 1);
690
      hi2s->TxXferCount = (Size << 1);
691
    }
692
    else
693
    {
694
      hi2s->TxXferSize = Size;
695
      hi2s->TxXferCount = Size;
696
    }
697
 
698
    /* Enable TXE and ERR interrupt */
699
    __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
700
 
701
    /* Check if the I2S is already enabled */
702
    if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
703
    {
704
      /* Enable I2S peripheral */
705
      __HAL_I2S_ENABLE(hi2s);
706
    }
707
 
708
    /* Process Unlocked */
709
    __HAL_UNLOCK(hi2s);
710
 
711
    return HAL_OK;
712
  }
713
  else
714
  {
715
    /* Process Unlocked */
716
    __HAL_UNLOCK(hi2s);
717
    return HAL_BUSY;
718
  }
719
}
720
 
721
/**
722
  * @brief Receive an amount of data in non-blocking mode with Interrupt
723
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
724
  *         the configuration information for I2S module
725
  * @param pData: a 16-bit pointer to the Receive data buffer.
726
  * @param Size: number of data sample to be sent:
727
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
728
  *       configuration phase, the Size parameter means the number of 16-bit data length
729
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
730
  *       the Size parameter means the number of 16-bit data length.
731
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
732
  *       between Master and Slave(example: audio streaming).
733
  * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
734
  * between Master and Slave otherwise the I2S interrupt should be optimized.
735
  * @retval HAL status
736
  */
737
HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
738
{
739
    if((pData == NULL) || (Size == 0))
740
    {
741
      return  HAL_ERROR;
742
    }
743
 
744
  /* Process Locked */
745
  __HAL_LOCK(hi2s);
746
 
747
  if(hi2s->State == HAL_I2S_STATE_READY)
748
  {
749
    hi2s->pRxBuffPtr = pData;
750
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
751
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
752
 
753
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
754
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
755
    {
756
      hi2s->RxXferSize = (Size << 1);
757
      hi2s->RxXferCount = (Size << 1);
758
    }  
759
    else
760
    {
761
      hi2s->RxXferSize = Size;
762
      hi2s->RxXferCount = Size;
763
    }
764
 
765
    /* Enable RXNE and ERR interrupt */
766
    __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
767
 
768
    /* Check if the I2S is already enabled */
769
    if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
770
    {
771
      /* Enable I2S peripheral */
772
      __HAL_I2S_ENABLE(hi2s);
773
    }
774
 
775
    /* Process Unlocked */
776
    __HAL_UNLOCK(hi2s);
777
 
778
    return HAL_OK;
779
  }
780
  else
781
  {
782
    /* Process Unlocked */
783
    __HAL_UNLOCK(hi2s);
784
    return HAL_BUSY;
785
  }
786
}
787
 
788
/**
789
  * @brief Transmit an amount of data in non-blocking mode with DMA
790
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
791
  *         the configuration information for I2S module
792
  * @param pData: a 16-bit pointer to the Transmit data buffer.
793
  * @param Size: number of data sample to be sent:
794
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
795
  *       configuration phase, the Size parameter means the number of 16-bit data length
796
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
797
  *       the Size parameter means the number of 16-bit data length.
798
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
799
  *       between Master and Slave(example: audio streaming).
800
  * @retval HAL status
801
  */
802
HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
803
{
804
  if((pData == NULL) || (Size == 0))
805
  {
806
    return  HAL_ERROR;
807
  }
808
 
809
  /* Process Locked */
810
  __HAL_LOCK(hi2s);
811
 
812
  if(hi2s->State == HAL_I2S_STATE_READY)
813
  {  
814
    hi2s->pTxBuffPtr = pData;
815
    hi2s->State = HAL_I2S_STATE_BUSY_TX;
816
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
817
 
818
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
819
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
820
    {
821
      hi2s->TxXferSize = (Size << 1);
822
      hi2s->TxXferCount = (Size << 1);
823
    }
824
    else
825
    {
826
      hi2s->TxXferSize = Size;
827
      hi2s->TxXferCount = Size;
828
    }
829
 
830
    /* Set the I2S Tx DMA Half transfert complete callback */
831
    hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
832
 
833
    /* Set the I2S Tx DMA transfert complete callback */
834
    hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
835
 
836
    /* Set the DMA error callback */
837
    hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
838
 
839
    /* Enable the Tx DMA Channel */
840
    HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
841
 
842
    /* Check if the I2S is already enabled */
843
    if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
844
    {
845
      /* Enable I2S peripheral */
846
      __HAL_I2S_ENABLE(hi2s);
847
    }
848
 
849
    /* Check if the I2S Tx request is already enabled */
850
    if(HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
851
    {
852
      /* Enable Tx DMA Request */  
853
      SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
854
    }
855
 
856
    /* Process Unlocked */
857
    __HAL_UNLOCK(hi2s);
858
 
859
    return HAL_OK;
860
  }
861
  else
862
  {
863
    /* Process Unlocked */
864
    __HAL_UNLOCK(hi2s);
865
    return HAL_BUSY;
866
  }
867
}
868
 
869
/**
870
  * @brief Receive an amount of data in non-blocking mode with DMA
871
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
872
  *         the configuration information for I2S module
873
  * @param pData: a 16-bit pointer to the Receive data buffer.
874
  * @param Size: number of data sample to be sent:
875
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
876
  *       configuration phase, the Size parameter means the number of 16-bit data length
877
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
878
  *       the Size parameter means the number of 16-bit data length.
879
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
880
  *       between Master and Slave(example: audio streaming).
881
  * @retval HAL status
882
  */
883
HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
884
{
885
  if((pData == NULL) || (Size == 0))
886
  {
887
    return  HAL_ERROR;
888
  }
889
 
890
  /* Process Locked */
891
  __HAL_LOCK(hi2s);
892
 
893
  if(hi2s->State == HAL_I2S_STATE_READY)
894
  {
895
    hi2s->pRxBuffPtr = pData;
896
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
897
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
898
 
899
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
900
      ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
901
    {
902
      hi2s->RxXferSize = (Size << 1);
903
      hi2s->RxXferCount = (Size << 1);
904
    }
905
    else
906
    {
907
      hi2s->RxXferSize = Size;
908
      hi2s->RxXferCount = Size;
909
    }
910
 
911
 
912
    /* Set the I2S Rx DMA Half transfert complete callback */
913
    hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
914
 
915
    /* Set the I2S Rx DMA transfert complete callback */
916
    hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
917
 
918
    /* Set the DMA error callback */
919
    hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
920
 
921
    /* Check if Master Receiver mode is selected */
922
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
923
    {
924
      /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
925
      access to the SPI_SR register. */
926
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);
927
    }
928
 
929
    /* Enable the Rx DMA Channel */
930
    HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize);
931
 
932
    /* Check if the I2S is already enabled */
933
    if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
934
    {
935
      /* Enable I2S peripheral */
936
      __HAL_I2S_ENABLE(hi2s);
937
    }
938
 
939
     /* Check if the I2S Rx request is already enabled */
940
    if(HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
941
    {
942
      /* Enable Rx DMA Request */  
943
      SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
944
    }
945
 
946
    /* Process Unlocked */
947
    __HAL_UNLOCK(hi2s);
948
 
949
    return HAL_OK;
950
  }
951
  else
952
  {
953
    /* Process Unlocked */
954
    __HAL_UNLOCK(hi2s);
955
    return HAL_BUSY;
956
  }
957
}
958
 
959
/**
960
  * @brief Pauses the audio stream playing from the Media.
961
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
962
  *         the configuration information for I2S module
963
  * @retval HAL status
964
  */
965
HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
966
{
967
  /* Process Locked */
968
  __HAL_LOCK(hi2s);
969
 
970
  if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
971
  {
972
    /* Disable the I2S DMA Tx request */
973
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
974
  }
975
  else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
976
  {
977
    /* Disable the I2S DMA Rx request */
978
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
979
  }
980
 
981
  /* Process Unlocked */
982
  __HAL_UNLOCK(hi2s);
983
 
984
  return HAL_OK;
985
}
986
 
987
/**
988
  * @brief Resumes the audio stream playing from the Media.
989
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
990
  *         the configuration information for I2S module
991
  * @retval HAL status
992
  */
993
HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
994
{
995
  /* Process Locked */
996
  __HAL_LOCK(hi2s);
997
 
998
  if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
999
  {
1000
    /* Enable the I2S DMA Tx request */
1001
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1002
  }
1003
  else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
1004
  {
1005
    /* Enable the I2S DMA Rx request */
1006
    SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1007
  }
1008
 
1009
  /* If the I2S peripheral is still not enabled, enable it */
1010
  if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1011
  {
1012
    /* Enable I2S peripheral */    
1013
    __HAL_I2S_ENABLE(hi2s);
1014
  }
1015
 
1016
  /* Process Unlocked */
1017
  __HAL_UNLOCK(hi2s);
1018
 
1019
  return HAL_OK;
1020
}
1021
 
1022
/**
1023
  * @brief Resumes the audio stream playing from the Media.
1024
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1025
  *         the configuration information for I2S module
1026
  * @retval HAL status
1027
  */
1028
HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1029
{
1030
  /* Process Locked */
1031
  __HAL_LOCK(hi2s);
1032
 
1033
  /* Disable the I2S Tx/Rx DMA requests */
1034
  CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1035
  CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1036
 
1037
  /* Abort the I2S DMA Channel tx */
1038
  if(hi2s->hdmatx != NULL)
1039
  {
1040
    /* Disable the I2S DMA channel */
1041
    __HAL_DMA_DISABLE(hi2s->hdmatx);
1042
    HAL_DMA_Abort(hi2s->hdmatx);
1043
  }
1044
  /* Abort the I2S DMA Channel rx */
1045
  if(hi2s->hdmarx != NULL)
1046
  {
1047
    /* Disable the I2S DMA channel */
1048
    __HAL_DMA_DISABLE(hi2s->hdmarx);
1049
    HAL_DMA_Abort(hi2s->hdmarx);
1050
  }
1051
 
1052
  /* Disable I2S peripheral */
1053
  __HAL_I2S_DISABLE(hi2s);
1054
 
1055
  hi2s->State = HAL_I2S_STATE_READY;
1056
 
1057
  /* Process Unlocked */
1058
  __HAL_UNLOCK(hi2s);
1059
 
1060
  return HAL_OK;
1061
}
1062
 
1063
/**
1064
  * @brief  This function handles I2S interrupt request.
1065
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1066
  *         the configuration information for I2S module
1067
  * @retval None
1068
  */
1069
void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1070
{  
1071
  uint32_t i2ssr = hi2s->Instance->SR;
1072
 
1073
  /* I2S in mode Receiver ------------------------------------------------*/
1074
  if(((i2ssr & I2S_FLAG_OVR) != I2S_FLAG_OVR) &&
1075
     ((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
1076
  {
1077
    I2S_Receive_IT(hi2s);
1078
    return;
1079
  }
1080
 
1081
  /* I2S in mode Tramitter -----------------------------------------------*/
1082
  if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
1083
  {    
1084
    I2S_Transmit_IT(hi2s);
1085
    return;
1086
  }
1087
 
1088
  /* I2S interrupt error -------------------------------------------------*/
1089
  if(__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)
1090
  {
1091
    /* I2S Overrun error interrupt occured ---------------------------------*/
1092
    if((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR)
1093
    {
1094
      /* Disable RXNE and ERR interrupt */
1095
      __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1096
 
1097
      /* Set the error code and execute error callback*/
1098
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1099
    }
1100
 
1101
    /* I2S Underrun error interrupt occured --------------------------------*/
1102
    if((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR)
1103
    {
1104
      /* Disable TXE and ERR interrupt */
1105
      __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1106
 
1107
      /* Set the error code and execute error callback*/
1108
      SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1109
    }
1110
 
1111
    /* Set the I2S State ready */
1112
    hi2s->State = HAL_I2S_STATE_READY;
1113
    /* Call the Error Callback */
1114
    HAL_I2S_ErrorCallback(hi2s);
1115
  }
1116
}
1117
 
1118
/**
1119
  * @brief Tx Transfer Half completed callbacks
1120
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1121
  *         the configuration information for I2S module
1122
  * @retval None
1123
  */
1124
 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1125
{
5 mjames 1126
  /* Prevent unused argument(s) compilation warning */
1127
  UNUSED(hi2s);
2 mjames 1128
  /* NOTE : This function Should not be modified, when the callback is needed,
1129
            the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1130
   */
1131
}
1132
 
1133
/**
1134
  * @brief Tx Transfer completed callbacks
1135
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1136
  *         the configuration information for I2S module
1137
  * @retval None
1138
  */
1139
 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1140
{
5 mjames 1141
  /* Prevent unused argument(s) compilation warning */
1142
  UNUSED(hi2s);
2 mjames 1143
  /* NOTE : This function Should not be modified, when the callback is needed,
1144
            the HAL_I2S_TxCpltCallback could be implemented in the user file
1145
   */
1146
}
1147
 
1148
/**
1149
  * @brief Rx Transfer half completed callbacks
1150
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1151
  *         the configuration information for I2S module
1152
  * @retval None
1153
  */
1154
__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1155
{
5 mjames 1156
  /* Prevent unused argument(s) compilation warning */
1157
  UNUSED(hi2s);
2 mjames 1158
  /* NOTE : This function Should not be modified, when the callback is needed,
1159
            the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1160
   */
1161
}
1162
 
1163
/**
1164
  * @brief Rx Transfer completed callbacks
1165
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1166
  *         the configuration information for I2S module
1167
  * @retval None
1168
  */
1169
__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1170
{
5 mjames 1171
  /* Prevent unused argument(s) compilation warning */
1172
  UNUSED(hi2s);
2 mjames 1173
  /* NOTE : This function Should not be modified, when the callback is needed,
1174
            the HAL_I2S_RxCpltCallback could be implemented in the user file
1175
   */
1176
}
1177
 
1178
/**
1179
  * @brief I2S error callbacks
1180
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1181
  *         the configuration information for I2S module
1182
  * @retval None
1183
  */
1184
 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1185
{
5 mjames 1186
  /* Prevent unused argument(s) compilation warning */
1187
  UNUSED(hi2s);
2 mjames 1188
  /* NOTE : This function Should not be modified, when the callback is needed,
1189
            the HAL_I2S_ErrorCallback could be implemented in the user file
1190
   */
1191
}
1192
 
1193
/**
1194
  * @}
1195
  */
1196
 
1197
/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1198
  *  @brief   Peripheral State functions
1199
  *
1200
@verbatim  
1201
 ===============================================================================
1202
                      ##### Peripheral State and Errors functions #####
1203
 ===============================================================================  
1204
    [..]
1205
    This subsection permits to get in run-time the status of the peripheral
1206
    and the data flow.
1207
 
1208
@endverbatim
1209
  * @{
1210
  */
1211
 
1212
/**
1213
  * @brief  Return the I2S state
1214
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1215
  *         the configuration information for I2S module
1216
  * @retval HAL state
1217
  */
1218
HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1219
{
1220
  return hi2s->State;
1221
}
1222
 
1223
/**
1224
  * @brief  Return the I2S error code
1225
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1226
  *         the configuration information for I2S module
1227
  * @retval I2S Error Code
1228
  */
1229
uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1230
{
1231
  return hi2s->ErrorCode;
1232
}
1233
/**
1234
  * @}
1235
  */
1236
 
1237
/**
1238
  * @}
1239
  */
1240
 
1241
/* Private functions ---------------------------------------------------------*/
1242
/** @addtogroup I2S_Private_Functions I2S Private Functions
1243
  * @{
1244
  */
1245
/**
1246
  * @brief DMA I2S transmit process complete callback
1247
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1248
  *                the configuration information for the specified DMA module.
1249
  * @retval None
1250
  */
1251
static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1252
{
1253
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1254
 
1255
  if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
1256
  {
1257
    /* Disable Tx DMA Request */
1258
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1259
 
1260
    hi2s->TxXferCount = 0;
1261
    hi2s->State = HAL_I2S_STATE_READY;
1262
  }
1263
  HAL_I2S_TxCpltCallback(hi2s);
1264
}
1265
 
1266
/**
1267
  * @brief DMA I2S transmit process half complete callback
1268
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1269
  *                the configuration information for the specified DMA module.
1270
  * @retval None
1271
  */
1272
static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1273
{
1274
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1275
 
1276
  HAL_I2S_TxHalfCpltCallback(hi2s);
1277
}
1278
 
1279
/**
1280
  * @brief DMA I2S receive process complete callback
1281
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1282
  *                the configuration information for the specified DMA module.
1283
  * @retval None
1284
  */
1285
static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1286
{
1287
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1288
 
1289
  if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
1290
  {
1291
    /* Disable Rx DMA Request */
1292
    CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1293
    hi2s->RxXferCount = 0;
1294
    hi2s->State = HAL_I2S_STATE_READY;
1295
  }
1296
  HAL_I2S_RxCpltCallback(hi2s);
1297
}
1298
 
1299
/**
1300
  * @brief DMA I2S receive process half complete callback
1301
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1302
  *                the configuration information for the specified DMA module.
1303
  * @retval None
1304
  */
1305
static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1306
{
1307
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1308
 
1309
  HAL_I2S_RxHalfCpltCallback(hi2s);
1310
}
1311
 
1312
/**
1313
  * @brief DMA I2S communication error callback
1314
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1315
  *                the configuration information for the specified DMA module.
1316
  * @retval None
1317
  */
1318
static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1319
{
1320
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1321
 
1322
  /* Disable Rx and Tx DMA Request */
1323
  CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1324
  hi2s->TxXferCount = 0;
1325
  hi2s->RxXferCount = 0;
1326
 
1327
  hi2s->State= HAL_I2S_STATE_READY;
1328
 
1329
  /* Set the error code and execute error callback*/
1330
  SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1331
  HAL_I2S_ErrorCallback(hi2s);
1332
}
1333
 
1334
/**
1335
  * @brief Transmit an amount of data in non-blocking mode with Interrupt
1336
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1337
  *         the configuration information for I2S module
1338
  * @retval None
1339
  */
1340
static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1341
{
1342
  /* Transmit data */
1343
  hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
1344
  hi2s->TxXferCount--;
1345
 
1346
  if(hi2s->TxXferCount == 0)
1347
  {
1348
    /* Disable TXE and ERR interrupt */
1349
    __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1350
 
1351
    hi2s->State = HAL_I2S_STATE_READY;
1352
    HAL_I2S_TxCpltCallback(hi2s);
1353
  }
1354
}
1355
 
1356
/**
1357
  * @brief Receive an amount of data in non-blocking mode with Interrupt
1358
  * @param hi2s: I2S handle
1359
  * @retval None
1360
  */
1361
static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1362
{
1363
  /* Receive data */    
1364
  (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1365
  hi2s->RxXferCount--;
1366
 
1367
  if(hi2s->RxXferCount == 0)
1368
  {
1369
    /* Disable RXNE and ERR interrupt */
1370
    __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1371
 
1372
    hi2s->State = HAL_I2S_STATE_READY;    
1373
    HAL_I2S_RxCpltCallback(hi2s);
1374
  }
1375
}
1376
 
1377
 
1378
/**
1379
  * @brief This function handles I2S Communication Timeout.
1380
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1381
  *         the configuration information for I2S module
1382
  * @param Flag: Flag checked
1383
  * @param Status: Value of the flag expected
1384
  * @param Timeout: Duration of the timeout
1385
  * @retval HAL status
1386
  */
1387
static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t Status, uint32_t Timeout)
1388
{
1389
  uint32_t tickstart = 0;
1390
 
1391
  /* Get tick */
1392
  tickstart = HAL_GetTick();
1393
 
1394
  /* Wait until flag is set */
1395
  if(Status == RESET)
1396
  {
1397
    while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET)
1398
    {
1399
      if(Timeout != HAL_MAX_DELAY)
1400
      {
1401
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1402
        {
1403
          /* Set the I2S State ready */
1404
          hi2s->State= HAL_I2S_STATE_READY;
1405
 
1406
          /* Process Unlocked */
1407
          __HAL_UNLOCK(hi2s);
1408
 
1409
          return HAL_TIMEOUT;
1410
        }
1411
      }
1412
    }
1413
  }
1414
  else
1415
  {
1416
    while(__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET)
1417
    {
1418
      if(Timeout != HAL_MAX_DELAY)
1419
      {
1420
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1421
        {
1422
          /* Set the I2S State ready */
1423
          hi2s->State= HAL_I2S_STATE_READY;
1424
 
1425
          /* Process Unlocked */
1426
          __HAL_UNLOCK(hi2s);
1427
 
1428
          return HAL_TIMEOUT;
1429
        }
1430
      }
1431
    }
1432
  }
1433
  return HAL_OK;
1434
}
1435
 
1436
/**
1437
  * @}
1438
  */
1439
 
1440
/**
1441
  * @}
1442
  */
1443
 
1444
#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
1445
#endif /* HAL_I2S_MODULE_ENABLED */
1446
 
1447
 
1448
/**
1449
  * @}
1450
  */
1451
 
1452
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/