• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_spi.c
4   * @author  MCD Application Team
5   * @version V1.4.0
6   * @date    04-August-2014
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 2014 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 #include "stm32f4xx_conf.h"
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   */
SPI_I2S_DeInit(SPI_TypeDef * SPIx)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   */
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)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   */
I2S_Init(SPI_TypeDef * SPIx,I2S_InitTypeDef * I2S_InitStruct)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     if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)
427     {
428       /* Get the I2S source clock value */
429       i2sclk = (uint32_t)(((HSE_VALUE / pllm) * plln) / pllr);
430     }
431     else
432     { /* Get the I2S source clock value */
433       i2sclk = (uint32_t)(((HSI_VALUE / pllm) * plln) / pllr);
434     }
435   #endif /* I2S_EXTERNAL_CLOCK_VAL */
436 
437     /* Compute the Real divider depending on the MCLK output state, with a floating point */
438     if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
439     {
440       /* MCLK output is enabled */
441       tmp = (uint16_t)(((((i2sclk / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
442     }
443     else
444     {
445       /* MCLK output is disabled */
446       tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
447     }
448 
449     /* Remove the flatting point */
450     tmp = tmp / 10;
451 
452     /* Check the parity of the divider */
453     i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
454 
455     /* Compute the i2sdiv prescaler */
456     i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
457 
458     /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
459     i2sodd = (uint16_t) (i2sodd << 8);
460   }
461 
462   /* Test if the divider is 1 or 0 or greater than 0xFF */
463   if ((i2sdiv < 2) || (i2sdiv > 0xFF))
464   {
465     /* Set the default values */
466     i2sdiv = 2;
467     i2sodd = 0;
468   }
469 
470   /* Write to SPIx I2SPR register the computed value */
471   SPIx->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
472 
473   /* Configure the I2S with the SPI_InitStruct values */
474   tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
475                   (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
476                   (uint16_t)I2S_InitStruct->I2S_CPOL))));
477 
478   /* Write to SPIx I2SCFGR */
479   SPIx->I2SCFGR = tmpreg;
480 }
481 
482 /**
483   * @brief  Fills each SPI_InitStruct member with its default value.
484   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
485   * @retval None
486   */
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)487 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
488 {
489 /*--------------- Reset SPI init structure parameters values -----------------*/
490   /* Initialize the SPI_Direction member */
491   SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
492   /* initialize the SPI_Mode member */
493   SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
494   /* initialize the SPI_DataSize member */
495   SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
496   /* Initialize the SPI_CPOL member */
497   SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
498   /* Initialize the SPI_CPHA member */
499   SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
500   /* Initialize the SPI_NSS member */
501   SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
502   /* Initialize the SPI_BaudRatePrescaler member */
503   SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
504   /* Initialize the SPI_FirstBit member */
505   SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
506   /* Initialize the SPI_CRCPolynomial member */
507   SPI_InitStruct->SPI_CRCPolynomial = 7;
508 }
509 
510 /**
511   * @brief  Fills each I2S_InitStruct member with its default value.
512   * @param  I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
513   * @retval None
514   */
I2S_StructInit(I2S_InitTypeDef * I2S_InitStruct)515 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
516 {
517 /*--------------- Reset I2S init structure parameters values -----------------*/
518   /* Initialize the I2S_Mode member */
519   I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
520 
521   /* Initialize the I2S_Standard member */
522   I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
523 
524   /* Initialize the I2S_DataFormat member */
525   I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
526 
527   /* Initialize the I2S_MCLKOutput member */
528   I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
529 
530   /* Initialize the I2S_AudioFreq member */
531   I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
532 
533   /* Initialize the I2S_CPOL member */
534   I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
535 }
536 
537 /**
538   * @brief  Enables or disables the specified SPI peripheral.
539   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
540   * @param  NewState: new state of the SPIx peripheral.
541   *          This parameter can be: ENABLE or DISABLE.
542   * @retval None
543   */
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)544 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
545 {
546   /* Check the parameters */
547   assert_param(IS_SPI_ALL_PERIPH(SPIx));
548   assert_param(IS_FUNCTIONAL_STATE(NewState));
549   if (NewState != DISABLE)
550   {
551     /* Enable the selected SPI peripheral */
552     SPIx->CR1 |= SPI_CR1_SPE;
553   }
554   else
555   {
556     /* Disable the selected SPI peripheral */
557     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
558   }
559 }
560 
561 /**
562   * @brief  Enables or disables the specified SPI peripheral (in I2S mode).
563   * @param  SPIx: where x can be 2 or 3 to select the SPI peripheral (or I2Sxext
564   *         for full duplex mode).
565   * @param  NewState: new state of the SPIx peripheral.
566   *         This parameter can be: ENABLE or DISABLE.
567   * @retval None
568   */
I2S_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)569 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
570 {
571   /* Check the parameters */
572   assert_param(IS_SPI_23_PERIPH_EXT(SPIx));
573   assert_param(IS_FUNCTIONAL_STATE(NewState));
574 
575   if (NewState != DISABLE)
576   {
577     /* Enable the selected SPI peripheral (in I2S mode) */
578     SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
579   }
580   else
581   {
582     /* Disable the selected SPI peripheral in I2S mode */
583     SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
584   }
585 }
586 
587 /**
588   * @brief  Configures the data size for the selected SPI.
589   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
590   * @param  SPI_DataSize: specifies the SPI data size.
591   *          This parameter can be one of the following values:
592   *            @arg SPI_DataSize_16b: Set data frame format to 16bit
593   *            @arg SPI_DataSize_8b: Set data frame format to 8bit
594   * @retval None
595   */
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)596 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
597 {
598   /* Check the parameters */
599   assert_param(IS_SPI_ALL_PERIPH(SPIx));
600   assert_param(IS_SPI_DATASIZE(SPI_DataSize));
601   /* Clear DFF bit */
602   SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b;
603   /* Set new DFF bit value */
604   SPIx->CR1 |= SPI_DataSize;
605 }
606 
607 /**
608   * @brief  Selects the data transfer direction in bidirectional mode for the specified SPI.
609   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
610   * @param  SPI_Direction: specifies the data transfer direction in bidirectional mode.
611   *          This parameter can be one of the following values:
612   *            @arg SPI_Direction_Tx: Selects Tx transmission direction
613   *            @arg SPI_Direction_Rx: Selects Rx receive direction
614   * @retval None
615   */
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)616 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
617 {
618   /* Check the parameters */
619   assert_param(IS_SPI_ALL_PERIPH(SPIx));
620   assert_param(IS_SPI_DIRECTION(SPI_Direction));
621   if (SPI_Direction == SPI_Direction_Tx)
622   {
623     /* Set the Tx only mode */
624     SPIx->CR1 |= SPI_Direction_Tx;
625   }
626   else
627   {
628     /* Set the Rx only mode */
629     SPIx->CR1 &= SPI_Direction_Rx;
630   }
631 }
632 
633 /**
634   * @brief  Configures internally by software the NSS pin for the selected SPI.
635   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
636   * @param  SPI_NSSInternalSoft: specifies the SPI NSS internal state.
637   *          This parameter can be one of the following values:
638   *            @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
639   *            @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
640   * @retval None
641   */
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)642 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
643 {
644   /* Check the parameters */
645   assert_param(IS_SPI_ALL_PERIPH(SPIx));
646   assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
647   if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
648   {
649     /* Set NSS pin internally by software */
650     SPIx->CR1 |= SPI_NSSInternalSoft_Set;
651   }
652   else
653   {
654     /* Reset NSS pin internally by software */
655     SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
656   }
657 }
658 
659 /**
660   * @brief  Enables or disables the SS output for the selected SPI.
661   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
662   * @param  NewState: new state of the SPIx SS output.
663   *          This parameter can be: ENABLE or DISABLE.
664   * @retval None
665   */
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)666 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
667 {
668   /* Check the parameters */
669   assert_param(IS_SPI_ALL_PERIPH(SPIx));
670   assert_param(IS_FUNCTIONAL_STATE(NewState));
671   if (NewState != DISABLE)
672   {
673     /* Enable the selected SPI SS output */
674     SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE;
675   }
676   else
677   {
678     /* Disable the selected SPI SS output */
679     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
680   }
681 }
682 
683 /**
684   * @brief  Enables or disables the SPIx/I2Sx DMA interface.
685   *
686   * @note   This function can be called only after the SPI_Init() function has
687   *         been called.
688   * @note   When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
689   *         are not taken into consideration and are configured by hardware
690   *         respectively to the TI mode requirements.
691   *
692   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6
693   * @param  NewState: new state of the selected SPI TI communication mode.
694   *          This parameter can be: ENABLE or DISABLE.
695   * @retval None
696   */
SPI_TIModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)697 void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
698 {
699   /* Check the parameters */
700   assert_param(IS_SPI_ALL_PERIPH(SPIx));
701   assert_param(IS_FUNCTIONAL_STATE(NewState));
702 
703   if (NewState != DISABLE)
704   {
705     /* Enable the TI mode for the selected SPI peripheral */
706     SPIx->CR2 |= SPI_CR2_FRF;
707   }
708   else
709   {
710     /* Disable the TI mode for the selected SPI peripheral */
711     SPIx->CR2 &= (uint16_t)~SPI_CR2_FRF;
712   }
713 }
714 
715 /**
716   * @brief  Configures the full duplex mode for the I2Sx peripheral using its
717   *         extension I2Sxext according to the specified parameters in the
718   *         I2S_InitStruct.
719   * @param  I2Sxext: where x can be  2 or 3 to select the I2S peripheral extension block.
720   * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
721   *         contains the configuration information for the specified I2S peripheral
722   *         extension.
723   *
724   * @note   The structure pointed by I2S_InitStruct parameter should be the same
725   *         used for the master I2S peripheral. In this case, if the master is
726   *         configured as transmitter, the slave will be receiver and vice versa.
727   *         Or you can force a different mode by modifying the field I2S_Mode to the
728   *         value I2S_SlaveRx or I2S_SlaveTx indepedently of the master configuration.
729   *
730   * @note   The I2S full duplex extension can be configured in slave mode only.
731   *
732   * @retval None
733   */
I2S_FullDuplexConfig(SPI_TypeDef * I2Sxext,I2S_InitTypeDef * I2S_InitStruct)734 void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct)
735 {
736   uint16_t tmpreg = 0, tmp = 0;
737 
738   /* Check the I2S parameters */
739   assert_param(IS_I2S_EXT_PERIPH(I2Sxext));
740   assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
741   assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
742   assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
743   assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
744 
745 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
746   /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
747   I2Sxext->I2SCFGR &= I2SCFGR_CLEAR_MASK;
748   I2Sxext->I2SPR = 0x0002;
749 
750   /* Get the I2SCFGR register value */
751   tmpreg = I2Sxext->I2SCFGR;
752 
753   /* Get the mode to be configured for the extended I2S */
754   if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx))
755   {
756     tmp = I2S_Mode_SlaveRx;
757   }
758   else
759   {
760     if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveRx))
761     {
762       tmp = I2S_Mode_SlaveTx;
763     }
764   }
765 
766 
767   /* Configure the I2S with the SPI_InitStruct values */
768   tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \
769                   (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
770                   (uint16_t)I2S_InitStruct->I2S_CPOL))));
771 
772   /* Write to SPIx I2SCFGR */
773   I2Sxext->I2SCFGR = tmpreg;
774 }
775 
776 /**
777   * @}
778   */
779 
780 /** @defgroup SPI_Group2 Data transfers functions
781  *  @brief   Data transfers functions
782  *
783 @verbatim
784  ===============================================================================
785                       ##### Data transfers functions #####
786  ===============================================================================
787 
788  [..] This section provides a set of functions allowing to manage the SPI data
789       transfers. In reception, data are received and then stored into an internal
790       Rx buffer while. In transmission, data are first stored into an internal Tx
791       buffer before being transmitted.
792 
793  [..] The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData()
794       function and returns the Rx buffered value. Whereas a write access to the SPI_DR
795       can be done using SPI_I2S_SendData() function and stores the written data into
796       Tx buffer.
797 
798 @endverbatim
799   * @{
800   */
801 
802 /**
803   * @brief  Returns the most recent received data by the SPIx/I2Sx peripheral.
804   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
805   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
806   * @retval The value of the received data.
807   */
SPI_I2S_ReceiveData(SPI_TypeDef * SPIx)808 uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
809 {
810   /* Check the parameters */
811   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
812 
813   /* Return the data in the DR register */
814   return SPIx->DR;
815 }
816 
817 /**
818   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
819   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
820   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
821   * @param  Data: Data to be transmitted.
822   * @retval None
823   */
SPI_I2S_SendData(SPI_TypeDef * SPIx,uint16_t Data)824 void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
825 {
826   /* Check the parameters */
827   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
828 
829   /* Write in the DR register the data to be sent */
830   SPIx->DR = Data;
831 }
832 
833 /**
834   * @}
835   */
836 
837 /** @defgroup SPI_Group3 Hardware CRC Calculation functions
838  *  @brief   Hardware CRC Calculation functions
839  *
840 @verbatim
841  ===============================================================================
842                  ##### Hardware CRC Calculation functions #####
843  ===============================================================================
844 
845  [..] This section provides a set of functions allowing to manage the SPI CRC hardware
846       calculation
847 
848  [..] SPI communication using CRC is possible through the following procedure:
849    (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
850        Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
851        function.
852    (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
853    (#) Enable the SPI using the SPI_Cmd() function
854    (#) Before writing the last data to the TX buffer, set the CRCNext bit using the
855        SPI_TransmitCRC() function to indicate that after transmission of the last
856        data, the CRC should be transmitted.
857    (#) After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
858         bit is reset. The CRC is also received and compared against the SPI_RXCRCR
859         value.
860         If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
861         can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
862 
863  [..]
864    (@) It is advised not to read the calculated CRC values during the communication.
865 
866    (@) When the SPI is in slave mode, be careful to enable CRC calculation only
867        when the clock is stable, that is, when the clock is in the steady state.
868        If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive
869        to the SCK slave input clock as soon as CRCEN is set, and this, whatever
870        the value of the SPE bit.
871 
872    (@) With high bitrate frequencies, be careful when transmitting the CRC.
873        As the number of used CPU cycles has to be as low as possible in the CRC
874        transfer phase, it is forbidden to call software functions in the CRC
875        transmission sequence to avoid errors in the last data and CRC reception.
876        In fact, CRCNEXT bit has to be written before the end of the transmission/reception
877        of the last data.
878 
879    (@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the
880        degradation of the SPI speed performance due to CPU accesses impacting the
881        SPI bandwidth.
882 
883    (@) When the STM32F4xx is configured as slave and the NSS hardware mode is
884        used, the NSS pin needs to be kept low between the data phase and the CRC
885        phase.
886 
887    (@) When the SPI is configured in slave mode with the CRC feature enabled, CRC
888        calculation takes place even if a high level is applied on the NSS pin.
889        This may happen for example in case of a multi-slave environment where the
890        communication master addresses slaves alternately.
891 
892    (@) Between a slave de-selection (high level on NSS) and a new slave selection
893        (low level on NSS), the CRC value should be cleared on both master and slave
894        sides in order to resynchronize the master and slave for their respective
895        CRC calculation.
896 
897    (@) To clear the CRC, follow the procedure below:
898        (#@) Disable SPI using the SPI_Cmd() function
899        (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
900        (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
901        (#@) Enable SPI using the SPI_Cmd() function.
902 
903 @endverbatim
904   * @{
905   */
906 
907 /**
908   * @brief  Enables or disables the CRC value calculation of the transferred bytes.
909   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
910   * @param  NewState: new state of the SPIx CRC value calculation.
911   *          This parameter can be: ENABLE or DISABLE.
912   * @retval None
913   */
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)914 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
915 {
916   /* Check the parameters */
917   assert_param(IS_SPI_ALL_PERIPH(SPIx));
918   assert_param(IS_FUNCTIONAL_STATE(NewState));
919   if (NewState != DISABLE)
920   {
921     /* Enable the selected SPI CRC calculation */
922     SPIx->CR1 |= SPI_CR1_CRCEN;
923   }
924   else
925   {
926     /* Disable the selected SPI CRC calculation */
927     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
928   }
929 }
930 
931 /**
932   * @brief  Transmit the SPIx CRC value.
933   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
934   * @retval None
935   */
SPI_TransmitCRC(SPI_TypeDef * SPIx)936 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
937 {
938   /* Check the parameters */
939   assert_param(IS_SPI_ALL_PERIPH(SPIx));
940 
941   /* Enable the selected SPI CRC transmission */
942   SPIx->CR1 |= SPI_CR1_CRCNEXT;
943 }
944 
945 /**
946   * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
947   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
948   * @param  SPI_CRC: specifies the CRC register to be read.
949   *          This parameter can be one of the following values:
950   *            @arg SPI_CRC_Tx: Selects Tx CRC register
951   *            @arg SPI_CRC_Rx: Selects Rx CRC register
952   * @retval The selected CRC register value..
953   */
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)954 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
955 {
956   uint16_t crcreg = 0;
957   /* Check the parameters */
958   assert_param(IS_SPI_ALL_PERIPH(SPIx));
959   assert_param(IS_SPI_CRC(SPI_CRC));
960   if (SPI_CRC != SPI_CRC_Rx)
961   {
962     /* Get the Tx CRC register */
963     crcreg = SPIx->TXCRCR;
964   }
965   else
966   {
967     /* Get the Rx CRC register */
968     crcreg = SPIx->RXCRCR;
969   }
970   /* Return the selected CRC register */
971   return crcreg;
972 }
973 
974 /**
975   * @brief  Returns the CRC Polynomial register value for the specified SPI.
976   * @param  SPIx: where x can be 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
977   * @retval The CRC Polynomial register value.
978   */
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)979 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
980 {
981   /* Check the parameters */
982   assert_param(IS_SPI_ALL_PERIPH(SPIx));
983 
984   /* Return the CRC polynomial register */
985   return SPIx->CRCPR;
986 }
987 
988 /**
989   * @}
990   */
991 
992 /** @defgroup SPI_Group4 DMA transfers management functions
993  *  @brief   DMA transfers management functions
994   *
995 @verbatim
996  ===============================================================================
997                    ##### DMA transfers management functions #####
998  ===============================================================================
999 
1000 @endverbatim
1001   * @{
1002   */
1003 
1004 /**
1005   * @brief  Enables or disables the SPIx/I2Sx DMA interface.
1006   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1007   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1008   * @param  SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled.
1009   *          This parameter can be any combination of the following values:
1010   *            @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
1011   *            @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
1012   * @param  NewState: new state of the selected SPI DMA transfer request.
1013   *          This parameter can be: ENABLE or DISABLE.
1014   * @retval None
1015   */
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)1016 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
1017 {
1018   /* Check the parameters */
1019   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1020   assert_param(IS_FUNCTIONAL_STATE(NewState));
1021   assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));
1022 
1023   if (NewState != DISABLE)
1024   {
1025     /* Enable the selected SPI DMA requests */
1026     SPIx->CR2 |= SPI_I2S_DMAReq;
1027   }
1028   else
1029   {
1030     /* Disable the selected SPI DMA requests */
1031     SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
1032   }
1033 }
1034 
1035 /**
1036   * @}
1037   */
1038 
1039 /** @defgroup SPI_Group5 Interrupts and flags management functions
1040  *  @brief   Interrupts and flags management functions
1041   *
1042 @verbatim
1043  ===============================================================================
1044             ##### Interrupts and flags management functions #####
1045  ===============================================================================
1046 
1047  [..] This section provides a set of functions allowing to configure the SPI Interrupts
1048       sources and check or clear the flags or pending bits status.
1049       The user should identify which mode will be used in his application to manage
1050       the communication: Polling mode, Interrupt mode or DMA mode.
1051 
1052  *** Polling Mode ***
1053  ====================
1054 [..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
1055   (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
1056   (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
1057   (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
1058   (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
1059   (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
1060   (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
1061   (#) I2S_FLAG_TIFRFE: to indicate a Frame Format error occurs.
1062   (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
1063   (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
1064 
1065   (@) Do not use the BSY flag to handle each data transmission or reception. It is
1066       better to use the TXE and RXNE flags instead.
1067 
1068  [..] In this Mode it is advised to use the following functions:
1069    (+) FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1070    (+) void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1071 
1072  *** Interrupt Mode ***
1073  ======================
1074  [..] In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources
1075       and 7 pending bits:
1076    (+) Pending Bits:
1077        (##) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
1078        (##) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
1079        (##) SPI_IT_CRCERR : to indicate if a CRC Calculation error occur (available in SPI mode only)
1080        (##) SPI_IT_MODF : to indicate if a Mode Fault error occur (available in SPI mode only)
1081        (##) SPI_I2S_IT_OVR : to indicate if an Overrun error occur
1082        (##) I2S_IT_UDR : to indicate an Underrun Error occurs (available in I2S mode only).
1083        (##) I2S_FLAG_TIFRFE : to indicate a Frame Format error occurs (available in TI mode only).
1084 
1085    (+) Interrupt Source:
1086        (##) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
1087             interrupt.
1088        (##) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
1089             empty interrupt.
1090        (##) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
1091 
1092  [..] In this Mode it is advised to use the following functions:
1093    (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
1094    (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1095    (+) void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1096 
1097  *** DMA Mode ***
1098  ================
1099  [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests:
1100    (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request
1101    (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request
1102 
1103  [..] In this Mode it is advised to use the following function:
1104    (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState
1105        NewState);
1106 
1107 @endverbatim
1108   * @{
1109   */
1110 
1111 /**
1112   * @brief  Enables or disables the specified SPI/I2S interrupts.
1113   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1114   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1115   * @param  SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
1116   *          This parameter can be one of the following values:
1117   *            @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
1118   *            @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
1119   *            @arg SPI_I2S_IT_ERR: Error interrupt mask
1120   * @param  NewState: new state of the specified SPI interrupt.
1121   *          This parameter can be: ENABLE or DISABLE.
1122   * @retval None
1123   */
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)1124 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
1125 {
1126   uint16_t itpos = 0, itmask = 0 ;
1127 
1128   /* Check the parameters */
1129   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1130   assert_param(IS_FUNCTIONAL_STATE(NewState));
1131   assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
1132 
1133   /* Get the SPI IT index */
1134   itpos = SPI_I2S_IT >> 4;
1135 
1136   /* Set the IT mask */
1137   itmask = (uint16_t)1 << (uint16_t)itpos;
1138 
1139   if (NewState != DISABLE)
1140   {
1141     /* Enable the selected SPI interrupt */
1142     SPIx->CR2 |= itmask;
1143   }
1144   else
1145   {
1146     /* Disable the selected SPI interrupt */
1147     SPIx->CR2 &= (uint16_t)~itmask;
1148   }
1149 }
1150 
1151 /**
1152   * @brief  Checks whether the specified SPIx/I2Sx flag is set or not.
1153   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1154   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1155   * @param  SPI_I2S_FLAG: specifies the SPI flag to check.
1156   *          This parameter can be one of the following values:
1157   *            @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
1158   *            @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
1159   *            @arg SPI_I2S_FLAG_BSY: Busy flag.
1160   *            @arg SPI_I2S_FLAG_OVR: Overrun flag.
1161   *            @arg SPI_FLAG_MODF: Mode Fault flag.
1162   *            @arg SPI_FLAG_CRCERR: CRC Error flag.
1163   *            @arg SPI_I2S_FLAG_TIFRFE: Format Error.
1164   *            @arg I2S_FLAG_UDR: Underrun Error flag.
1165   *            @arg I2S_FLAG_CHSIDE: Channel Side flag.
1166   * @retval The new state of SPI_I2S_FLAG (SET or RESET).
1167   */
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1168 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1169 {
1170   FlagStatus bitstatus = RESET;
1171   /* Check the parameters */
1172   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1173   assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
1174 
1175   /* Check the status of the specified SPI flag */
1176   if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
1177   {
1178     /* SPI_I2S_FLAG is set */
1179     bitstatus = SET;
1180   }
1181   else
1182   {
1183     /* SPI_I2S_FLAG is reset */
1184     bitstatus = RESET;
1185   }
1186   /* Return the SPI_I2S_FLAG status */
1187   return  bitstatus;
1188 }
1189 
1190 /**
1191   * @brief  Clears the SPIx CRC Error (CRCERR) flag.
1192   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1193   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1194   * @param  SPI_I2S_FLAG: specifies the SPI flag to clear.
1195   *          This function clears only CRCERR flag.
1196   *            @arg SPI_FLAG_CRCERR: CRC Error flag.
1197   *
1198   * @note   OVR (OverRun error) flag is cleared by software sequence: a read
1199   *          operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read
1200   *          operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
1201   * @note   UDR (UnderRun error) flag is cleared by a read operation to
1202   *          SPI_SR register (SPI_I2S_GetFlagStatus()).
1203   * @note   MODF (Mode Fault) flag is cleared by software sequence: a read/write
1204   *          operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a
1205   *          write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
1206   *
1207   * @retval None
1208   */
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1209 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1210 {
1211   /* Check the parameters */
1212   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1213   assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));
1214 
1215   /* Clear the selected SPI CRC Error (CRCERR) flag */
1216   SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
1217 }
1218 
1219 /**
1220   * @brief  Checks whether the specified SPIx/I2Sx interrupt has occurred or not.
1221   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1222   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1223   * @param  SPI_I2S_IT: specifies the SPI interrupt source to check.
1224   *          This parameter can be one of the following values:
1225   *            @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
1226   *            @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
1227   *            @arg SPI_I2S_IT_OVR: Overrun interrupt.
1228   *            @arg SPI_IT_MODF: Mode Fault interrupt.
1229   *            @arg SPI_IT_CRCERR: CRC Error interrupt.
1230   *            @arg I2S_IT_UDR: Underrun interrupt.
1231   *            @arg SPI_I2S_IT_TIFRFE: Format Error interrupt.
1232   * @retval The new state of SPI_I2S_IT (SET or RESET).
1233   */
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)1234 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1235 {
1236   ITStatus bitstatus = RESET;
1237   uint16_t itpos = 0, itmask = 0, enablestatus = 0;
1238 
1239   /* Check the parameters */
1240   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1241   assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
1242 
1243   /* Get the SPI_I2S_IT index */
1244   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1245 
1246   /* Get the SPI_I2S_IT IT mask */
1247   itmask = SPI_I2S_IT >> 4;
1248 
1249   /* Set the IT mask */
1250   itmask = 0x01 << itmask;
1251 
1252   /* Get the SPI_I2S_IT enable bit status */
1253   enablestatus = (SPIx->CR2 & itmask) ;
1254 
1255   /* Check the status of the specified SPI interrupt */
1256   if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
1257   {
1258     /* SPI_I2S_IT is set */
1259     bitstatus = SET;
1260   }
1261   else
1262   {
1263     /* SPI_I2S_IT is reset */
1264     bitstatus = RESET;
1265   }
1266   /* Return the SPI_I2S_IT status */
1267   return bitstatus;
1268 }
1269 
1270 /**
1271   * @brief  Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
1272   * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2, 3, 4, 5 or 6
1273   *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
1274   * @param  SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.
1275   *         This function clears only CRCERR interrupt pending bit.
1276   *            @arg SPI_IT_CRCERR: CRC Error interrupt.
1277   *
1278   * @note   OVR (OverRun Error) interrupt pending bit is cleared by software
1279   *          sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData())
1280   *          followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()).
1281   * @note   UDR (UnderRun Error) interrupt pending bit is cleared by a read
1282   *          operation to SPI_SR register (SPI_I2S_GetITStatus()).
1283   * @note   MODF (Mode Fault) interrupt pending bit is cleared by software sequence:
1284   *          a read/write operation to SPI_SR register (SPI_I2S_GetITStatus())
1285   *          followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable
1286   *          the SPI).
1287   * @retval None
1288   */
SPI_I2S_ClearITPendingBit(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)1289 void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1290 {
1291   uint16_t itpos = 0;
1292   /* Check the parameters */
1293   assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
1294   assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));
1295 
1296   /* Get the SPI_I2S IT index */
1297   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1298 
1299   /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */
1300   SPIx->SR = (uint16_t)~itpos;
1301 }
1302 
1303 /**
1304   * @}
1305   */
1306 
1307 /**
1308   * @}
1309   */
1310 
1311 /**
1312   * @}
1313   */
1314 
1315 /**
1316   * @}
1317   */
1318 
1319 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1320