1 /**
2   ******************************************************************************
3   * @file    stm32f10x_spi.c
4   * @author  MCD Application Team
5   * @version V3.4.0
6   * @date    10/15/2010
7   * @brief   This file provides all the SPI firmware functions.
8   ******************************************************************************
9   * @copy
10   *
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
19   */
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "stm32f10x_spi.h"
23 #include "stm32f10x_rcc.h"
24 
25 /** @addtogroup STM32F10x_StdPeriph_Driver
26   * @{
27   */
28 
29 /** @defgroup SPI
30   * @brief SPI driver modules
31   * @{
32   */
33 
34 /** @defgroup SPI_Private_TypesDefinitions
35   * @{
36   */
37 
38 /**
39   * @}
40   */
41 
42 
43 /** @defgroup SPI_Private_Defines
44   * @{
45   */
46 
47 /* SPI SPE mask */
48 #define CR1_SPE_Set          ((uint16_t)0x0040)
49 #define CR1_SPE_Reset        ((uint16_t)0xFFBF)
50 
51 /* I2S I2SE mask */
52 #define I2SCFGR_I2SE_Set     ((uint16_t)0x0400)
53 #define I2SCFGR_I2SE_Reset   ((uint16_t)0xFBFF)
54 
55 /* SPI CRCNext mask */
56 #define CR1_CRCNext_Set      ((uint16_t)0x1000)
57 
58 /* SPI CRCEN mask */
59 #define CR1_CRCEN_Set        ((uint16_t)0x2000)
60 #define CR1_CRCEN_Reset      ((uint16_t)0xDFFF)
61 
62 /* SPI SSOE mask */
63 #define CR2_SSOE_Set         ((uint16_t)0x0004)
64 #define CR2_SSOE_Reset       ((uint16_t)0xFFFB)
65 
66 /* SPI registers Masks */
67 #define CR1_CLEAR_Mask       ((uint16_t)0x3040)
68 #define I2SCFGR_CLEAR_Mask   ((uint16_t)0xF040)
69 
70 /* SPI or I2S mode selection masks */
71 #define SPI_Mode_Select      ((uint16_t)0xF7FF)
72 #define I2S_Mode_Select      ((uint16_t)0x0800)
73 
74 /* I2S clock source selection masks */
75 #define I2S2_CLOCK_SRC       ((uint32_t)(0x00020000))
76 #define I2S3_CLOCK_SRC       ((uint32_t)(0x00040000))
77 #define I2S_MUL_MASK         ((uint32_t)(0x0000F000))
78 #define I2S_DIV_MASK         ((uint32_t)(0x000000F0))
79 
80 /**
81   * @}
82   */
83 
84 /** @defgroup SPI_Private_Macros
85   * @{
86   */
87 
88 /**
89   * @}
90   */
91 
92 /** @defgroup SPI_Private_Variables
93   * @{
94   */
95 
96 /**
97   * @}
98   */
99 
100 /** @defgroup SPI_Private_FunctionPrototypes
101   * @{
102   */
103 
104 /**
105   * @}
106   */
107 
108 /** @defgroup SPI_Private_Functions
109   * @{
110   */
111 
112 /**
113   * @brief  Deinitializes the SPIx peripheral registers to their default
114   *   reset values (Affects also the I2Ss).
115   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
116   * @retval None
117   */
SPI_I2S_DeInit(SPI_TypeDef * SPIx)118 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
119 {
120   /* Check the parameters */
121   assert_param(IS_SPI_ALL_PERIPH(SPIx));
122 
123   if (SPIx == SPI1)
124   {
125     /* Enable SPI1 reset state */
126     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
127     /* Release SPI1 from reset state */
128     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
129   }
130   else if (SPIx == SPI2)
131   {
132     /* Enable SPI2 reset state */
133     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
134     /* Release SPI2 from reset state */
135     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
136   }
137   else
138   {
139     if (SPIx == SPI3)
140     {
141       /* Enable SPI3 reset state */
142       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
143       /* Release SPI3 from reset state */
144       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
145     }
146   }
147 }
148 
149 /**
150   * @brief  Initializes the SPIx peripheral according to the specified
151   *   parameters in the SPI_InitStruct.
152   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
153   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
154   *   contains the configuration information for the specified SPI peripheral.
155   * @retval None
156   */
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)157 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
158 {
159   uint16_t tmpreg = 0;
160 
161   /* check the parameters */
162   assert_param(IS_SPI_ALL_PERIPH(SPIx));
163 
164   /* Check the SPI parameters */
165   assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
166   assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
167   assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
168   assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
169   assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
170   assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
171   assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
172   assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
173   assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
174 
175 /*---------------------------- SPIx CR1 Configuration ------------------------*/
176   /* Get the SPIx CR1 value */
177   tmpreg = SPIx->CR1;
178   /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
179   tmpreg &= CR1_CLEAR_Mask;
180   /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
181      master/salve mode, CPOL and CPHA */
182   /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
183   /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
184   /* Set LSBFirst bit according to SPI_FirstBit value */
185   /* Set BR bits according to SPI_BaudRatePrescaler value */
186   /* Set CPOL bit according to SPI_CPOL value */
187   /* Set CPHA bit according to SPI_CPHA value */
188   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
189                   SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |
190                   SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
191                   SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
192   /* Write to SPIx CR1 */
193   SPIx->CR1 = tmpreg;
194 
195   /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
196   SPIx->I2SCFGR &= SPI_Mode_Select;
197 
198 /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
199   /* Write to SPIx CRCPOLY */
200   SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
201 }
202 
203 /**
204   * @brief  Initializes the SPIx peripheral according to the specified
205   *   parameters in the I2S_InitStruct.
206   * @param  SPIx: where x can be  2 or 3 to select the SPI peripheral
207   *   (configured in I2S mode).
208   * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
209   *   contains the configuration information for the specified SPI peripheral
210   *   configured in I2S mode.
211   * @note
212   *  The function calculates the optimal prescaler needed to obtain the most
213   *  accurate audio frequency (depending on the I2S clock source, the PLL values
214   *  and the product configuration). But in case the prescaler value is greater
215   *  than 511, the default value (0x02) will be configured instead.  *
216   * @retval None
217   */
I2S_Init(SPI_TypeDef * SPIx,I2S_InitTypeDef * I2S_InitStruct)218 void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
219 {
220   uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
221   uint32_t tmp = 0;
222   RCC_ClocksTypeDef RCC_Clocks;
223   uint32_t sourceclock = 0;
224 
225   /* Check the I2S parameters */
226   assert_param(IS_SPI_23_PERIPH(SPIx));
227   assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
228   assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
229   assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
230   assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
231   assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
232   assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
233 
234 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
235   /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
236   SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
237   SPIx->I2SPR = 0x0002;
238 
239   /* Get the I2SCFGR register value */
240   tmpreg = SPIx->I2SCFGR;
241 
242   /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
243   if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
244   {
245     i2sodd = (uint16_t)0;
246     i2sdiv = (uint16_t)2;
247   }
248   /* If the requested audio frequency is not the default, compute the prescaler */
249   else
250   {
251     /* Check the frame length (For the Prescaler computing) */
252     if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
253     {
254       /* Packet length is 16 bits */
255       packetlength = 1;
256     }
257     else
258     {
259       /* Packet length is 32 bits */
260       packetlength = 2;
261     }
262 
263     /* Get the I2S clock source mask depending on the peripheral number */
264     if(((uint32_t)SPIx) == SPI2_BASE)
265     {
266       /* The mask is relative to I2S2 */
267       tmp = I2S2_CLOCK_SRC;
268     }
269     else
270     {
271       /* The mask is relative to I2S3 */
272       tmp = I2S3_CLOCK_SRC;
273     }
274 
275     /* Check the I2S clock source configuration depending on the Device:
276        Only Connectivity line devices have the PLL3 VCO clock */
277 #ifdef STM32F10X_CL
278     if((RCC->CFGR2 & tmp) != 0)
279     {
280       /* Get the configuration bits of RCC PLL3 multiplier */
281       tmp = (uint32_t)((RCC->CFGR2 & I2S_MUL_MASK) >> 12);
282 
283       /* Get the value of the PLL3 multiplier */
284       if((tmp > 5) && (tmp < 15))
285       {
286         /* Multplier is between 8 and 14 (value 15 is forbidden) */
287         tmp += 2;
288       }
289       else
290       {
291         if (tmp == 15)
292         {
293           /* Multiplier is 20 */
294           tmp = 20;
295         }
296       }
297       /* Get the PREDIV2 value */
298       sourceclock = (uint32_t)(((RCC->CFGR2 & I2S_DIV_MASK) >> 4) + 1);
299 
300       /* Calculate the Source Clock frequency based on PLL3 and PREDIV2 values */
301       sourceclock = (uint32_t) ((HSE_Value / sourceclock) * tmp * 2);
302     }
303     else
304     {
305       /* I2S Clock source is System clock: Get System Clock frequency */
306       RCC_GetClocksFreq(&RCC_Clocks);
307 
308       /* Get the source clock value: based on System Clock value */
309       sourceclock = RCC_Clocks.SYSCLK_Frequency;
310     }
311 #else /* STM32F10X_HD */
312     /* I2S Clock source is System clock: Get System Clock frequency */
313     RCC_GetClocksFreq(&RCC_Clocks);
314 
315     /* Get the source clock value: based on System Clock value */
316     sourceclock = RCC_Clocks.SYSCLK_Frequency;
317 #endif /* STM32F10X_CL */
318 
319     /* Compute the Real divider depending on the MCLK output state with a flaoting point */
320     if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
321     {
322       /* MCLK output is enabled */
323       tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
324     }
325     else
326     {
327       /* MCLK output is disabled */
328       tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
329     }
330 
331     /* Remove the flaoting point */
332     tmp = tmp / 10;
333 
334     /* Check the parity of the divider */
335     i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
336 
337     /* Compute the i2sdiv prescaler */
338     i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
339 
340     /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
341     i2sodd = (uint16_t) (i2sodd << 8);
342   }
343 
344   /* Test if the divider is 1 or 0 or greater than 0xFF */
345   if ((i2sdiv < 2) || (i2sdiv > 0xFF))
346   {
347     /* Set the default values */
348     i2sdiv = 2;
349     i2sodd = 0;
350   }
351 
352   /* Write to SPIx I2SPR register the computed value */
353   SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
354 
355   /* Configure the I2S with the SPI_InitStruct values */
356   tmpreg |= (uint16_t)(I2S_Mode_Select | (uint16_t)(I2S_InitStruct->I2S_Mode | \
357                   (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
358                   (uint16_t)I2S_InitStruct->I2S_CPOL))));
359 
360   /* Write to SPIx I2SCFGR */
361   SPIx->I2SCFGR = tmpreg;
362 }
363 
364 /**
365   * @brief  Fills each SPI_InitStruct member with its default value.
366   * @param  SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized.
367   * @retval None
368   */
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)369 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
370 {
371 /*--------------- Reset SPI init structure parameters values -----------------*/
372   /* Initialize the SPI_Direction member */
373   SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
374   /* initialize the SPI_Mode member */
375   SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
376   /* initialize the SPI_DataSize member */
377   SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
378   /* Initialize the SPI_CPOL member */
379   SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
380   /* Initialize the SPI_CPHA member */
381   SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
382   /* Initialize the SPI_NSS member */
383   SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
384   /* Initialize the SPI_BaudRatePrescaler member */
385   SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
386   /* Initialize the SPI_FirstBit member */
387   SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
388   /* Initialize the SPI_CRCPolynomial member */
389   SPI_InitStruct->SPI_CRCPolynomial = 7;
390 }
391 
392 /**
393   * @brief  Fills each I2S_InitStruct member with its default value.
394   * @param  I2S_InitStruct : pointer to a I2S_InitTypeDef structure which will be initialized.
395   * @retval None
396   */
I2S_StructInit(I2S_InitTypeDef * I2S_InitStruct)397 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
398 {
399 /*--------------- Reset I2S init structure parameters values -----------------*/
400   /* Initialize the I2S_Mode member */
401   I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
402 
403   /* Initialize the I2S_Standard member */
404   I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
405 
406   /* Initialize the I2S_DataFormat member */
407   I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
408 
409   /* Initialize the I2S_MCLKOutput member */
410   I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
411 
412   /* Initialize the I2S_AudioFreq member */
413   I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
414 
415   /* Initialize the I2S_CPOL member */
416   I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
417 }
418 
419 /**
420   * @brief  Enables or disables the specified SPI peripheral.
421   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
422   * @param  NewState: new state of the SPIx peripheral.
423   *   This parameter can be: ENABLE or DISABLE.
424   * @retval None
425   */
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)426 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
427 {
428   /* Check the parameters */
429   assert_param(IS_SPI_ALL_PERIPH(SPIx));
430   assert_param(IS_FUNCTIONAL_STATE(NewState));
431   if (NewState != DISABLE)
432   {
433     /* Enable the selected SPI peripheral */
434     SPIx->CR1 |= CR1_SPE_Set;
435   }
436   else
437   {
438     /* Disable the selected SPI peripheral */
439     SPIx->CR1 &= CR1_SPE_Reset;
440   }
441 }
442 
443 /**
444   * @brief  Enables or disables the specified SPI peripheral (in I2S mode).
445   * @param  SPIx: where x can be 2 or 3 to select the SPI peripheral.
446   * @param  NewState: new state of the SPIx peripheral.
447   *   This parameter can be: ENABLE or DISABLE.
448   * @retval None
449   */
I2S_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)450 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
451 {
452   /* Check the parameters */
453   assert_param(IS_SPI_23_PERIPH(SPIx));
454   assert_param(IS_FUNCTIONAL_STATE(NewState));
455   if (NewState != DISABLE)
456   {
457     /* Enable the selected SPI peripheral (in I2S mode) */
458     SPIx->I2SCFGR |= I2SCFGR_I2SE_Set;
459   }
460   else
461   {
462     /* Disable the selected SPI peripheral (in I2S mode) */
463     SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset;
464   }
465 }
466 
467 /**
468   * @brief  Enables or disables the specified SPI/I2S interrupts.
469   * @param  SPIx: where x can be
470   *   - 1, 2 or 3 in SPI mode
471   *   - 2 or 3 in I2S mode
472   * @param  SPI_I2S_IT: specifies the SPI/I2S interrupt source to be enabled or disabled.
473   *   This parameter can be one of the following values:
474   *     @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
475   *     @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
476   *     @arg SPI_I2S_IT_ERR: Error interrupt mask
477   * @param  NewState: new state of the specified SPI/I2S interrupt.
478   *   This parameter can be: ENABLE or DISABLE.
479   * @retval None
480   */
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)481 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
482 {
483   uint16_t itpos = 0, itmask = 0 ;
484   /* Check the parameters */
485   assert_param(IS_SPI_ALL_PERIPH(SPIx));
486   assert_param(IS_FUNCTIONAL_STATE(NewState));
487   assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
488 
489   /* Get the SPI/I2S IT index */
490   itpos = SPI_I2S_IT >> 4;
491 
492   /* Set the IT mask */
493   itmask = (uint16_t)1 << (uint16_t)itpos;
494 
495   if (NewState != DISABLE)
496   {
497     /* Enable the selected SPI/I2S interrupt */
498     SPIx->CR2 |= itmask;
499   }
500   else
501   {
502     /* Disable the selected SPI/I2S interrupt */
503     SPIx->CR2 &= (uint16_t)~itmask;
504   }
505 }
506 
507 /**
508   * @brief  Enables or disables the SPIx/I2Sx DMA interface.
509   * @param  SPIx: where x can be
510   *   - 1, 2 or 3 in SPI mode
511   *   - 2 or 3 in I2S mode
512   * @param  SPI_I2S_DMAReq: specifies the SPI/I2S DMA transfer request to be enabled or disabled.
513   *   This parameter can be any combination of the following values:
514   *     @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
515   *     @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
516   * @param  NewState: new state of the selected SPI/I2S DMA transfer request.
517   *   This parameter can be: ENABLE or DISABLE.
518   * @retval None
519   */
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)520 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
521 {
522   /* Check the parameters */
523   assert_param(IS_SPI_ALL_PERIPH(SPIx));
524   assert_param(IS_FUNCTIONAL_STATE(NewState));
525   assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));
526   if (NewState != DISABLE)
527   {
528     /* Enable the selected SPI/I2S DMA requests */
529     SPIx->CR2 |= SPI_I2S_DMAReq;
530   }
531   else
532   {
533     /* Disable the selected SPI/I2S DMA requests */
534     SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
535   }
536 }
537 
538 /**
539   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
540   * @param  SPIx: where x can be
541   *   - 1, 2 or 3 in SPI mode
542   *   - 2 or 3 in I2S mode
543   * @param  Data : Data to be transmitted.
544   * @retval None
545   */
SPI_I2S_SendData(SPI_TypeDef * SPIx,uint16_t Data)546 void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
547 {
548   /* Check the parameters */
549   assert_param(IS_SPI_ALL_PERIPH(SPIx));
550 
551   /* Write in the DR register the data to be sent */
552   SPIx->DR = Data;
553 }
554 
555 /**
556   * @brief  Returns the most recent received data by the SPIx/I2Sx peripheral.
557   * @param  SPIx: where x can be
558   *   - 1, 2 or 3 in SPI mode
559   *   - 2 or 3 in I2S mode
560   * @retval The value of the received data.
561   */
SPI_I2S_ReceiveData(SPI_TypeDef * SPIx)562 uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
563 {
564   /* Check the parameters */
565   assert_param(IS_SPI_ALL_PERIPH(SPIx));
566 
567   /* Return the data in the DR register */
568   return SPIx->DR;
569 }
570 
571 /**
572   * @brief  Configures internally by software the NSS pin for the selected SPI.
573   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
574   * @param  SPI_NSSInternalSoft: specifies the SPI NSS internal state.
575   *   This parameter can be one of the following values:
576   *     @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
577   *     @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
578   * @retval None
579   */
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)580 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
581 {
582   /* Check the parameters */
583   assert_param(IS_SPI_ALL_PERIPH(SPIx));
584   assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
585   if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
586   {
587     /* Set NSS pin internally by software */
588     SPIx->CR1 |= SPI_NSSInternalSoft_Set;
589   }
590   else
591   {
592     /* Reset NSS pin internally by software */
593     SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
594   }
595 }
596 
597 /**
598   * @brief  Enables or disables the SS output for the selected SPI.
599   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
600   * @param  NewState: new state of the SPIx SS output.
601   *   This parameter can be: ENABLE or DISABLE.
602   * @retval None
603   */
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)604 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
605 {
606   /* Check the parameters */
607   assert_param(IS_SPI_ALL_PERIPH(SPIx));
608   assert_param(IS_FUNCTIONAL_STATE(NewState));
609   if (NewState != DISABLE)
610   {
611     /* Enable the selected SPI SS output */
612     SPIx->CR2 |= CR2_SSOE_Set;
613   }
614   else
615   {
616     /* Disable the selected SPI SS output */
617     SPIx->CR2 &= CR2_SSOE_Reset;
618   }
619 }
620 
621 /**
622   * @brief  Configures the data size for the selected SPI.
623   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
624   * @param  SPI_DataSize: specifies the SPI data size.
625   *   This parameter can be one of the following values:
626   *     @arg SPI_DataSize_16b: Set data frame format to 16bit
627   *     @arg SPI_DataSize_8b: Set data frame format to 8bit
628   * @retval None
629   */
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)630 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
631 {
632   /* Check the parameters */
633   assert_param(IS_SPI_ALL_PERIPH(SPIx));
634   assert_param(IS_SPI_DATASIZE(SPI_DataSize));
635   /* Clear DFF bit */
636   SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b;
637   /* Set new DFF bit value */
638   SPIx->CR1 |= SPI_DataSize;
639 }
640 
641 /**
642   * @brief  Transmit the SPIx CRC value.
643   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
644   * @retval None
645   */
SPI_TransmitCRC(SPI_TypeDef * SPIx)646 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
647 {
648   /* Check the parameters */
649   assert_param(IS_SPI_ALL_PERIPH(SPIx));
650 
651   /* Enable the selected SPI CRC transmission */
652   SPIx->CR1 |= CR1_CRCNext_Set;
653 }
654 
655 /**
656   * @brief  Enables or disables the CRC value calculation of the transfered bytes.
657   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
658   * @param  NewState: new state of the SPIx CRC value calculation.
659   *   This parameter can be: ENABLE or DISABLE.
660   * @retval None
661   */
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)662 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
663 {
664   /* Check the parameters */
665   assert_param(IS_SPI_ALL_PERIPH(SPIx));
666   assert_param(IS_FUNCTIONAL_STATE(NewState));
667   if (NewState != DISABLE)
668   {
669     /* Enable the selected SPI CRC calculation */
670     SPIx->CR1 |= CR1_CRCEN_Set;
671   }
672   else
673   {
674     /* Disable the selected SPI CRC calculation */
675     SPIx->CR1 &= CR1_CRCEN_Reset;
676   }
677 }
678 
679 /**
680   * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
681   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
682   * @param  SPI_CRC: specifies the CRC register to be read.
683   *   This parameter can be one of the following values:
684   *     @arg SPI_CRC_Tx: Selects Tx CRC register
685   *     @arg SPI_CRC_Rx: Selects Rx CRC register
686   * @retval The selected CRC register value..
687   */
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)688 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
689 {
690   uint16_t crcreg = 0;
691   /* Check the parameters */
692   assert_param(IS_SPI_ALL_PERIPH(SPIx));
693   assert_param(IS_SPI_CRC(SPI_CRC));
694   if (SPI_CRC != SPI_CRC_Rx)
695   {
696     /* Get the Tx CRC register */
697     crcreg = SPIx->TXCRCR;
698   }
699   else
700   {
701     /* Get the Rx CRC register */
702     crcreg = SPIx->RXCRCR;
703   }
704   /* Return the selected CRC register */
705   return crcreg;
706 }
707 
708 /**
709   * @brief  Returns the CRC Polynomial register value for the specified SPI.
710   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
711   * @retval The CRC Polynomial register value.
712   */
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)713 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
714 {
715   /* Check the parameters */
716   assert_param(IS_SPI_ALL_PERIPH(SPIx));
717 
718   /* Return the CRC polynomial register */
719   return SPIx->CRCPR;
720 }
721 
722 /**
723   * @brief  Selects the data transfer direction in bi-directional mode for the specified SPI.
724   * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
725   * @param  SPI_Direction: specifies the data transfer direction in bi-directional mode.
726   *   This parameter can be one of the following values:
727   *     @arg SPI_Direction_Tx: Selects Tx transmission direction
728   *     @arg SPI_Direction_Rx: Selects Rx receive direction
729   * @retval None
730   */
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)731 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
732 {
733   /* Check the parameters */
734   assert_param(IS_SPI_ALL_PERIPH(SPIx));
735   assert_param(IS_SPI_DIRECTION(SPI_Direction));
736   if (SPI_Direction == SPI_Direction_Tx)
737   {
738     /* Set the Tx only mode */
739     SPIx->CR1 |= SPI_Direction_Tx;
740   }
741   else
742   {
743     /* Set the Rx only mode */
744     SPIx->CR1 &= SPI_Direction_Rx;
745   }
746 }
747 
748 /**
749   * @brief  Checks whether the specified SPI/I2S flag is set or not.
750   * @param  SPIx: where x can be
751   *   - 1, 2 or 3 in SPI mode
752   *   - 2 or 3 in I2S mode
753   * @param  SPI_I2S_FLAG: specifies the SPI/I2S flag to check.
754   *   This parameter can be one of the following values:
755   *     @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
756   *     @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
757   *     @arg SPI_I2S_FLAG_BSY: Busy flag.
758   *     @arg SPI_I2S_FLAG_OVR: Overrun flag.
759   *     @arg SPI_FLAG_MODF: Mode Fault flag.
760   *     @arg SPI_FLAG_CRCERR: CRC Error flag.
761   *     @arg I2S_FLAG_UDR: Underrun Error flag.
762   *     @arg I2S_FLAG_CHSIDE: Channel Side flag.
763   * @retval The new state of SPI_I2S_FLAG (SET or RESET).
764   */
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)765 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
766 {
767   FlagStatus bitstatus = RESET;
768   /* Check the parameters */
769   assert_param(IS_SPI_ALL_PERIPH(SPIx));
770   assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
771   /* Check the status of the specified SPI/I2S flag */
772   if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
773   {
774     /* SPI_I2S_FLAG is set */
775     bitstatus = SET;
776   }
777   else
778   {
779     /* SPI_I2S_FLAG is reset */
780     bitstatus = RESET;
781   }
782   /* Return the SPI_I2S_FLAG status */
783   return  bitstatus;
784 }
785 
786 /**
787   * @brief  Clears the SPIx CRC Error (CRCERR) flag.
788   * @param  SPIx: where x can be
789   *   - 1, 2 or 3 in SPI mode
790   * @param  SPI_I2S_FLAG: specifies the SPI flag to clear.
791   *   This function clears only CRCERR flag.
792   * @note
793   *   - OVR (OverRun error) flag is cleared by software sequence: a read
794   *     operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read
795   *     operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
796   *   - UDR (UnderRun error) flag is cleared by a read operation to
797   *     SPI_SR register (SPI_I2S_GetFlagStatus()).
798   *   - MODF (Mode Fault) flag is cleared by software sequence: a read/write
799   *     operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a
800   *     write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
801   * @retval None
802   */
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)803 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
804 {
805   /* Check the parameters */
806   assert_param(IS_SPI_ALL_PERIPH(SPIx));
807   assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));
808 
809     /* Clear the selected SPI CRC Error (CRCERR) flag */
810     SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
811 }
812 
813 /**
814   * @brief  Checks whether the specified SPI/I2S interrupt has occurred or not.
815   * @param  SPIx: where x can be
816   *   - 1, 2 or 3 in SPI mode
817   *   - 2 or 3 in I2S mode
818   * @param  SPI_I2S_IT: specifies the SPI/I2S interrupt source to check.
819   *   This parameter can be one of the following values:
820   *     @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
821   *     @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
822   *     @arg SPI_I2S_IT_OVR: Overrun interrupt.
823   *     @arg SPI_IT_MODF: Mode Fault interrupt.
824   *     @arg SPI_IT_CRCERR: CRC Error interrupt.
825   *     @arg I2S_IT_UDR: Underrun Error interrupt.
826   * @retval The new state of SPI_I2S_IT (SET or RESET).
827   */
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)828 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
829 {
830   ITStatus bitstatus = RESET;
831   uint16_t itpos = 0, itmask = 0, enablestatus = 0;
832 
833   /* Check the parameters */
834   assert_param(IS_SPI_ALL_PERIPH(SPIx));
835   assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
836 
837   /* Get the SPI/I2S IT index */
838   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
839 
840   /* Get the SPI/I2S IT mask */
841   itmask = SPI_I2S_IT >> 4;
842 
843   /* Set the IT mask */
844   itmask = 0x01 << itmask;
845 
846   /* Get the SPI_I2S_IT enable bit status */
847   enablestatus = (SPIx->CR2 & itmask) ;
848 
849   /* Check the status of the specified SPI/I2S interrupt */
850   if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
851   {
852     /* SPI_I2S_IT is set */
853     bitstatus = SET;
854   }
855   else
856   {
857     /* SPI_I2S_IT is reset */
858     bitstatus = RESET;
859   }
860   /* Return the SPI_I2S_IT status */
861   return bitstatus;
862 }
863 
864 /**
865   * @brief  Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
866   * @param  SPIx: where x can be
867   *   - 1, 2 or 3 in SPI mode
868   * @param  SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.
869   *   This function clears only CRCERR intetrrupt pending bit.
870   * @note
871   *   - OVR (OverRun Error) interrupt pending bit is cleared by software
872   *     sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData())
873   *     followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()).
874   *   - UDR (UnderRun Error) interrupt pending bit is cleared by a read
875   *     operation to SPI_SR register (SPI_I2S_GetITStatus()).
876   *   - MODF (Mode Fault) interrupt pending bit is cleared by software sequence:
877   *     a read/write operation to SPI_SR register (SPI_I2S_GetITStatus())
878   *     followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable
879   *     the SPI).
880   * @retval None
881   */
SPI_I2S_ClearITPendingBit(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)882 void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
883 {
884   uint16_t itpos = 0;
885   /* Check the parameters */
886   assert_param(IS_SPI_ALL_PERIPH(SPIx));
887   assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));
888 
889   /* Get the SPI IT index */
890   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
891 
892   /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */
893   SPIx->SR = (uint16_t)~itpos;
894 }
895 /**
896   * @}
897   */
898 
899 /**
900   * @}
901   */
902 
903 /**
904   * @}
905   */
906 
907 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
908