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