Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / lib / stdperiphlib / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_spi.c @ 69661903

History | View | Annotate | Download (51.1 KB)

1 69661903 Thomas Schöpping
/**
2
  ******************************************************************************
3
  * @file    stm32f4xx_spi.c
4
  * @author  MCD Application Team
5
  * @version V1.1.0
6
  * @date    11-January-2013
7
  * @brief   This file provides firmware functions to manage the following 
8
  *          functionalities of the Serial peripheral interface (SPI):
9
  *           + Initialization and Configuration
10
  *           + Data transfers functions
11
  *           + Hardware CRC Calculation
12
  *           + DMA transfers management
13
  *           + Interrupts and flags management 
14
  *           
15
@verbatim
16

17
 ===================================================================
18
                  ##### How to use this driver #####
19
 ===================================================================
20
 [..]
21
   (#) Enable peripheral clock using the following functions 
22
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1
23
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2
24
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3
25
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI4
26
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI5
27
       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI6.
28
  
29
   (#) Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHB1PeriphClockCmd()
30
       function. In I2S mode, if an external clock source is used then the I2S 
31
       CKIN pin GPIO clock should also be enabled.
32
  
33
   (#) Peripherals alternate function: 
34
       (++) Connect the pin to the desired peripherals' Alternate Function (AF) 
35
            using GPIO_PinAFConfig() function
36
       (++) Configure the desired pin in alternate function by: 
37
            GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
38
       (++) Select the type, pull-up/pull-down and output speed via GPIO_PuPd, 
39
            GPIO_OType and GPIO_Speed members
40
       (++) Call GPIO_Init() function In I2S mode, if an external clock source is 
41
            used then the I2S CKIN pin should be also configured in Alternate 
42
            function Push-pull pull-up mode. 
43
          
44
   (#) Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave 
45
       Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
46
       function.
47
       In I2S mode, program the Mode, Standard, Data Format, MCLK Output, Audio 
48
       frequency and Polarity using I2S_Init() function. For I2S mode, make sure 
49
       that either:
50
       (++) I2S PLL is configured using the functions 
51
            RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S), RCC_PLLI2SCmd(ENABLE) and 
52
            RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY); or 
53
       (++) External clock source is configured using the function 
54
            RCC_I2SCLKConfig(RCC_I2S2CLKSource_Ext) and after setting correctly 
55
            the define constant I2S_EXTERNAL_CLOCK_VAL in the stm32f4xx_conf.h file. 
56
  
57
   (#) Enable the NVIC and the corresponding interrupt using the function 
58
       SPI_ITConfig() if you need to use interrupt mode. 
59
  
60
   (#) When using the DMA mode 
61
       (++) Configure the DMA using DMA_Init() function
62
       (++) Active the needed channel Request using SPI_I2S_DMACmd() function
63
   
64
   (#) Enable the SPI using the SPI_Cmd() function or enable the I2S using
65
       I2S_Cmd().
66
   
67
   (#) Enable the DMA using the DMA_Cmd() function when using DMA mode. 
68
  
69
   (#) Optionally, you can enable/configure the following parameters without
70
       re-initialization (i.e there is no need to call again SPI_Init() function):
71
       (++) When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx)
72
            is programmed as Data direction parameter using the SPI_Init() function
73
            it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx
74
            using the SPI_BiDirectionalLineConfig() function.
75
       (++) When SPI_NSS_Soft is selected as Slave Select Management parameter 
76
            using the SPI_Init() function it can be possible to manage the 
77
            NSS internal signal using the SPI_NSSInternalSoftwareConfig() function.
78
       (++) Reconfigure the data size using the SPI_DataSizeConfig() function  
79
       (++) Enable or disable the SS output using the SPI_SSOutputCmd() function  
80
            
81
    (#) To use the CRC Hardware calculation feature refer to the Peripheral 
82
        CRC hardware Calculation subsection.
83
     
84
  
85
 [..] It is possible to use SPI in I2S full duplex mode, in this case, each SPI 
86
      peripheral is able to manage sending and receiving data simultaneously
87
      using two data lines. Each SPI peripheral has an extended block called I2Sxext
88
      (ie. I2S2ext for SPI2 and I2S3ext for SPI3).
89
      The extension block is not a full SPI IP, it is used only as I2S slave to
90
      implement full duplex mode. The extension block uses the same clock sources
91
      as its master.          
92
      To configure I2S full duplex you have to:
93
              
94
      (#) Configure SPIx in I2S mode (I2S_Init() function) as described above. 
95
             
96
      (#) Call the I2S_FullDuplexConfig() function using the same strucutre passed to  
97
          I2S_Init() function.
98
              
99
      (#) Call I2S_Cmd() for SPIx then for its extended block.
100
            
101
      (#) To configure interrupts or DMA requests and to get/clear flag status, 
102
          use I2Sxext instance for the extension block.
103
               
104
 [..] Functions that can be called with I2Sxext instances are: I2S_Cmd(), 
105
      I2S_FullDuplexConfig(), SPI_I2S_ReceiveData(), SPI_I2S_SendData(), 
106
      SPI_I2S_DMACmd(), SPI_I2S_ITConfig(), SPI_I2S_GetFlagStatus(), 
107
      SPI_I2S_ClearFlag(), SPI_I2S_GetITStatus() and SPI_I2S_ClearITPendingBit().
108
                   
109
      Example: To use SPI3 in Full duplex mode (SPI3 is Master Tx, I2S3ext is Slave Rx):
110
              
111
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);   
112
      I2S_StructInit(&I2SInitStruct);
113
      I2SInitStruct.Mode = I2S_Mode_MasterTx;     
114
      I2S_Init(SPI3, &I2SInitStruct);
115
      I2S_FullDuplexConfig(SPI3ext, &I2SInitStruct)
116
      I2S_Cmd(SPI3, ENABLE);
117
      I2S_Cmd(SPI3ext, ENABLE);
118
      ...
119
      while (SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET)
120
      {}
121
      SPI_I2S_SendData(SPI3, txdata[i]);
122
      ...  
123
      while (SPI_I2S_GetFlagStatus(I2S3ext, SPI_FLAG_RXNE) == RESET)
124
      {}
125
      rxdata[i] = SPI_I2S_ReceiveData(I2S3ext);
126
      ...          
127
                
128
 [..]       
129
   (@) In I2S mode: if an external clock is used as source clock for the I2S,  
130
       then the define I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should 
131
       be enabled and set to the value of the source clock frequency (in Hz).
132
   
133
   (@) In SPI mode: To use the SPI TI mode, call the function SPI_TIModeCmd() 
134
       just after calling the function SPI_Init().
135
  
136
@endverbatim  
137
  *                                  
138
  ******************************************************************************
139
  * @attention
140
  *
141
  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
142
  *
143
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
144
  * You may not use this file except in compliance with the License.
145
  * You may obtain a copy of the License at:
146
  *
147
  *        http://www.st.com/software_license_agreement_liberty_v2
148
  *
149
  * Unless required by applicable law or agreed to in writing, software 
150
  * distributed under the License is distributed on an "AS IS" BASIS, 
151
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152
  * See the License for the specific language governing permissions and
153
  * limitations under the License.
154
  *
155
  ******************************************************************************  
156
  */ 
157
158
/* Includes ------------------------------------------------------------------*/
159
#include "stm32f4xx_spi.h"
160
#include "stm32f4xx_rcc.h"
161
162
/** @addtogroup STM32F4xx_StdPeriph_Driver
163
  * @{
164
  */
165
166
/** @defgroup SPI 
167
  * @brief SPI driver modules
168
  * @{
169
  */ 
170
171
/* Private typedef -----------------------------------------------------------*/
172
/* Private define ------------------------------------------------------------*/
173
174
/* SPI registers Masks */
175
#define CR1_CLEAR_MASK            ((uint16_t)0x3040)
176
#define I2SCFGR_CLEAR_MASK        ((uint16_t)0xF040)
177
178
/* RCC PLLs masks */
179
#define PLLCFGR_PPLR_MASK         ((uint32_t)0x70000000)
180
#define PLLCFGR_PPLN_MASK         ((uint32_t)0x00007FC0)
181
182
#define SPI_CR2_FRF               ((uint16_t)0x0010)
183
#define SPI_SR_TIFRFE             ((uint16_t)0x0100)
184
185
/* Private macro -------------------------------------------------------------*/
186
/* Private variables ---------------------------------------------------------*/
187
/* Private function prototypes -----------------------------------------------*/
188
/* Private functions ---------------------------------------------------------*/
189
190
/** @defgroup SPI_Private_Functions
191
  * @{
192
  */
193
194
/** @defgroup SPI_Group1 Initialization and Configuration functions
195
 *  @brief   Initialization and Configuration functions 
196
 *
197
@verbatim   
198
 ===============================================================================
199
             ##### Initialization and Configuration functions ##### 
200
 ===============================================================================  
201
 [..] This section provides a set of functions allowing to initialize the SPI 
202
      Direction, SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS 
203
      Management, SPI Baud Rate Prescaler, SPI First Bit and SPI CRC Polynomial.
204
  
205
 [..] The SPI_Init() function follows the SPI configuration procedures for Master 
206
      mode and Slave mode (details for these procedures are available in reference 
207
      manual (RM0090)).
208
  
209
@endverbatim
210
  * @{
211
  */
212
213
/**
214
  * @brief  De-initialize the SPIx peripheral registers to their default reset values.
215
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
216
  *         in SPI mode or 2 or 3 in I2S mode.   
217
  *         
218
  * @note   The extended I2S blocks (ie. I2S2ext and I2S3ext blocks) are de-initialized
219
  *         when the relative I2S peripheral is de-initialized (the extended block's clock
220
  *         is managed by the I2S peripheral clock).
221
  *             
222
  * @retval None
223
  */
224
void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
225
{
226
  /* Check the parameters */
227
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
228
229
  if (SPIx == SPI1)
230
  {
231
    /* Enable SPI1 reset state */
232
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
233
    /* Release SPI1 from reset state */
234
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
235
  }
236
  else if (SPIx == SPI2)
237
  {
238
    /* Enable SPI2 reset state */
239
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
240
    /* Release SPI2 from reset state */
241
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
242
  }
243
  else if (SPIx == SPI3)
244
  {
245
    /* Enable SPI3 reset state */
246
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
247
    /* Release SPI3 from reset state */
248
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
249
  }
250
  else if (SPIx == SPI4)
251
  {
252
    /* Enable SPI4 reset state */
253
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI4, ENABLE);
254
    /* Release SPI4 from reset state */
255
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI4, DISABLE);
256
  }
257
  else if (SPIx == SPI5)
258
  {
259
    /* Enable SPI5 reset state */
260
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI5, ENABLE);
261
    /* Release SPI5 from reset state */
262
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI5, DISABLE);
263
  }
264
  else 
265
  {
266
    if (SPIx == SPI6)
267
    {
268
      /* Enable SPI6 reset state */
269
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI6, ENABLE);
270
      /* Release SPI6 from reset state */
271
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI6, DISABLE);
272
    }
273
  }
274
}
275
276
/**
277
  * @brief  Initializes the SPIx peripheral according to the specified 
278
  *         parameters in the SPI_InitStruct.
279
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
280
  * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
281
  *         contains the configuration information for the specified SPI peripheral.
282
  * @retval None
283
  */
284
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
285
{
286
  uint16_t tmpreg = 0;
287
  
288
  /* check the parameters */
289
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
290
  
291
  /* Check the SPI parameters */
292
  assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
293
  assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
294
  assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
295
  assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
296
  assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
297
  assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
298
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
299
  assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
300
  assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
301
302
/*---------------------------- SPIx CR1 Configuration ------------------------*/
303
  /* Get the SPIx CR1 value */
304
  tmpreg = SPIx->CR1;
305
  /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
306
  tmpreg &= CR1_CLEAR_MASK;
307
  /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
308
     master/salve mode, CPOL and CPHA */
309
  /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
310
  /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
311
  /* Set LSBFirst bit according to SPI_FirstBit value */
312
  /* Set BR bits according to SPI_BaudRatePrescaler value */
313
  /* Set CPOL bit according to SPI_CPOL value */
314
  /* Set CPHA bit according to SPI_CPHA value */
315
  tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
316
                  SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |  
317
                  SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |  
318
                  SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
319
  /* Write to SPIx CR1 */
320
  SPIx->CR1 = tmpreg;
321
322
  /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
323
  SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
324
/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
325
  /* Write to SPIx CRCPOLY */
326
  SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
327
}
328
329
/**
330
  * @brief  Initializes the SPIx peripheral according to the specified 
331
  *         parameters in the I2S_InitStruct.
332
  * @param  SPIx: where x can be  2 or 3 to select the SPI peripheral (configured in I2S mode).
333
  * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
334
  *         contains the configuration information for the specified SPI peripheral
335
  *         configured in I2S mode.
336
  *           
337
  * @note   The function calculates the optimal prescaler needed to obtain the most 
338
  *         accurate audio frequency (depending on the I2S clock source, the PLL values 
339
  *         and the product configuration). But in case the prescaler value is greater 
340
  *         than 511, the default value (0x02) will be configured instead.    
341
  * 
342
  * @note   if an external clock is used as source clock for the I2S, then the define
343
  *         I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should be enabled and set
344
  *         to the value of the the source clock frequency (in Hz).
345
  *  
346
  * @retval None
347
  */
348
void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
349
{
350
  uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
351
  uint32_t tmp = 0, i2sclk = 0;
352
#ifndef I2S_EXTERNAL_CLOCK_VAL
353
  uint32_t pllm = 0, plln = 0, pllr = 0;
354
#endif /* I2S_EXTERNAL_CLOCK_VAL */
355
  
356
  /* Check the I2S parameters */
357
  assert_param(IS_SPI_23_PERIPH(SPIx));
358
  assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
359
  assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
360
  assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
361
  assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
362
  assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
363
  assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));  
364
365
/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
366
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
367
  SPIx->I2SCFGR &= I2SCFGR_CLEAR_MASK; 
368
  SPIx->I2SPR = 0x0002;
369
  
370
  /* Get the I2SCFGR register value */
371
  tmpreg = SPIx->I2SCFGR;
372
  
373
  /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
374
  if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
375
  {
376
    i2sodd = (uint16_t)0;
377
    i2sdiv = (uint16_t)2;   
378
  }
379
  /* If the requested audio frequency is not the default, compute the prescaler */
380
  else
381
  {
382
    /* Check the frame length (For the Prescaler computing) *******************/
383
    if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
384
    {
385
      /* Packet length is 16 bits */
386
      packetlength = 1;
387
    }
388
    else
389
    {
390
      /* Packet length is 32 bits */
391
      packetlength = 2;
392
    }
393
394
    /* Get I2S source Clock frequency  ****************************************/
395
      
396
    /* If an external I2S clock has to be used, this define should be set  
397
       in the project configuration or in the stm32f4xx_conf.h file */
398
  #ifdef I2S_EXTERNAL_CLOCK_VAL     
399
    /* Set external clock as I2S clock source */
400
    if ((RCC->CFGR & RCC_CFGR_I2SSRC) == 0)
401
    {
402
      RCC->CFGR |= (uint32_t)RCC_CFGR_I2SSRC;
403
    }
404
    
405
    /* Set the I2S clock to the external clock  value */
406
    i2sclk = I2S_EXTERNAL_CLOCK_VAL;
407
408
  #else /* There is no define for External I2S clock source */
409
    /* Set PLLI2S as I2S clock source */
410
    if ((RCC->CFGR & RCC_CFGR_I2SSRC) != 0)
411
    {
412
      RCC->CFGR &= ~(uint32_t)RCC_CFGR_I2SSRC;
413
    }    
414
    
415
    /* Get the PLLI2SN value */
416
    plln = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & \
417
                      (RCC_PLLI2SCFGR_PLLI2SN >> 6));
418
    
419
    /* Get the PLLI2SR value */
420
    pllr = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & \
421
                      (RCC_PLLI2SCFGR_PLLI2SR >> 28));
422
    
423
    /* Get the PLLM value */
424
    pllm = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);      
425
426
    /* Get the I2S source clock value */
427
    i2sclk = (uint32_t)(((HSE_VALUE / pllm) * plln) / pllr);
428
  #endif /* I2S_EXTERNAL_CLOCK_VAL */
429
    
430
    /* Compute the Real divider depending on the MCLK output state, with a floating point */
431
    if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
432
    {
433
      /* MCLK output is enabled */
434
      tmp = (uint16_t)(((((i2sclk / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
435
    }
436
    else
437
    {
438
      /* MCLK output is disabled */
439
      tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
440
    }
441
    
442
    /* Remove the flatting point */
443
    tmp = tmp / 10;  
444
      
445
    /* Check the parity of the divider */
446
    i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
447
   
448
    /* Compute the i2sdiv prescaler */
449
    i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
450
   
451
    /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
452
    i2sodd = (uint16_t) (i2sodd << 8);
453
  }
454
455
  /* Test if the divider is 1 or 0 or greater than 0xFF */
456
  if ((i2sdiv < 2) || (i2sdiv > 0xFF))
457
  {
458
    /* Set the default values */
459
    i2sdiv = 2;
460
    i2sodd = 0;
461
  }
462
463
  /* Write to SPIx I2SPR register the computed value */
464
  SPIx->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
465
 
466
  /* Configure the I2S with the SPI_InitStruct values */
467
  tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
468
                  (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
469
                  (uint16_t)I2S_InitStruct->I2S_CPOL))));
470
 
471
  /* Write to SPIx I2SCFGR */  
472
  SPIx->I2SCFGR = tmpreg;
473
}
474
475
/**
476
  * @brief  Fills each SPI_InitStruct member with its default value.
477
  * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
478
  * @retval None
479
  */
480
void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
481
{
482
/*--------------- Reset SPI init structure parameters values -----------------*/
483
  /* Initialize the SPI_Direction member */
484
  SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
485
  /* initialize the SPI_Mode member */
486
  SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
487
  /* initialize the SPI_DataSize member */
488
  SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
489
  /* Initialize the SPI_CPOL member */
490
  SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
491
  /* Initialize the SPI_CPHA member */
492
  SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
493
  /* Initialize the SPI_NSS member */
494
  SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
495
  /* Initialize the SPI_BaudRatePrescaler member */
496
  SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
497
  /* Initialize the SPI_FirstBit member */
498
  SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
499
  /* Initialize the SPI_CRCPolynomial member */
500
  SPI_InitStruct->SPI_CRCPolynomial = 7;
501
}
502
503
/**
504
  * @brief  Fills each I2S_InitStruct member with its default value.
505
  * @param  I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
506
  * @retval None
507
  */
508
void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
509
{
510
/*--------------- Reset I2S init structure parameters values -----------------*/
511
  /* Initialize the I2S_Mode member */
512
  I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
513
  
514
  /* Initialize the I2S_Standard member */
515
  I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
516
  
517
  /* Initialize the I2S_DataFormat member */
518
  I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
519
  
520
  /* Initialize the I2S_MCLKOutput member */
521
  I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
522
  
523
  /* Initialize the I2S_AudioFreq member */
524
  I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
525
  
526
  /* Initialize the I2S_CPOL member */
527
  I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
528
}
529
530
/**
531
  * @brief  Enables or disables the specified SPI peripheral.
532
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
533
  * @param  NewState: new state of the SPIx peripheral. 
534
  *          This parameter can be: ENABLE or DISABLE.
535
  * @retval None
536
  */
537
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
538
{
539
  /* Check the parameters */
540
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
541
  assert_param(IS_FUNCTIONAL_STATE(NewState));
542
  if (NewState != DISABLE)
543
  {
544
    /* Enable the selected SPI peripheral */
545
    SPIx->CR1 |= SPI_CR1_SPE;
546
  }
547
  else
548
  {
549
    /* Disable the selected SPI peripheral */
550
    SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
551
  }
552
}
553
554
/**
555
  * @brief  Enables or disables the specified SPI peripheral (in I2S mode).
556
  * @param  SPIx: where x can be 2 or 3 to select the SPI peripheral (or I2Sxext 
557
  *         for full duplex mode).
558
  * @param  NewState: new state of the SPIx peripheral. 
559
  *         This parameter can be: ENABLE or DISABLE.
560
  * @retval None
561
  */
562
void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
563
{
564
  /* Check the parameters */
565
  assert_param(IS_SPI_23_PERIPH_EXT(SPIx));
566
  assert_param(IS_FUNCTIONAL_STATE(NewState));
567
  
568
  if (NewState != DISABLE)
569
  {
570
    /* Enable the selected SPI peripheral (in I2S mode) */
571
    SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
572
  }
573
  else
574
  {
575
    /* Disable the selected SPI peripheral in I2S mode */
576
    SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
577
  }
578
}
579
580
/**
581
  * @brief  Configures the data size for the selected SPI.
582
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
583
  * @param  SPI_DataSize: specifies the SPI data size.
584
  *          This parameter can be one of the following values:
585
  *            @arg SPI_DataSize_16b: Set data frame format to 16bit
586
  *            @arg SPI_DataSize_8b: Set data frame format to 8bit
587
  * @retval None
588
  */
589
void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
590
{
591
  /* Check the parameters */
592
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
593
  assert_param(IS_SPI_DATASIZE(SPI_DataSize));
594
  /* Clear DFF bit */
595
  SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b;
596
  /* Set new DFF bit value */
597
  SPIx->CR1 |= SPI_DataSize;
598
}
599
600
/**
601
  * @brief  Selects the data transfer direction in bidirectional mode for the specified SPI.
602
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
603
  * @param  SPI_Direction: specifies the data transfer direction in bidirectional mode. 
604
  *          This parameter can be one of the following values:
605
  *            @arg SPI_Direction_Tx: Selects Tx transmission direction
606
  *            @arg SPI_Direction_Rx: Selects Rx receive direction
607
  * @retval None
608
  */
609
void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
610
{
611
  /* Check the parameters */
612
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
613
  assert_param(IS_SPI_DIRECTION(SPI_Direction));
614
  if (SPI_Direction == SPI_Direction_Tx)
615
  {
616
    /* Set the Tx only mode */
617
    SPIx->CR1 |= SPI_Direction_Tx;
618
  }
619
  else
620
  {
621
    /* Set the Rx only mode */
622
    SPIx->CR1 &= SPI_Direction_Rx;
623
  }
624
}
625
626
/**
627
  * @brief  Configures internally by software the NSS pin for the selected SPI.
628
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
629
  * @param  SPI_NSSInternalSoft: specifies the SPI NSS internal state.
630
  *          This parameter can be one of the following values:
631
  *            @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
632
  *            @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
633
  * @retval None
634
  */
635
void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
636
{
637
  /* Check the parameters */
638
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
639
  assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
640
  if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
641
  {
642
    /* Set NSS pin internally by software */
643
    SPIx->CR1 |= SPI_NSSInternalSoft_Set;
644
  }
645
  else
646
  {
647
    /* Reset NSS pin internally by software */
648
    SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
649
  }
650
}
651
652
/**
653
  * @brief  Enables or disables the SS output for the selected SPI.
654
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
655
  * @param  NewState: new state of the SPIx SS output. 
656
  *          This parameter can be: ENABLE or DISABLE.
657
  * @retval None
658
  */
659
void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
660
{
661
  /* Check the parameters */
662
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
663
  assert_param(IS_FUNCTIONAL_STATE(NewState));
664
  if (NewState != DISABLE)
665
  {
666
    /* Enable the selected SPI SS output */
667
    SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE;
668
  }
669
  else
670
  {
671
    /* Disable the selected SPI SS output */
672
    SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
673
  }
674
}
675
676
/**
677
  * @brief  Enables or disables the SPIx/I2Sx DMA interface.
678
  *   
679
  * @note   This function can be called only after the SPI_Init() function has 
680
  *         been called. 
681
  * @note   When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA 
682
  *         are not taken into consideration and are configured by hardware
683
  *         respectively to the TI mode requirements.  
684
  * 
685
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 
686
  * @param  NewState: new state of the selected SPI TI communication mode.
687
  *          This parameter can be: ENABLE or DISABLE.
688
  * @retval None
689
  */
690
void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
691
{
692
  /* Check the parameters */
693
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
694
  assert_param(IS_FUNCTIONAL_STATE(NewState));
695
696
  if (NewState != DISABLE)
697
  {
698
    /* Enable the TI mode for the selected SPI peripheral */
699
    SPIx->CR2 |= SPI_CR2_FRF;
700
  }
701
  else
702
  {
703
    /* Disable the TI mode for the selected SPI peripheral */
704
    SPIx->CR2 &= (uint16_t)~SPI_CR2_FRF;
705
  }
706
}
707
708
/**
709
  * @brief  Configures the full duplex mode for the I2Sx peripheral using its
710
  *         extension I2Sxext according to the specified parameters in the 
711
  *         I2S_InitStruct.
712
  * @param  I2Sxext: where x can be  2 or 3 to select the I2S peripheral extension block.
713
  * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
714
  *         contains the configuration information for the specified I2S peripheral
715
  *         extension.
716
  * 
717
  * @note   The structure pointed by I2S_InitStruct parameter should be the same
718
  *         used for the master I2S peripheral. In this case, if the master is 
719
  *         configured as transmitter, the slave will be receiver and vice versa.
720
  *         Or you can force a different mode by modifying the field I2S_Mode to the
721
  *         value I2S_SlaveRx or I2S_SlaveTx indepedently of the master configuration.    
722
  *         
723
  * @note   The I2S full duplex extension can be configured in slave mode only.    
724
  *  
725
  * @retval None
726
  */
727
void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct)
728
{
729
  uint16_t tmpreg = 0, tmp = 0;
730
  
731
  /* Check the I2S parameters */
732
  assert_param(IS_I2S_EXT_PERIPH(I2Sxext));
733
  assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
734
  assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
735
  assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
736
  assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));  
737
738
/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
739
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
740
  I2Sxext->I2SCFGR &= I2SCFGR_CLEAR_MASK; 
741
  I2Sxext->I2SPR = 0x0002;
742
  
743
  /* Get the I2SCFGR register value */
744
  tmpreg = I2Sxext->I2SCFGR;
745
  
746
  /* Get the mode to be configured for the extended I2S */
747
  if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx))
748
  {
749
    tmp = I2S_Mode_SlaveRx;
750
  }
751
  else
752
  {
753
    if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveRx))
754
    {
755
      tmp = I2S_Mode_SlaveTx;
756
    }
757
  }
758
759
 
760
  /* Configure the I2S with the SPI_InitStruct values */
761
  tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \
762
                  (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
763
                  (uint16_t)I2S_InitStruct->I2S_CPOL))));
764
 
765
  /* Write to SPIx I2SCFGR */  
766
  I2Sxext->I2SCFGR = tmpreg;
767
}
768
769
/**
770
  * @}
771
  */
772
773
/** @defgroup SPI_Group2 Data transfers functions
774
 *  @brief   Data transfers functions
775
 *
776
@verbatim   
777
 ===============================================================================
778
                      ##### Data transfers functions #####
779
 ===============================================================================  
780

781
 [..] This section provides a set of functions allowing to manage the SPI data 
782
      transfers. In reception, data are received and then stored into an internal 
783
      Rx buffer while. In transmission, data are first stored into an internal Tx 
784
      buffer before being transmitted.
785

786
 [..] The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData()
787
      function and returns the Rx buffered value. Whereas a write access to the SPI_DR 
788
      can be done using SPI_I2S_SendData() function and stores the written data into 
789
      Tx buffer.
790

791
@endverbatim
792
  * @{
793
  */
794
795
/**
796
  * @brief  Returns the most recent received data by the SPIx/I2Sx peripheral. 
797
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
798
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. 
799
  * @retval The value of the received data.
800
  */
801
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
802
{
803
  /* Check the parameters */
804
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
805
  
806
  /* Return the data in the DR register */
807
  return SPIx->DR;
808
}
809
810
/**
811
  * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
812
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
813
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.     
814
  * @param  Data: Data to be transmitted.
815
  * @retval None
816
  */
817
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
818
{
819
  /* Check the parameters */
820
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
821
  
822
  /* Write in the DR register the data to be sent */
823
  SPIx->DR = Data;
824
}
825
826
/**
827
  * @}
828
  */
829
830
/** @defgroup SPI_Group3 Hardware CRC Calculation functions
831
 *  @brief   Hardware CRC Calculation functions
832
 *
833
@verbatim   
834
 ===============================================================================
835
                 ##### Hardware CRC Calculation functions #####
836
 ===============================================================================  
837

838
 [..] This section provides a set of functions allowing to manage the SPI CRC hardware 
839
      calculation
840

841
 [..] SPI communication using CRC is possible through the following procedure:
842
   (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, 
843
       Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
844
       function.
845
   (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
846
   (#) Enable the SPI using the SPI_Cmd() function
847
   (#) Before writing the last data to the TX buffer, set the CRCNext bit using the 
848
       SPI_TransmitCRC() function to indicate that after transmission of the last 
849
       data, the CRC should be transmitted.
850
   (#) After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
851
        bit is reset. The CRC is also received and compared against the SPI_RXCRCR 
852
        value. 
853
        If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
854
        can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
855

856
 [..]
857
   (@) It is advised not to read the calculated CRC values during the communication.
858

859
   (@) When the SPI is in slave mode, be careful to enable CRC calculation only 
860
       when the clock is stable, that is, when the clock is in the steady state. 
861
       If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive 
862
       to the SCK slave input clock as soon as CRCEN is set, and this, whatever 
863
       the value of the SPE bit.
864

865
   (@) With high bitrate frequencies, be careful when transmitting the CRC.
866
       As the number of used CPU cycles has to be as low as possible in the CRC 
867
       transfer phase, it is forbidden to call software functions in the CRC 
868
       transmission sequence to avoid errors in the last data and CRC reception. 
869
       In fact, CRCNEXT bit has to be written before the end of the transmission/reception 
870
       of the last data.
871

872
   (@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the
873
       degradation of the SPI speed performance due to CPU accesses impacting the 
874
       SPI bandwidth.
875

876
   (@) When the STM32F4xx is configured as slave and the NSS hardware mode is 
877
       used, the NSS pin needs to be kept low between the data phase and the CRC 
878
       phase.
879

880
   (@) When the SPI is configured in slave mode with the CRC feature enabled, CRC
881
       calculation takes place even if a high level is applied on the NSS pin. 
882
       This may happen for example in case of a multi-slave environment where the 
883
       communication master addresses slaves alternately.
884

885
   (@) Between a slave de-selection (high level on NSS) and a new slave selection 
886
       (low level on NSS), the CRC value should be cleared on both master and slave
887
       sides in order to resynchronize the master and slave for their respective 
888
       CRC calculation.
889

890
   (@) To clear the CRC, follow the procedure below:
891
       (#@) Disable SPI using the SPI_Cmd() function
892
       (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
893
       (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
894
       (#@) Enable SPI using the SPI_Cmd() function.
895

896
@endverbatim
897
  * @{
898
  */
899
900
/**
901
  * @brief  Enables or disables the CRC value calculation of the transferred bytes.
902
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
903
  * @param  NewState: new state of the SPIx CRC value calculation.
904
  *          This parameter can be: ENABLE or DISABLE.
905
  * @retval None
906
  */
907
void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
908
{
909
  /* Check the parameters */
910
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
911
  assert_param(IS_FUNCTIONAL_STATE(NewState));
912
  if (NewState != DISABLE)
913
  {
914
    /* Enable the selected SPI CRC calculation */
915
    SPIx->CR1 |= SPI_CR1_CRCEN;
916
  }
917
  else
918
  {
919
    /* Disable the selected SPI CRC calculation */
920
    SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
921
  }
922
}
923
924
/**
925
  * @brief  Transmit the SPIx CRC value.
926
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
927
  * @retval None
928
  */
929
void SPI_TransmitCRC(SPI_TypeDef* SPIx)
930
{
931
  /* Check the parameters */
932
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
933
  
934
  /* Enable the selected SPI CRC transmission */
935
  SPIx->CR1 |= SPI_CR1_CRCNEXT;
936
}
937
938
/**
939
  * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
940
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
941
  * @param  SPI_CRC: specifies the CRC register to be read.
942
  *          This parameter can be one of the following values:
943
  *            @arg SPI_CRC_Tx: Selects Tx CRC register
944
  *            @arg SPI_CRC_Rx: Selects Rx CRC register
945
  * @retval The selected CRC register value..
946
  */
947
uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
948
{
949
  uint16_t crcreg = 0;
950
  /* Check the parameters */
951
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
952
  assert_param(IS_SPI_CRC(SPI_CRC));
953
  if (SPI_CRC != SPI_CRC_Rx)
954
  {
955
    /* Get the Tx CRC register */
956
    crcreg = SPIx->TXCRCR;
957
  }
958
  else
959
  {
960
    /* Get the Rx CRC register */
961
    crcreg = SPIx->RXCRCR;
962
  }
963
  /* Return the selected CRC register */
964
  return crcreg;
965
}
966
967
/**
968
  * @brief  Returns the CRC Polynomial register value for the specified SPI.
969
  * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
970
  * @retval The CRC Polynomial register value.
971
  */
972
uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
973
{
974
  /* Check the parameters */
975
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
976
  
977
  /* Return the CRC polynomial register */
978
  return SPIx->CRCPR;
979
}
980
981
/**
982
  * @}
983
  */
984
985
/** @defgroup SPI_Group4 DMA transfers management functions
986
 *  @brief   DMA transfers management functions
987
  *
988
@verbatim   
989
 ===============================================================================
990
                   ##### DMA transfers management functions #####
991
 ===============================================================================  
992

993
@endverbatim
994
  * @{
995
  */
996
997
/**
998
  * @brief  Enables or disables the SPIx/I2Sx DMA interface.
999
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1000
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. 
1001
  * @param  SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. 
1002
  *          This parameter can be any combination of the following values:
1003
  *            @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
1004
  *            @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
1005
  * @param  NewState: new state of the selected SPI DMA transfer request.
1006
  *          This parameter can be: ENABLE or DISABLE.
1007
  * @retval None
1008
  */
1009
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
1010
{
1011
  /* Check the parameters */
1012
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1013
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1014
  assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));
1015
1016
  if (NewState != DISABLE)
1017
  {
1018
    /* Enable the selected SPI DMA requests */
1019
    SPIx->CR2 |= SPI_I2S_DMAReq;
1020
  }
1021
  else
1022
  {
1023
    /* Disable the selected SPI DMA requests */
1024
    SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
1025
  }
1026
}
1027
1028
/**
1029
  * @}
1030
  */
1031
1032
/** @defgroup SPI_Group5 Interrupts and flags management functions
1033
 *  @brief   Interrupts and flags management functions
1034
  *
1035
@verbatim   
1036
 ===============================================================================
1037
            ##### Interrupts and flags management functions #####
1038
 ===============================================================================  
1039
 
1040
 [..] This section provides a set of functions allowing to configure the SPI Interrupts 
1041
      sources and check or clear the flags or pending bits status.
1042
      The user should identify which mode will be used in his application to manage 
1043
      the communication: Polling mode, Interrupt mode or DMA mode. 
1044
    
1045
 *** Polling Mode ***
1046
 ====================
1047
[..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
1048
  (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
1049
  (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
1050
  (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
1051
  (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur              
1052
  (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
1053
  (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
1054
  (#) I2S_FLAG_TIFRFE: to indicate a Frame Format error occurs.
1055
  (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
1056
  (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
1057

1058
  (@) Do not use the BSY flag to handle each data transmission or reception. It is
1059
      better to use the TXE and RXNE flags instead.
1060

1061
 [..] In this Mode it is advised to use the following functions:
1062
   (+) FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1063
   (+) void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1064

1065
 *** Interrupt Mode ***
1066
 ======================
1067
 [..] In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources
1068
      and 7 pending bits: 
1069
   (+) Pending Bits:
1070
       (##) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
1071
       (##) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
1072
       (##) SPI_IT_CRCERR : to indicate if a CRC Calculation error occur (available in SPI mode only)            
1073
       (##) SPI_IT_MODF : to indicate if a Mode Fault error occur (available in SPI mode only)
1074
       (##) SPI_I2S_IT_OVR : to indicate if an Overrun error occur
1075
       (##) I2S_IT_UDR : to indicate an Underrun Error occurs (available in I2S mode only).
1076
       (##) I2S_FLAG_TIFRFE : to indicate a Frame Format error occurs (available in TI mode only).
1077

1078
   (+) Interrupt Source:
1079
       (##) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty 
1080
            interrupt.  
1081
       (##) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not 
1082
            empty interrupt.
1083
       (##) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
1084

1085
 [..] In this Mode it is advised to use the following functions:
1086
   (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
1087
   (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1088
   (+) void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1089

1090
 *** DMA Mode ***
1091
 ================
1092
 [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests:
1093
   (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request
1094
   (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request
1095

1096
 [..] In this Mode it is advised to use the following function:
1097
   (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState 
1098
       NewState);
1099

1100
@endverbatim
1101
  * @{
1102
  */
1103
1104
/**
1105
  * @brief  Enables or disables the specified SPI/I2S interrupts.
1106
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1107
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. 
1108
  * @param  SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. 
1109
  *          This parameter can be one of the following values:
1110
  *            @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
1111
  *            @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
1112
  *            @arg SPI_I2S_IT_ERR: Error interrupt mask
1113
  * @param  NewState: new state of the specified SPI interrupt.
1114
  *          This parameter can be: ENABLE or DISABLE.
1115
  * @retval None
1116
  */
1117
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
1118
{
1119
  uint16_t itpos = 0, itmask = 0 ;
1120
  
1121
  /* Check the parameters */
1122
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1123
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1124
  assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
1125
1126
  /* Get the SPI IT index */
1127
  itpos = SPI_I2S_IT >> 4;
1128
1129
  /* Set the IT mask */
1130
  itmask = (uint16_t)1 << (uint16_t)itpos;
1131
1132
  if (NewState != DISABLE)
1133
  {
1134
    /* Enable the selected SPI interrupt */
1135
    SPIx->CR2 |= itmask;
1136
  }
1137
  else
1138
  {
1139
    /* Disable the selected SPI interrupt */
1140
    SPIx->CR2 &= (uint16_t)~itmask;
1141
  }
1142
}
1143
1144
/**
1145
  * @brief  Checks whether the specified SPIx/I2Sx flag is set or not.
1146
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1147
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. 
1148
  * @param  SPI_I2S_FLAG: specifies the SPI flag to check. 
1149
  *          This parameter can be one of the following values:
1150
  *            @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
1151
  *            @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
1152
  *            @arg SPI_I2S_FLAG_BSY: Busy flag.
1153
  *            @arg SPI_I2S_FLAG_OVR: Overrun flag.
1154
  *            @arg SPI_FLAG_MODF: Mode Fault flag.
1155
  *            @arg SPI_FLAG_CRCERR: CRC Error flag.
1156
  *            @arg SPI_I2S_FLAG_TIFRFE: Format Error.
1157
  *            @arg I2S_FLAG_UDR: Underrun Error flag.
1158
  *            @arg I2S_FLAG_CHSIDE: Channel Side flag.  
1159
  * @retval The new state of SPI_I2S_FLAG (SET or RESET).
1160
  */
1161
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1162
{
1163
  FlagStatus bitstatus = RESET;
1164
  /* Check the parameters */
1165
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1166
  assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
1167
  
1168
  /* Check the status of the specified SPI flag */
1169
  if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
1170
  {
1171
    /* SPI_I2S_FLAG is set */
1172
    bitstatus = SET;
1173
  }
1174
  else
1175
  {
1176
    /* SPI_I2S_FLAG is reset */
1177
    bitstatus = RESET;
1178
  }
1179
  /* Return the SPI_I2S_FLAG status */
1180
  return  bitstatus;
1181
}
1182
1183
/**
1184
  * @brief  Clears the SPIx CRC Error (CRCERR) flag.
1185
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1186
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. 
1187
  * @param  SPI_I2S_FLAG: specifies the SPI flag to clear. 
1188
  *          This function clears only CRCERR flag.
1189
  *            @arg SPI_FLAG_CRCERR: CRC Error flag.  
1190
  *  
1191
  * @note   OVR (OverRun error) flag is cleared by software sequence: a read 
1192
  *          operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read 
1193
  *          operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
1194
  * @note   UDR (UnderRun error) flag is cleared by a read operation to 
1195
  *          SPI_SR register (SPI_I2S_GetFlagStatus()).   
1196
  * @note   MODF (Mode Fault) flag is cleared by software sequence: a read/write 
1197
  *          operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a 
1198
  *          write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
1199
  *  
1200
  * @retval None
1201
  */
1202
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1203
{
1204
  /* Check the parameters */
1205
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1206
  assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));
1207
    
1208
  /* Clear the selected SPI CRC Error (CRCERR) flag */
1209
  SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
1210
}
1211
1212
/**
1213
  * @brief  Checks whether the specified SPIx/I2Sx interrupt has occurred or not.
1214
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1215
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.  
1216
  * @param  SPI_I2S_IT: specifies the SPI interrupt source to check. 
1217
  *          This parameter can be one of the following values:
1218
  *            @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
1219
  *            @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
1220
  *            @arg SPI_I2S_IT_OVR: Overrun interrupt.
1221
  *            @arg SPI_IT_MODF: Mode Fault interrupt.
1222
  *            @arg SPI_IT_CRCERR: CRC Error interrupt.
1223
  *            @arg I2S_IT_UDR: Underrun interrupt.  
1224
  *            @arg SPI_I2S_IT_TIFRFE: Format Error interrupt.  
1225
  * @retval The new state of SPI_I2S_IT (SET or RESET).
1226
  */
1227
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1228
{
1229
  ITStatus bitstatus = RESET;
1230
  uint16_t itpos = 0, itmask = 0, enablestatus = 0;
1231
1232
  /* Check the parameters */
1233
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1234
  assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
1235
1236
  /* Get the SPI_I2S_IT index */
1237
  itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1238
1239
  /* Get the SPI_I2S_IT IT mask */
1240
  itmask = SPI_I2S_IT >> 4;
1241
1242
  /* Set the IT mask */
1243
  itmask = 0x01 << itmask;
1244
1245
  /* Get the SPI_I2S_IT enable bit status */
1246
  enablestatus = (SPIx->CR2 & itmask) ;
1247
1248
  /* Check the status of the specified SPI interrupt */
1249
  if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
1250
  {
1251
    /* SPI_I2S_IT is set */
1252
    bitstatus = SET;
1253
  }
1254
  else
1255
  {
1256
    /* SPI_I2S_IT is reset */
1257
    bitstatus = RESET;
1258
  }
1259
  /* Return the SPI_I2S_IT status */
1260
  return bitstatus;
1261
}
1262
1263
/**
1264
  * @brief  Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
1265
  * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6 
1266
  *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.  
1267
  * @param  SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.
1268
  *         This function clears only CRCERR interrupt pending bit.   
1269
  *            @arg SPI_IT_CRCERR: CRC Error interrupt.
1270
  *   
1271
  * @note   OVR (OverRun Error) interrupt pending bit is cleared by software 
1272
  *          sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) 
1273
  *          followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()).
1274
  * @note   UDR (UnderRun Error) interrupt pending bit is cleared by a read 
1275
  *          operation to SPI_SR register (SPI_I2S_GetITStatus()).   
1276
  * @note   MODF (Mode Fault) interrupt pending bit is cleared by software sequence:
1277
  *          a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) 
1278
  *          followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable 
1279
  *          the SPI).
1280
  * @retval None
1281
  */
1282
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1283
{
1284
  uint16_t itpos = 0;
1285
  /* Check the parameters */
1286
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1287
  assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));
1288
1289
  /* Get the SPI_I2S IT index */
1290
  itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1291
1292
  /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */
1293
  SPIx->SR = (uint16_t)~itpos;
1294
}
1295
1296
/**
1297
  * @}
1298
  */
1299
1300
/**
1301
  * @}
1302
  */ 
1303
1304
/**
1305
  * @}
1306
  */ 
1307
1308
/**
1309
  * @}
1310
  */ 
1311
1312
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/