1 /**
2   ******************************************************************************
3   * @file    stm32f37x_spi.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    20-September-2012
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 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE)
22             function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE)
23             function for SPI2 or using RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE)
24             for SPI3.
25 
26         (#) Enable SCK, MOSI, MISO and NSS GPIO clocks using
27             RCC_AHBPeriphClockCmd() function.
28 
29         (#) Peripherals alternate function:
30            (++) Connect the pin to the desired peripherals' Alternate
31                  Function (AF) using GPIO_PinAFConfig() function.
32            (++) Configure the desired pin in alternate function by:
33                  GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF.
34            (++) Select the type, pull-up/pull-down and output speed via
35                  GPIO_PuPd, GPIO_OType and GPIO_Speed members.
36            (++) Call GPIO_Init() function.
37 
38         (#) Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave
39             Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
40             function.In I2S mode, program the Mode, Standard, Data Format, MCLK
41             Output, Audio frequency and Polarity using I2S_Init() function.
42 
43         (#) Configure the FIFO threshold using SPI_RxFIFOThresholdConfig() to select
44             at which threshold the RXNE event is generated.
45 
46         (#) Enable the NVIC and the corresponding interrupt using the function
47             SPI_ITConfig() if you need to use interrupt mode.
48 
49         (#) When using the DMA mode
50            (++) Configure the DMA using DMA_Init() function.
51            (++) Active the needed channel Request using SPI_I2S_DMACmd() function.
52 
53         (#) Enable the SPI using the SPI_Cmd() function or enable the I2S using
54             I2S_Cmd().
55 
56         (#) Enable the DMA using the DMA_Cmd() function when using DMA mode.
57 
58         (#) Optionally, you can enable/configure the following parameters without
59             re-initialization (i.e there is no need to call again SPI_Init() function):
60            (++) When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx)
61                  is programmed as Data direction parameter using the SPI_Init()
62                  function it can be possible to switch between SPI_Direction_Tx
63                  or SPI_Direction_Rx using the SPI_BiDirectionalLineConfig() function.
64            (++) When SPI_NSS_Soft is selected as Slave Select Management parameter
65                  using the SPI_Init() function it can be possible to manage the
66                  NSS internal signal using the SPI_NSSInternalSoftwareConfig() function.
67            (++) Reconfigure the data size using the SPI_DataSizeConfig() function.
68            (++) Enable or disable the SS output using the SPI_SSOutputCmd() function.
69 
70         (#) To use the CRC Hardware calculation feature refer to the Peripheral
71             CRC hardware Calculation subsection.
72 
73     @endverbatim
74   ******************************************************************************
75   * @attention
76   *
77   * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
78   *
79   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
80   * You may not use this file except in compliance with the License.
81   * You may obtain a copy of the License at:
82   *
83   *        http://www.st.com/software_license_agreement_liberty_v2
84   *
85   * Unless required by applicable law or agreed to in writing, software
86   * distributed under the License is distributed on an "AS IS" BASIS,
87   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88   * See the License for the specific language governing permissions and
89   * limitations under the License.
90   *
91   ******************************************************************************
92   */
93 
94 /* Includes ------------------------------------------------------------------*/
95 #include "stm32f37x_spi.h"
96 #include "stm32f37x_rcc.h"
97 
98 /** @addtogroup STM32F37x_StdPeriph_Driver
99   * @{
100   */
101 
102 /** @defgroup SPI
103   * @brief SPI driver modules
104   * @{
105   */
106 
107 /* Private typedef -----------------------------------------------------------*/
108 /* Private define ------------------------------------------------------------*/
109 /* SPI registers Masks */
110 #define CR1_CLEAR_MASK       ((uint16_t)0x3040)
111 #define CR1_CLEAR_MASK2      ((uint16_t)0xFFFB)
112 #define CR2_LDMA_MASK        ((uint16_t)0x9FFF)
113 
114 #define I2SCFGR_CLEAR_Mask   ((uint16_t)0xF040)
115 
116 /* Private macro -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /* Private functions ---------------------------------------------------------*/
120 
121 /** @defgroup SPI_Private_Functions
122   * @{
123   */
124 
125 /** @defgroup SPI_Group1 Initialization and Configuration functions
126  *  @brief   Initialization and Configuration functions
127  *
128 @verbatim
129  ===============================================================================
130            ##### Initialization and Configuration functions #####
131  ===============================================================================
132     [..] This section provides a set of functions allowing to initialize the SPI Direction,
133          SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud
134          Rate Prescaler, SPI First Bit and SPI CRC Polynomial.
135 
136     [..] The SPI_Init() function follows the SPI configuration procedures for Master mode
137          and Slave mode (details for these procedures are available in reference manual).
138 
139     [..] When the Software NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Soft) is selected,
140          use the following function to manage the NSS bit:
141          void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
142 
143     [..] In Master mode, when the Hardware NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Hard)
144          is selected, use the follwoing function to enable the NSS output feature.
145          void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
146 
147     [..] The NSS pulse mode can be managed by the SPI TI mode when enabling it using the following function:
148          void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
149          And it can be managed by software in the SPI Motorola mode using this function:
150          void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
151 
152     [..] This section provides also functions to initialize the I2S Mode, Standard,
153          Data Format, MCLK Output, Audio frequency and Polarity.
154 
155     [..] The I2S_Init() function follows the I2S configuration procedures for Master mode
156          and Slave mode.
157 
158 @endverbatim
159   * @{
160   */
161 
162 /**
163   * @brief  Deinitializes the SPIx peripheral registers to their default
164   *         reset values.
165   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
166   * @retval None
167   */
SPI_I2S_DeInit(SPI_TypeDef * SPIx)168 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
169 {
170   /* Check the parameters */
171   assert_param(IS_SPI_ALL_PERIPH(SPIx));
172 
173   if (SPIx == SPI1)
174   {
175     /* Enable SPI1 reset state */
176     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
177     /* Release SPI1 from reset state */
178     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
179   }
180   else if (SPIx == SPI2)
181   {
182     /* Enable SPI2 reset state */
183     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
184     /* Release SPI2 from reset state */
185     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
186   }
187   else
188   {
189     if (SPIx == SPI3)
190     {
191       /* Enable SPI3 reset state */
192       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
193       /* Release SPI3 from reset state */
194       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
195     }
196   }
197 }
198 
199 /**
200   * @brief  Fills each SPI_InitStruct member with its default value.
201   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
202   * @retval None
203   */
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)204 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
205 {
206 /*--------------- Reset SPI init structure parameters values -----------------*/
207   /* Initialize the SPI_Direction member */
208   SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
209   /* Initialize the SPI_Mode member */
210   SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
211   /* Initialize the SPI_DataSize member */
212   SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
213   /* Initialize the SPI_CPOL member */
214   SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
215   /* Initialize the SPI_CPHA member */
216   SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
217   /* Initialize the SPI_NSS member */
218   SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
219   /* Initialize the SPI_BaudRatePrescaler member */
220   SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
221   /* Initialize the SPI_FirstBit member */
222   SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
223   /* Initialize the SPI_CRCPolynomial member */
224   SPI_InitStruct->SPI_CRCPolynomial = 7;
225 }
226 
227 /**
228   * @brief  Initializes the SPIx peripheral according to the specified
229   *         parameters in the SPI_InitStruct.
230   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
231   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
232   *         contains the configuration information for the specified SPI peripheral.
233   * @retval None
234   */
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)235 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
236 {
237   uint16_t tmpreg = 0;
238 
239   /* check the parameters */
240   assert_param(IS_SPI_ALL_PERIPH(SPIx));
241 
242   /* Check the SPI parameters */
243   assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
244   assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
245   assert_param(IS_SPI_DATA_SIZE(SPI_InitStruct->SPI_DataSize));
246   assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
247   assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
248   assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
249   assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
250   assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
251   assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
252 
253   /*---------------------------- SPIx CR1 Configuration ------------------------*/
254   /* Get the SPIx CR1 value */
255   tmpreg = SPIx->CR1;
256   /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, CPOL and CPHA bits */
257   tmpreg &= CR1_CLEAR_MASK;
258   /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
259   master/slave mode, CPOL and CPHA */
260   /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
261   /* Set SSM, SSI bit according to SPI_NSS values */
262   /* Set LSBFirst bit according to SPI_FirstBit value */
263   /* Set BR bits according to SPI_BaudRatePrescaler value */
264   /* Set CPOL bit according to SPI_CPOL value */
265   /* Set CPHA bit according to SPI_CPHA value */
266   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_FirstBit |
267                       SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA |
268                       SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler);
269   /* Write to SPIx CR1 */
270   SPIx->CR1 = tmpreg;
271   /*-------------------------Data Size Configuration -----------------------*/
272   /* Get the SPIx CR2 value */
273   tmpreg = SPIx->CR2;
274   /* Clear DS[3:0] bits */
275   tmpreg &=(uint16_t)~SPI_CR2_DS;
276   /* Configure SPIx: Data Size */
277   tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize);
278   /* Write to SPIx CR2 */
279   SPIx->CR2 = tmpreg;
280 
281   /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
282   /* Write to SPIx CRCPOLY */
283   SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
284 
285   /*---------------------------- SPIx CR1 Configuration ------------------------*/
286   /* Get the SPIx CR1 value */
287   tmpreg = SPIx->CR1;
288   /* Clear MSTR bit */
289   tmpreg &= CR1_CLEAR_MASK2;
290   /* Configure SPIx: master/slave mode */
291   /* Set MSTR bit according to SPI_Mode */
292   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode);
293   /* Write to SPIx CR1 */
294   SPIx->CR1 = tmpreg;
295 
296   /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
297   SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
298 }
299 
300 /**
301   * @brief  Fills each I2S_InitStruct member with its default value.
302   * @param  I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
303   * @retval None
304   */
I2S_StructInit(I2S_InitTypeDef * I2S_InitStruct)305 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
306 {
307 /*--------------- Reset I2S init structure parameters values -----------------*/
308   /* Initialize the I2S_Mode member */
309   I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
310 
311   /* Initialize the I2S_Standard member */
312   I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
313 
314   /* Initialize the I2S_DataFormat member */
315   I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
316 
317   /* Initialize the I2S_MCLKOutput member */
318   I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
319 
320   /* Initialize the I2S_AudioFreq member */
321   I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
322 
323   /* Initialize the I2S_CPOL member */
324   I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
325 }
326 
327 /**
328   * @brief  Initializes the SPIx peripheral according to the specified
329   *         parameters in the I2S_InitStruct.
330   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
331   * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
332   *         contains the configuration information for the specified SPI peripheral
333   *         configured in I2S mode.
334   * @note   This function calculates the optimal prescaler needed to obtain the most
335   *         accurate audio frequency (depending on the I2S clock source, the PLL values
336   *         and the product configuration). But in case the prescaler value is greater
337   *         than 511, the default value (0x02) will be configured instead.
338   * @retval None
339   */
I2S_Init(SPI_TypeDef * SPIx,I2S_InitTypeDef * I2S_InitStruct)340 void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
341 {
342   uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
343   uint32_t tmp = 0;
344   RCC_ClocksTypeDef RCC_Clocks;
345   uint32_t sourceclock = 0;
346 
347   /* Check the I2S parameters */
348   assert_param(IS_SPI_ALL_PERIPH(SPIx));
349   assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
350   assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
351   assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
352   assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
353   assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
354   assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
355 
356 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
357   /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
358   SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
359   SPIx->I2SPR = 0x0002;
360 
361   /* Get the I2SCFGR register value */
362   tmpreg = SPIx->I2SCFGR;
363 
364   /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
365   if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
366   {
367     i2sodd = (uint16_t)0;
368     i2sdiv = (uint16_t)2;
369   }
370   /* If the requested audio frequency is not the default, compute the prescaler */
371   else
372   {
373     /* Check the frame length (For the Prescaler computing) */
374     if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
375     {
376       /* Packet length is 16 bits */
377       packetlength = 1;
378     }
379     else
380     {
381       /* Packet length is 32 bits */
382       packetlength = 2;
383     }
384 
385     /* I2S Clock source is System clock: Get System Clock frequency */
386     RCC_GetClocksFreq(&RCC_Clocks);
387 
388     /* Get the source clock value: based on System Clock value */
389     sourceclock = RCC_Clocks.SYSCLK_Frequency;
390 
391     /* Compute the Real divider depending on the MCLK output state with a floating point */
392     if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
393     {
394       /* MCLK output is enabled */
395       tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
396     }
397     else
398     {
399       /* MCLK output is disabled */
400       tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
401     }
402 
403     /* Remove the floating point */
404     tmp = tmp / 10;
405 
406     /* Check the parity of the divider */
407     i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
408 
409     /* Compute the i2sdiv prescaler */
410     i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
411 
412     /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
413     i2sodd = (uint16_t) (i2sodd << 8);
414   }
415 
416   /* Test if the divider is 1 or 0 or greater than 0xFF */
417   if ((i2sdiv < 2) || (i2sdiv > 0xFF))
418   {
419     /* Set the default values */
420     i2sdiv = 2;
421     i2sodd = 0;
422   }
423 
424   /* Write to SPIx I2SPR register the computed value */
425   SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
426 
427   /* Configure the I2S with the SPI_InitStruct values */
428   tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
429                   (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
430                   (uint16_t)I2S_InitStruct->I2S_CPOL))));
431 
432   /* Write to SPIx I2SCFGR */
433   SPIx->I2SCFGR = tmpreg;
434 }
435 
436 /**
437   * @brief  Enables or disables the specified SPI peripheral.
438   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
439   * @param  NewState: new state of the SPIx peripheral.
440   *          This parameter can be: ENABLE or DISABLE.
441   * @retval None
442   */
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)443 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
444 {
445   /* Check the parameters */
446   assert_param(IS_SPI_ALL_PERIPH(SPIx));
447   assert_param(IS_FUNCTIONAL_STATE(NewState));
448 
449   if (NewState != DISABLE)
450   {
451     /* Enable the selected SPI peripheral */
452     SPIx->CR1 |= SPI_CR1_SPE;
453   }
454   else
455   {
456     /* Disable the selected SPI peripheral */
457     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
458   }
459 }
460 
461 /**
462   * @brief  Enables or disables the TI Mode.
463   *
464   * @note   This function can be called only after the SPI_Init() function has
465   *         been called.
466   * @note   When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
467   *         are not taken into consideration and are configured by hardware
468   *         respectively to the TI mode requirements.
469   *
470   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
471   * @param  NewState: new state of the selected SPI TI communication mode.
472   *          This parameter can be: ENABLE or DISABLE.
473   * @retval None
474   */
SPI_TIModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)475 void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
476 {
477   /* Check the parameters */
478   assert_param(IS_SPI_ALL_PERIPH(SPIx));
479   assert_param(IS_FUNCTIONAL_STATE(NewState));
480 
481   if (NewState != DISABLE)
482   {
483     /* Enable the TI mode for the selected SPI peripheral */
484     SPIx->CR2 |= SPI_CR2_FRF;
485   }
486   else
487   {
488     /* Disable the TI mode for the selected SPI peripheral */
489     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF);
490   }
491 }
492 
493 /**
494   * @brief  Enables or disables the specified SPI peripheral (in I2S mode).
495   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
496   * @param  NewState: new state of the SPIx peripheral.
497   *          This parameter can be: ENABLE or DISABLE.
498   * @retval None
499   */
I2S_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)500 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
501 {
502   /* Check the parameters */
503   assert_param(IS_SPI_ALL_PERIPH(SPIx));
504   assert_param(IS_FUNCTIONAL_STATE(NewState));
505   if (NewState != DISABLE)
506   {
507     /* Enable the selected SPI peripheral in I2S mode */
508     SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
509   }
510   else
511   {
512     /* Disable the selected SPI peripheral in I2S mode */
513     SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
514   }
515 }
516 
517 /**
518   * @brief  Configures the data size for the selected SPI.
519   * @param  SPIx: where x can be 1, 2 or 3  to select the SPI peripheral.
520   * @param  SPI_DataSize: specifies the SPI data size.
521   *         For the SPIx peripheral this parameter can be one of the following values:
522   *            @arg SPI_DataSize_4b: Set data size to 4 bits
523   *            @arg SPI_DataSize_5b: Set data size to 5 bits
524   *            @arg SPI_DataSize_6b: Set data size to 6 bits
525   *            @arg SPI_DataSize_7b: Set data size to 7 bits
526   *            @arg SPI_DataSize_8b: Set data size to 8 bits
527   *            @arg SPI_DataSize_9b: Set data size to 9 bits
528   *            @arg SPI_DataSize_10b: Set data size to 10 bits
529   *            @arg SPI_DataSize_11b: Set data size to 11 bits
530   *            @arg SPI_DataSize_12b: Set data size to 12 bits
531   *            @arg SPI_DataSize_13b: Set data size to 13 bits
532   *            @arg SPI_DataSize_14b: Set data size to 14 bits
533   *            @arg SPI_DataSize_15b: Set data size to 15 bits
534   *            @arg SPI_DataSize_16b: Set data size to 16 bits
535   * @retval None
536   */
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)537 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
538 {
539   uint16_t tmpreg = 0;
540 
541   /* Check the parameters */
542   assert_param(IS_SPI_ALL_PERIPH(SPIx));
543   assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
544   /* Read the CR2 register */
545   tmpreg = SPIx->CR2;
546   /* Clear DS[3:0] bits */
547   tmpreg &= (uint16_t)~SPI_CR2_DS;
548   /* Set new DS[3:0] bits value */
549   tmpreg |= SPI_DataSize;
550   SPIx->CR2 = tmpreg;
551 }
552 
553 /**
554   * @brief  Configures the FIFO reception threshold for the selected SPI.
555   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
556   * @param  SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
557   *          This parameter can be one of the following values:
558   *            @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
559   *                                         level is greater or equal to 1/2.
560   *            @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
561   *                                         level is greater or equal to 1/4.
562   * @retval None
563   */
SPI_RxFIFOThresholdConfig(SPI_TypeDef * SPIx,uint16_t SPI_RxFIFOThreshold)564 void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
565 {
566   /* Check the parameters */
567   assert_param(IS_SPI_ALL_PERIPH(SPIx));
568   assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
569 
570   /* Clear FRXTH bit */
571   SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
572 
573   /* Set new FRXTH bit value */
574   SPIx->CR2 |= SPI_RxFIFOThreshold;
575 }
576 
577 /**
578   * @brief  Selects the data transfer direction in bidirectional mode for the specified SPI.
579   * @param  SPIx: where x can be 1, 2 or 3  to select the SPI peripheral.
580   * @param  SPI_Direction: specifies the data transfer direction in bidirectional mode.
581   *          This parameter can be one of the following values:
582   *            @arg SPI_Direction_Tx: Selects Tx transmission direction
583   *            @arg SPI_Direction_Rx: Selects Rx receive direction
584   * @retval None
585   */
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)586 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
587 {
588   /* Check the parameters */
589   assert_param(IS_SPI_ALL_PERIPH(SPIx));
590   assert_param(IS_SPI_DIRECTION(SPI_Direction));
591   if (SPI_Direction == SPI_Direction_Tx)
592   {
593     /* Set the Tx only mode */
594     SPIx->CR1 |= SPI_Direction_Tx;
595   }
596   else
597   {
598     /* Set the Rx only mode */
599     SPIx->CR1 &= SPI_Direction_Rx;
600   }
601 }
602 
603 /**
604   * @brief  Configures internally by software the NSS pin for the selected SPI.
605   * @note   This function can be called only after the SPI_Init() function has
606   *         been called.
607   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
608   * @param  SPI_NSSInternalSoft: specifies the SPI NSS internal state.
609   *          This parameter can be one of the following values:
610   *            @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
611   *            @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
612   * @retval None
613   */
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)614 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
615 {
616   /* Check the parameters */
617   assert_param(IS_SPI_ALL_PERIPH(SPIx));
618   assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
619 
620   if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
621   {
622     /* Set NSS pin internally by software */
623     SPIx->CR1 |= SPI_NSSInternalSoft_Set;
624   }
625   else
626   {
627     /* Reset NSS pin internally by software */
628     SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
629   }
630 }
631 
632 /**
633   * @brief  Enables or disables the SS output for the selected SPI.
634   * @note   This function can be called only after the SPI_Init() function has
635   *         been called and the NSS hardware management mode is selected.
636   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
637   * @param  NewState: new state of the SPIx SS output.
638   *          This parameter can be: ENABLE or DISABLE.
639   * @retval None
640   */
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)641 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
642 {
643   /* Check the parameters */
644   assert_param(IS_SPI_ALL_PERIPH(SPIx));
645   assert_param(IS_FUNCTIONAL_STATE(NewState));
646   if (NewState != DISABLE)
647   {
648     /* Enable the selected SPI SS output */
649     SPIx->CR2 |= SPI_CR2_SSOE;
650   }
651   else
652   {
653     /* Disable the selected SPI SS output */
654     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
655   }
656 }
657 
658 /**
659   * @brief  Enables or disables the NSS pulse management mode.
660   * @note   This function can be called only after the SPI_Init() function has
661   *         been called.
662   * @note   When TI mode is selected, the control bits NSSP is not taken into
663   *         consideration and are configured by hardware respectively to the
664   *         TI mode requirements.
665   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
666   * @param  NewState: new state of the NSS pulse management mode.
667   *          This parameter can be: ENABLE or DISABLE.
668   * @retval None
669   */
SPI_NSSPulseModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)670 void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
671 {
672   /* Check the parameters */
673   assert_param(IS_SPI_ALL_PERIPH(SPIx));
674   assert_param(IS_FUNCTIONAL_STATE(NewState));
675 
676   if (NewState != DISABLE)
677   {
678     /* Enable the NSS pulse management mode */
679     SPIx->CR2 |= SPI_CR2_NSSP;
680   }
681   else
682   {
683     /* Disable the NSS pulse management mode */
684     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP);
685   }
686 }
687 
688 /**
689   * @}
690   */
691 
692 /** @defgroup SPI_Group2 Data transfers functions
693  *  @brief   Data transfers functions
694  *
695 @verbatim
696  ===============================================================================
697                     ##### Data transfers functions #####
698  ===============================================================================
699     [..] This section provides a set of functions allowing to manage the SPI or I2S
700          data transfers.
701 
702     [..] In reception, data are received and then stored into an internal Rx buffer while
703          In transmission, data are first stored into an internal Tx buffer before being
704          transmitted.
705 
706     [..] The read access of the SPI_DR register can be done using
707          SPI_ReceiveData8() (when data size is equal or inferior than 8bits) and.
708          SPI_I2S_ReceiveData16() (when data size is superior than 8bits)function
709          and returns the Rx buffered value. Whereas a write access to the SPI_DR
710          can be done using SPI_SendData8() (when data size is equal or inferior than 8bits)
711          and SPI_I2S_SendData16() (when data size is superior than 8bits) function
712          and stores the written data into Tx buffer.
713 
714 @endverbatim
715   * @{
716   */
717 
718 /**
719   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
720   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
721   * @param  Data: Data to be transmitted.
722   * @retval None
723   */
SPI_SendData8(SPI_TypeDef * SPIx,uint8_t Data)724 void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
725 {
726   uint32_t spixbase = 0x00;
727 
728   /* Check the parameters */
729   assert_param(IS_SPI_ALL_PERIPH(SPIx));
730 
731   spixbase = (uint32_t)SPIx;
732   spixbase += 0x0C;
733 
734   *(__IO uint8_t *) spixbase = Data;
735 }
736 
737 /**
738   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
739   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
740   * @param  Data: Data to be transmitted.
741   * @retval None
742   */
SPI_I2S_SendData16(SPI_TypeDef * SPIx,uint16_t Data)743 void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
744 {
745   /* Check the parameters */
746   assert_param(IS_SPI_ALL_PERIPH(SPIx));
747 
748   SPIx->DR = (uint16_t)Data;
749 }
750 
751 /**
752   * @brief  Returns the most recent received data by the SPIx/I2Sx peripheral.
753   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
754   * @retval The value of the received data.
755   */
SPI_ReceiveData8(SPI_TypeDef * SPIx)756 uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx)
757 {
758   uint32_t spixbase = 0x00;
759 
760   spixbase = (uint32_t)SPIx;
761   spixbase += 0x0C;
762 
763   return *(__IO uint8_t *) spixbase;
764 }
765 
766 /**
767   * @brief  Returns the most recent received data by the SPIx peripheral.
768   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
769   * @retval The value of the received data.
770   */
SPI_I2S_ReceiveData16(SPI_TypeDef * SPIx)771 uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx)
772 {
773   return SPIx->DR;
774 }
775 /**
776   * @}
777   */
778 
779 /** @defgroup SPI_Group3 Hardware CRC Calculation functions
780  *  @brief   Hardware CRC Calculation functions
781  *
782 @verbatim
783  ===============================================================================
784                 ##### Hardware CRC Calculation functions #####
785  ===============================================================================
786     [..] This section provides a set of functions allowing to manage the SPI CRC hardware
787          calculation.SPI communication using CRC is possible through the following procedure:
788 
789          (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
790              Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
791              function.
792          (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
793          (#) Enable the SPI using the SPI_Cmd() function
794          (#) Before writing the last data to the TX buffer, set the CRCNext bit using the
795              SPI_TransmitCRC() function to indicate that after transmission of the last
796              data, the CRC should be transmitted.
797          (#) After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
798              bit is reset. The CRC is also received and compared against the SPI_RXCRCR
799              value.
800              If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
801              can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
802 
803     -@-
804        (+@) It is advised to don't read the calculate CRC values during the communication.
805        (+@) When the SPI is in slave mode, be careful to enable CRC calculation only
806        when the clock is stable, that is, when the clock is in the steady state.
807        If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive
808        to the SCK slave input clock as soon as CRCEN is set, and this, whatever
809        the value of the SPE bit.
810        (+@) With high bitrate frequencies, be careful when transmitting the CRC.
811        As the number of used CPU cycles has to be as low as possible in the CRC
812        transfer phase, it is forbidden to call software functions in the CRC
813        transmission sequence to avoid errors in the last data and CRC reception.
814        In fact, CRCNEXT bit has to be written before the end of the transmission/reception
815        of the last data.
816        (+@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the
817        degradation of the SPI speed performance due to CPU accesses impacting the
818        SPI bandwidth.
819        (+@) When the STM32F37x are configured as slaves and the NSS hardware mode is
820        used, the NSS pin needs to be kept low between the data phase and the CRC
821        phase.
822        (+@) When the SPI is configured in slave mode with the CRC feature enabled, CRC
823        calculation takes place even if a high level is applied on the NSS pin.
824        This may happen for example in case of a multislave environment where the
825        communication master addresses slaves alternately.
826        (+@) Between a slave deselection (high level on NSS) and a new slave selection
827        (low level on NSS), the CRC value should be cleared on both master and slave
828        sides in order to resynchronize the master and slave for their respective
829        CRC calculation.
830 
831     -@- To clear the CRC, follow the procedure below:
832        (#@) Disable SPI using the SPI_Cmd() function
833        (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
834        (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
835        (#@) Enable SPI using the SPI_Cmd() function.
836 
837 @endverbatim
838   * @{
839   */
840 
841 /**
842   * @brief  Configures the CRC calculation length for the selected SPI.
843   * @note   This function can be called only after the SPI_Init() function has
844   *         been called.
845   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
846   * @param  SPI_CRCLength: specifies the SPI CRC calculation length.
847   *          This parameter can be one of the following values:
848   *            @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits
849   *            @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits
850   * @retval None
851   */
SPI_CRCLengthConfig(SPI_TypeDef * SPIx,uint16_t SPI_CRCLength)852 void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength)
853 {
854   /* Check the parameters */
855   assert_param(IS_SPI_ALL_PERIPH(SPIx));
856   assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength));
857 
858   /* Clear CRCL bit */
859   SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL);
860 
861   /* Set new CRCL bit value */
862   SPIx->CR1 |= SPI_CRCLength;
863 }
864 
865 /**
866   * @brief  Enables or disables the CRC value calculation of the transferred bytes.
867   * @note   This function can be called only after the SPI_Init() function has
868   *         been called.
869   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral..
870   * @param  NewState: new state of the SPIx CRC value calculation.
871   *          This parameter can be: ENABLE or DISABLE.
872   * @retval None
873   */
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)874 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
875 {
876   /* Check the parameters */
877   assert_param(IS_SPI_ALL_PERIPH(SPIx));
878   assert_param(IS_FUNCTIONAL_STATE(NewState));
879 
880   if (NewState != DISABLE)
881   {
882     /* Enable the selected SPI CRC calculation */
883     SPIx->CR1 |= SPI_CR1_CRCEN;
884   }
885   else
886   {
887     /* Disable the selected SPI CRC calculation */
888     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
889   }
890 }
891 
892 /**
893   * @brief  Transmit the SPIx CRC value.
894   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
895   * @retval None
896   */
SPI_TransmitCRC(SPI_TypeDef * SPIx)897 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
898 {
899   /* Check the parameters */
900   assert_param(IS_SPI_ALL_PERIPH(SPIx));
901 
902   /* Enable the selected SPI CRC transmission */
903   SPIx->CR1 |= SPI_CR1_CRCNEXT;
904 }
905 
906 /**
907   * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
908   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
909   * @param  SPI_CRC: specifies the CRC register to be read.
910   *          This parameter can be one of the following values:
911   *            @arg SPI_CRC_Tx: Selects Tx CRC register
912   *            @arg SPI_CRC_Rx: Selects Rx CRC register
913   * @retval The selected CRC register value..
914   */
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)915 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
916 {
917   uint16_t crcreg = 0;
918   /* Check the parameters */
919   assert_param(IS_SPI_ALL_PERIPH(SPIx));
920   assert_param(IS_SPI_CRC(SPI_CRC));
921 
922   if (SPI_CRC != SPI_CRC_Rx)
923   {
924     /* Get the Tx CRC register */
925     crcreg = SPIx->TXCRCR;
926   }
927   else
928   {
929     /* Get the Rx CRC register */
930     crcreg = SPIx->RXCRCR;
931   }
932   /* Return the selected CRC register */
933   return crcreg;
934 }
935 
936 /**
937   * @brief  Returns the CRC Polynomial register value for the specified SPI.
938   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
939   * @retval The CRC Polynomial register value.
940   */
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)941 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
942 {
943   /* Check the parameters */
944   assert_param(IS_SPI_ALL_PERIPH(SPIx));
945 
946   /* Return the CRC polynomial register */
947   return SPIx->CRCPR;
948 }
949 
950 /**
951   * @}
952   */
953 
954 /** @defgroup SPI_Group4 DMA transfers management functions
955  *  @brief   DMA transfers management functions
956   *
957 @verbatim
958  ===============================================================================
959                 ##### DMA transfers management functions #####
960  ===============================================================================
961     [..] This section provides two functions that can be used only in DMA mode.
962 
963 @endverbatim
964   * @{
965   */
966 
967 /**
968   * @brief  Enables or disables the SPIx/I2Sx DMA interface.
969   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
970   * @param  SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled.
971   *          This parameter can be any combination of the following values:
972   *            @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
973   *            @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
974   * @param  NewState: new state of the selected SPI DMA transfer request.
975   *          This parameter can be: ENABLE or DISABLE.
976   * @retval None
977   */
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)978 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
979 {
980   /* Check the parameters */
981   assert_param(IS_SPI_ALL_PERIPH(SPIx));
982   assert_param(IS_FUNCTIONAL_STATE(NewState));
983   assert_param(IS_SPI_I2S_DMA_REQ(SPI_I2S_DMAReq));
984 
985   if (NewState != DISABLE)
986   {
987     /* Enable the selected SPI DMA requests */
988     SPIx->CR2 |= SPI_I2S_DMAReq;
989   }
990   else
991   {
992     /* Disable the selected SPI DMA requests */
993     SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
994   }
995 }
996 
997 /**
998   * @brief  Configures the number of data to transfer type(Even/Odd) for the DMA
999   *         last transfers and for the selected SPI.
1000   * @note   This function have a meaning only if DMA mode is selected and if
1001   *         the packing mode is used (data length <= 8 and DMA transfer size halfword)
1002   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1003   * @param  SPI_LastDMATransfer: specifies the SPI last DMA transfers state.
1004   *          This parameter can be one of the following values:
1005   *            @arg SPI_LastDMATransfer_TxEvenRxEven: Number of data for transmission Even
1006   *                                                   and number of data for reception Even.
1007   *            @arg SPI_LastDMATransfer_TxOddRxEven: Number of data for transmission Odd
1008   *                                                  and number of data for reception Even.
1009   *            @arg SPI_LastDMATransfer_TxEvenRxOdd: Number of data for transmission Even
1010   *                                                  and number of data for reception Odd.
1011   *            @arg SPI_LastDMATransfer_TxOddRxOdd: Number of data for transmission Odd
1012   *                                                 and number of data for reception Odd.
1013   * @retval None
1014   */
SPI_LastDMATransferCmd(SPI_TypeDef * SPIx,uint16_t SPI_LastDMATransfer)1015 void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer)
1016 {
1017   /* Check the parameters */
1018   assert_param(IS_SPI_ALL_PERIPH(SPIx));
1019   assert_param(IS_SPI_LAST_DMA_TRANSFER(SPI_LastDMATransfer));
1020 
1021   /* Clear LDMA_TX and LDMA_RX bits */
1022   SPIx->CR2 &= CR2_LDMA_MASK;
1023 
1024   /* Set new LDMA_TX and LDMA_RX bits value */
1025   SPIx->CR2 |= SPI_LastDMATransfer;
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     [..] This section provides a set of functions allowing to configure the SPI/I2S Interrupts
1040          sources and check or clear the flags or pending bits status.
1041          The user should identify which mode will be used in his application to manage
1042          the communication: Polling mode, Interrupt mode or DMA mode.
1043 
1044   *** Polling Mode ***
1045   ====================
1046     [..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
1047         (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
1048         (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
1049         (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
1050         (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
1051         (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
1052         (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
1053         (#) SPI_I2S_FLAG_FRE: to indicate a Frame Format error occurs.
1054         (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
1055         (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
1056 
1057     [..]
1058         (@)Do not use the BSY flag to handle each data transmission or reception. It is better
1059            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/I2S communication can be managed by 3 interrupt sources
1068          and 5 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_I2S_IT_OVR : to indicate if an Overrun error occur
1073         (#) I2S_IT_UDR : to indicate an Underrun Error occurs.
1074         (#) SPI_I2S_FLAG_FRE : to indicate a Frame Format error occurs.
1075 
1076     [..] Interrupt Source:
1077         (#) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
1078             interrupt.
1079         (#) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
1080             empty interrupt.
1081         (#) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
1082 
1083     [..] In this Mode it is advised to use the following functions:
1084          (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
1085          (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1086 
1087   *** FIFO Status ***
1088   ===================
1089     [..] It is possible to monitor the FIFO status when a transfer is ongoing using the
1090          following function:
1091          (+) uint32_t SPI_GetFIFOStatus(uint8_t SPI_FIFO_Direction);
1092 
1093   *** DMA Mode ***
1094   ================
1095     [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel
1096          requests:
1097         (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
1098         (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request.
1099 
1100     [..] In this Mode it is advised to use the following function:
1101         (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState).
1102 
1103 @endverbatim
1104   * @{
1105   */
1106 
1107 /**
1108   * @brief  Enables or disables the specified SPI/I2S interrupts.
1109   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1110   * @param  SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
1111   *          This parameter can be one of the following values:
1112   *            @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
1113   *            @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
1114   *            @arg SPI_I2S_IT_ERR: Error interrupt mask
1115   * @param  NewState: new state of the specified SPI interrupt.
1116   *          This parameter can be: ENABLE or DISABLE.
1117   * @retval None
1118   */
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)1119 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
1120 {
1121   uint16_t itpos = 0, itmask = 0 ;
1122 
1123   /* Check the parameters */
1124   assert_param(IS_SPI_ALL_PERIPH(SPIx));
1125   assert_param(IS_FUNCTIONAL_STATE(NewState));
1126   assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
1127 
1128   /* Get the SPI IT index */
1129   itpos = SPI_I2S_IT >> 4;
1130 
1131   /* Set the IT mask */
1132   itmask = (uint16_t)1 << (uint16_t)itpos;
1133 
1134   if (NewState != DISABLE)
1135   {
1136     /* Enable the selected SPI interrupt */
1137     SPIx->CR2 |= itmask;
1138   }
1139   else
1140   {
1141     /* Disable the selected SPI interrupt */
1142     SPIx->CR2 &= (uint16_t)~itmask;
1143   }
1144 }
1145 
1146 /**
1147   * @brief  Returns the current SPIx Transmission FIFO filled level.
1148   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1149   * @retval The Transmission FIFO filling state.
1150   *          - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty
1151   *          - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
1152   *          - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full.
1153   *          - SPI_TransmissionFIFOStatus_Full: when FIFO is full.
1154   */
SPI_GetTransmissionFIFOStatus(SPI_TypeDef * SPIx)1155 uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx)
1156 {
1157   /* Get the SPIx Transmission FIFO level bits */
1158   return (uint16_t)((SPIx->SR & SPI_SR_FTLVL));
1159 }
1160 
1161 /**
1162   * @brief  Returns the current SPIx Reception FIFO filled level.
1163   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1164   * @retval The Reception FIFO filling state.
1165   *          - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty
1166   *          - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
1167   *          - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full.
1168   *          - SPI_ReceptionFIFOStatus_Full: when FIFO is full.
1169   */
SPI_GetReceptionFIFOStatus(SPI_TypeDef * SPIx)1170 uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx)
1171 {
1172   /* Get the SPIx Reception FIFO level bits */
1173   return (uint16_t)((SPIx->SR & SPI_SR_FRLVL));
1174 }
1175 
1176 /**
1177   * @brief  Checks whether the specified SPI flag is set or not.
1178   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1179   * @param  SPI_I2S_FLAG: specifies the SPI flag to check.
1180   *          This parameter can be one of the following values:
1181   *            @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
1182   *            @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
1183   *            @arg SPI_I2S_FLAG_BSY: Busy flag.
1184   *            @arg SPI_I2S_FLAG_OVR: Overrun flag.
1185   *            @arg SPI_FLAG_MODF: Mode Fault flag.
1186   *            @arg SPI_FLAG_CRCERR: CRC Error flag.
1187   *            @arg SPI_I2S_FLAG_FRE: TI frame format error flag.
1188   *            @arg I2S_FLAG_UDR: Underrun Error flag.
1189   *            @arg I2S_FLAG_CHSIDE: Channel Side flag.
1190   * @retval The new state of SPI_I2S_FLAG (SET or RESET).
1191   */
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1192 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1193 {
1194   FlagStatus bitstatus = RESET;
1195   /* Check the parameters */
1196   assert_param(IS_SPI_ALL_PERIPH(SPIx));
1197   assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
1198 
1199   /* Check the status of the specified SPI flag */
1200   if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
1201   {
1202     /* SPI_I2S_FLAG is set */
1203     bitstatus = SET;
1204   }
1205   else
1206   {
1207     /* SPI_I2S_FLAG is reset */
1208     bitstatus = RESET;
1209   }
1210   /* Return the SPI_I2S_FLAG status */
1211   return  bitstatus;
1212 }
1213 
1214 /**
1215   * @brief  Clears the SPIx CRC Error (CRCERR) flag.
1216   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1217   * @param  SPI_I2S_FLAG: specifies the SPI flag to clear.
1218   *         This function clears only CRCERR flag.
1219   * @note   OVR (OverRun error) flag is cleared by software sequence: a read
1220   *         operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by
1221   *         a read operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
1222   * @note   MODF (Mode Fault) flag is cleared by software sequence: a read/write
1223   *         operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by
1224   *         a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
1225   * @retval None
1226   */
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1227 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1228 {
1229   /* Check the parameters */
1230   assert_param(IS_SPI_ALL_PERIPH(SPIx));
1231   assert_param(IS_SPI_CLEAR_FLAG(SPI_I2S_FLAG));
1232 
1233   /* Clear the selected SPI CRC Error (CRCERR) flag */
1234   SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
1235 }
1236 
1237 /**
1238   * @brief  Checks whether the specified SPI/I2S interrupt has occurred or not.
1239   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1240   * @param  SPI_I2S_IT: specifies the SPI interrupt source to check.
1241   *          This parameter can be one of the following values:
1242   *            @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
1243   *            @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
1244   *            @arg SPI_IT_MODF: Mode Fault interrupt.
1245   *            @arg SPI_I2S_IT_OVR: Overrun interrupt.
1246   *            @arg I2S_IT_UDR: Underrun interrupt.
1247   *            @arg SPI_I2S_IT_FRE: Format Error interrupt.
1248   * @retval The new state of SPI_I2S_IT (SET or RESET).
1249   */
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)1250 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1251 {
1252   ITStatus bitstatus = RESET;
1253   uint16_t itpos = 0, itmask = 0, enablestatus = 0;
1254 
1255   /* Check the parameters */
1256   assert_param(IS_SPI_ALL_PERIPH(SPIx));
1257   assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
1258 
1259   /* Get the SPI_I2S_IT index */
1260   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1261 
1262   /* Get the SPI_I2S_IT IT mask */
1263   itmask = SPI_I2S_IT >> 4;
1264 
1265   /* Set the IT mask */
1266   itmask = 0x01 << itmask;
1267 
1268   /* Get the SPI_I2S_IT enable bit status */
1269   enablestatus = (SPIx->CR2 & itmask) ;
1270 
1271   /* Check the status of the specified SPI interrupt */
1272   if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
1273   {
1274     /* SPI_I2S_IT is set */
1275     bitstatus = SET;
1276   }
1277   else
1278   {
1279     /* SPI_I2S_IT is reset */
1280     bitstatus = RESET;
1281   }
1282   /* Return the SPI_I2S_IT status */
1283   return bitstatus;
1284 }
1285 
1286 /**
1287   * @}
1288   */
1289 
1290 /**
1291   * @}
1292   */
1293 
1294 /**
1295   * @}
1296   */
1297 
1298 /**
1299   * @}
1300   */
1301 
1302 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1303