1 /**
2   ******************************************************************************
3   * @file               ft32f0xx_spi.c
4   * @author             FMD AE
5   * @brief              This file provides firmware functions to manage the following
6   *                     functionalities of the Serial peripheral interface (SPI):
7   *                 + Initialization and Configuration
8   *                 + Data transfers functions
9   *                 + Hardware CRC Calculation
10   *                 + DMA transfers management
11   *                 + Interrupts and flags management
12   * @version            V1.0.0
13   * @data                   2021-07-01
14     ******************************************************************************
15   */
16 /* Includes ------------------------------------------------------------------*/
17 #include "ft32f0xx_spi.h"
18 #include "ft32f0xx_rcc.h"
19 
20 /* SPI registers Masks */
21 #define CR1_CLEAR_MASK       ((uint16_t)0x3040)
22 #define CR1_CLEAR_MASK2      ((uint16_t)0xFFFB)
23 #define CR2_LDMA_MASK        ((uint16_t)0x9FFF)
24 
25 #define I2SCFGR_CLEAR_Mask   ((uint16_t)0xF040)
26 
27 
28 /**
29   * @brief  Deinitializes the SPIx peripheral registers to their default
30   *         reset values.
31   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
32   * @retval None
33   */
SPI_I2S_DeInit(SPI_TypeDef * SPIx)34 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
35 {
36   /* Check the parameters */
37   assert_param(IS_SPI_ALL_PERIPH(SPIx));
38 
39   if (SPIx == SPI1)
40   {
41     /* Enable SPI1 reset state */
42     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
43     /* Release SPI1 from reset state */
44     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
45   }
46   else
47   {
48     if (SPIx == SPI2)
49     {
50       /* Enable SPI2 reset state */
51       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
52       /* Release SPI2 from reset state */
53       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
54     }
55   }
56 }
57 
58 /**
59   * @brief  Fills each SPI_InitStruct member with its default value.
60   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
61   * @retval None
62   */
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)63 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
64 {
65 /*--------------- Reset SPI init structure parameters values -----------------*/
66   /* Initialize the SPI_Direction member */
67   SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
68   /* Initialize the SPI_Mode member */
69   SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
70   /* Initialize the SPI_DataSize member */
71   SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
72   /* Initialize the SPI_CPOL member */
73   SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
74   /* Initialize the SPI_CPHA member */
75   SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
76   /* Initialize the SPI_NSS member */
77   SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
78   /* Initialize the SPI_BaudRatePrescaler member */
79   SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
80   /* Initialize the SPI_FirstBit member */
81   SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
82   /* Initialize the SPI_CRCPolynomial member */
83   SPI_InitStruct->SPI_CRCPolynomial = 7;
84 }
85 
86 /**
87   * @brief  Initializes the SPIx peripheral according to the specified
88   *         parameters in the SPI_InitStruct.
89   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
90   * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
91   *         contains the configuration information for the specified SPI peripheral.
92   * @retval None
93   */
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)94 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
95 {
96   uint16_t tmpreg = 0;
97 
98   /* check the parameters */
99   assert_param(IS_SPI_ALL_PERIPH(SPIx));
100 
101   /* Check the SPI parameters */
102   assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
103   assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
104   assert_param(IS_SPI_DATA_SIZE(SPI_InitStruct->SPI_DataSize));
105   assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
106   assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
107   assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
108   assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
109   assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
110   assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
111 
112   /*---------------------------- SPIx CR1 Configuration ------------------------*/
113   /* Get the SPIx CR1 value */
114   tmpreg = SPIx->CR1;
115   /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, CPOL and CPHA bits */
116   tmpreg &= CR1_CLEAR_MASK;
117   /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
118   master/slave mode, CPOL and CPHA */
119   /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
120   /* Set SSM, SSI bit according to SPI_NSS values */
121   /* Set LSBFirst bit according to SPI_FirstBit value */
122   /* Set BR bits according to SPI_BaudRatePrescaler value */
123   /* Set CPOL bit according to SPI_CPOL value */
124   /* Set CPHA bit according to SPI_CPHA value */
125   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_FirstBit |
126                       SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA |
127                       SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler);
128   /* Write to SPIx CR1 */
129   SPIx->CR1 = tmpreg;
130   /*-------------------------Data Size Configuration -----------------------*/
131   /* Get the SPIx CR2 value */
132   tmpreg = SPIx->CR2;
133   /* Clear DS[3:0] bits */
134   tmpreg &=(uint16_t)~SPI_CR2_DS;
135   /* Configure SPIx: Data Size */
136   tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize);
137   /* Write to SPIx CR2 */
138   SPIx->CR2 = tmpreg;
139 
140   /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
141   /* Write to SPIx CRCPOLY */
142   SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
143 
144   /*---------------------------- SPIx CR1 Configuration ------------------------*/
145   /* Get the SPIx CR1 value */
146   tmpreg = SPIx->CR1;
147   /* Clear MSTR bit */
148   tmpreg &= CR1_CLEAR_MASK2;
149   /* Configure SPIx: master/slave mode */
150   /* Set MSTR bit according to SPI_Mode */
151   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode);
152   /* Write to SPIx CR1 */
153   SPIx->CR1 = tmpreg;
154 
155 //  /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
156 //  SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
157 }
158 /**
159   * @brief  Enables or disables the specified SPI peripheral.
160   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
161   * @param  NewState: new state of the SPIx peripheral.
162   *          This parameter can be: ENABLE or DISABLE.
163   * @retval None
164   */
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)165 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
166 {
167   /* Check the parameters */
168   assert_param(IS_SPI_ALL_PERIPH(SPIx));
169   assert_param(IS_FUNCTIONAL_STATE(NewState));
170 
171   if (NewState != DISABLE)
172   {
173     /* Enable the selected SPI peripheral */
174     SPIx->CR1 |= SPI_CR1_SPE;
175   }
176   else
177   {
178     /* Disable the selected SPI peripheral */
179     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
180   }
181 }
182 
183 /**
184   * @brief  Enables or disables the TI Mode.
185   *
186   * @note   This function can be called only after the SPI_Init() function has
187   *         been called.
188   * @note   When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
189   *         are not taken into consideration and are configured by hardware
190   *         respectively to the TI mode requirements.
191   *
192   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
193   * @param  NewState: new state of the selected SPI TI communication mode.
194   *          This parameter can be: ENABLE or DISABLE.
195   * @retval None
196   */
SPI_TIModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)197 void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
198 {
199   /* Check the parameters */
200   assert_param(IS_SPI_ALL_PERIPH(SPIx));
201   assert_param(IS_FUNCTIONAL_STATE(NewState));
202 
203   if (NewState != DISABLE)
204   {
205     /* Enable the TI mode for the selected SPI peripheral */
206     SPIx->CR2 |= SPI_CR2_FRF;
207   }
208   else
209   {
210     /* Disable the TI mode for the selected SPI peripheral */
211     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF);
212   }
213 }
214 /**
215   * @brief  Configures the data size for the selected SPI.
216   * @param  SPIx: where x can be 1 or 2  to select the SPI peripheral.
217   * @param  SPI_DataSize: specifies the SPI data size.
218   *         For the SPIx peripheral this parameter can be one of the following values:
219   *            @arg SPI_DataSize_4b: Set data size to 4 bits
220   *            @arg SPI_DataSize_5b: Set data size to 5 bits
221   *            @arg SPI_DataSize_6b: Set data size to 6 bits
222   *            @arg SPI_DataSize_7b: Set data size to 7 bits
223   *            @arg SPI_DataSize_8b: Set data size to 8 bits
224   *            @arg SPI_DataSize_9b: Set data size to 9 bits
225   *            @arg SPI_DataSize_10b: Set data size to 10 bits
226   *            @arg SPI_DataSize_11b: Set data size to 11 bits
227   *            @arg SPI_DataSize_12b: Set data size to 12 bits
228   *            @arg SPI_DataSize_13b: Set data size to 13 bits
229   *            @arg SPI_DataSize_14b: Set data size to 14 bits
230   *            @arg SPI_DataSize_15b: Set data size to 15 bits
231   *            @arg SPI_DataSize_16b: Set data size to 16 bits
232   * @retval None
233   */
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)234 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
235 {
236   uint16_t tmpreg = 0;
237 
238   /* Check the parameters */
239   assert_param(IS_SPI_ALL_PERIPH(SPIx));
240   assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
241   /* Read the CR2 register */
242   tmpreg = SPIx->CR2;
243   /* Clear DS[3:0] bits */
244   tmpreg &= (uint16_t)~SPI_CR2_DS;
245   /* Set new DS[3:0] bits value */
246   tmpreg |= SPI_DataSize;
247   SPIx->CR2 = tmpreg;
248 }
249 
250 /**
251   * @brief  Configures the FIFO reception threshold for the selected SPI.
252   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
253   * @param  SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
254   *          This parameter can be one of the following values:
255   *            @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
256   *                                         level is greater or equal to 1/2.
257   *            @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
258   *                                         level is greater or equal to 1/4.
259   * @retval None
260   */
SPI_RxFIFOThresholdConfig(SPI_TypeDef * SPIx,uint16_t SPI_RxFIFOThreshold)261 void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
262 {
263   /* Check the parameters */
264   assert_param(IS_SPI_ALL_PERIPH(SPIx));
265   assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
266 
267   /* Clear FRXTH bit */
268   SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
269 
270   /* Set new FRXTH bit value */
271   SPIx->CR2 |= SPI_RxFIFOThreshold;
272 }
273 
274 /**
275   * @brief  Selects the data transfer direction in bidirectional mode for the specified SPI.
276   * @param  SPIx: where x can be 1 or 2  to select the SPI peripheral.
277   * @param  SPI_Direction: specifies the data transfer direction in bidirectional mode.
278   *          This parameter can be one of the following values:
279   *            @arg SPI_Direction_Tx: Selects Tx transmission direction
280   *            @arg SPI_Direction_Rx: Selects Rx receive direction
281   * @retval None
282   */
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)283 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
284 {
285   /* Check the parameters */
286   assert_param(IS_SPI_ALL_PERIPH(SPIx));
287   assert_param(IS_SPI_DIRECTION(SPI_Direction));
288   if (SPI_Direction == SPI_Direction_Tx)
289   {
290     /* Set the Tx only mode */
291     SPIx->CR1 |= SPI_Direction_Tx;
292   }
293   else
294   {
295     /* Set the Rx only mode */
296     SPIx->CR1 &= SPI_Direction_Rx;
297   }
298 }
299 
300 /**
301   * @brief  Configures internally by software the NSS pin for the selected SPI.
302   * @note   This function can be called only after the SPI_Init() function has
303   *         been called.
304   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
305   * @param  SPI_NSSInternalSoft: specifies the SPI NSS internal state.
306   *          This parameter can be one of the following values:
307   *            @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
308   *            @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
309   * @retval None
310   */
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)311 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
312 {
313   /* Check the parameters */
314   assert_param(IS_SPI_ALL_PERIPH(SPIx));
315   assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
316 
317   if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
318   {
319     /* Set NSS pin internally by software */
320     SPIx->CR1 |= SPI_NSSInternalSoft_Set;
321   }
322   else
323   {
324     /* Reset NSS pin internally by software */
325     SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
326   }
327 }
328 
329 /**
330   * @brief  Enables or disables the SS output for the selected SPI.
331   * @note   This function can be called only after the SPI_Init() function has
332   *         been called and the NSS hardware management mode is selected.
333   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
334   * @param  NewState: new state of the SPIx SS output.
335   *          This parameter can be: ENABLE or DISABLE.
336   * @retval None
337   */
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)338 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
339 {
340   /* Check the parameters */
341   assert_param(IS_SPI_ALL_PERIPH(SPIx));
342   assert_param(IS_FUNCTIONAL_STATE(NewState));
343   if (NewState != DISABLE)
344   {
345     /* Enable the selected SPI SS output */
346     SPIx->CR2 |= SPI_CR2_SSOE;
347   }
348   else
349   {
350     /* Disable the selected SPI SS output */
351     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
352   }
353 }
354 
355 /**
356   * @brief  Enables or disables the NSS pulse management mode.
357   * @note   This function can be called only after the SPI_Init() function has
358   *         been called.
359   * @note   When TI mode is selected, the control bits NSSP is not taken into
360   *         consideration and are configured by hardware respectively to the
361   *         TI mode requirements.
362   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
363   * @param  NewState: new state of the NSS pulse management mode.
364   *          This parameter can be: ENABLE or DISABLE.
365   * @retval None
366   */
SPI_NSSPulseModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)367 void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
368 {
369   /* Check the parameters */
370   assert_param(IS_SPI_ALL_PERIPH(SPIx));
371   assert_param(IS_FUNCTIONAL_STATE(NewState));
372 
373   if (NewState != DISABLE)
374   {
375     /* Enable the NSS pulse management mode */
376     SPIx->CR2 |= SPI_CR2_NSSP;
377   }
378   else
379   {
380     /* Disable the NSS pulse management mode */
381     SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP);
382   }
383 }
384 
385 /**
386   * @}
387   */
388 /**
389   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
390   * @param  SPIx: where x can be 1 or 2 in SPI mode to select the SPI peripheral.
391   * @param  Data: Data to be transmitted.
392   * @retval None
393   */
SPI_SendData8(SPI_TypeDef * SPIx,uint8_t Data)394 void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
395 {
396   uint32_t spixbase = 0x00;
397 
398   /* Check the parameters */
399   assert_param(IS_SPI_ALL_PERIPH(SPIx));
400 
401   spixbase = (uint32_t)SPIx;
402   spixbase += 0x0C;
403 
404   *(__IO uint8_t *) spixbase = Data;
405 }
406 
407 /**
408   * @brief  Transmits a Data through the SPIx/I2Sx peripheral.
409   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
410   *         the SPI peripheral.
411   * @param  Data: Data to be transmitted.
412   * @retval None
413   */
SPI_I2S_SendData16(SPI_TypeDef * SPIx,uint16_t Data)414 void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
415 {
416   /* Check the parameters */
417   assert_param(IS_SPI_ALL_PERIPH(SPIx));
418 
419   SPIx->DR = (uint16_t)Data;
420 }
421 
422 /**
423   * @brief  Returns the most recent received data by the SPIx/I2Sx peripheral.
424   * @param  SPIx: where x can be 1 or 2 in SPI mode to select the SPI peripheral.
425   * @retval The value of the received data.
426   */
SPI_ReceiveData8(SPI_TypeDef * SPIx)427 uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx)
428 {
429   uint32_t spixbase = 0x00;
430 
431   spixbase = (uint32_t)SPIx;
432   spixbase += 0x0C;
433 
434   return *(__IO uint8_t *) spixbase;
435 }
436 
437 /**
438   * @brief  Returns the most recent received data by the SPIx peripheral.
439   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
440   *         the SPI peripheral.
441   * @retval The value of the received data.
442   */
SPI_I2S_ReceiveData16(SPI_TypeDef * SPIx)443 uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx)
444 {
445   return SPIx->DR;
446 }
447 /**
448   * @}
449   */
450 /**
451   * @brief  Configures the CRC calculation length for the selected SPI.
452   * @note   This function can be called only after the SPI_Init() function has
453   *         been called.
454   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
455   * @param  SPI_CRCLength: specifies the SPI CRC calculation length.
456   *          This parameter can be one of the following values:
457   *            @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits
458   *            @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits
459   * @retval None
460   */
SPI_CRCLengthConfig(SPI_TypeDef * SPIx,uint16_t SPI_CRCLength)461 void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength)
462 {
463   /* Check the parameters */
464   assert_param(IS_SPI_ALL_PERIPH(SPIx));
465   assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength));
466 
467   /* Clear CRCL bit */
468   SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL);
469 
470   /* Set new CRCL bit value */
471   SPIx->CR1 |= SPI_CRCLength;
472 }
473 
474 /**
475   * @brief  Enables or disables the CRC value calculation of the transferred bytes.
476   * @note   This function can be called only after the SPI_Init() function has
477   *         been called.
478   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
479   * @param  NewState: new state of the SPIx CRC value calculation.
480   *          This parameter can be: ENABLE or DISABLE.
481   * @retval None
482   */
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)483 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
484 {
485   /* Check the parameters */
486   assert_param(IS_SPI_ALL_PERIPH(SPIx));
487   assert_param(IS_FUNCTIONAL_STATE(NewState));
488 
489   if (NewState != DISABLE)
490   {
491     /* Enable the selected SPI CRC calculation */
492     SPIx->CR1 |= SPI_CR1_CRCEN;
493   }
494   else
495   {
496     /* Disable the selected SPI CRC calculation */
497     SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
498   }
499 }
500 
501 /**
502   * @brief  Transmit the SPIx CRC value.
503   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
504   * @retval None
505   */
SPI_TransmitCRC(SPI_TypeDef * SPIx)506 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
507 {
508   /* Check the parameters */
509   assert_param(IS_SPI_ALL_PERIPH(SPIx));
510 
511   /* Enable the selected SPI CRC transmission */
512   SPIx->CR1 |= SPI_CR1_CRCNEXT;
513 }
514 
515 /**
516   * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
517   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
518   * @param  SPI_CRC: specifies the CRC register to be read.
519   *          This parameter can be one of the following values:
520   *            @arg SPI_CRC_Tx: Selects Tx CRC register
521   *            @arg SPI_CRC_Rx: Selects Rx CRC register
522   * @retval The selected CRC register value..
523   */
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)524 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
525 {
526   uint16_t crcreg = 0;
527   /* Check the parameters */
528   assert_param(IS_SPI_ALL_PERIPH(SPIx));
529   assert_param(IS_SPI_CRC(SPI_CRC));
530 
531   if (SPI_CRC != SPI_CRC_Rx)
532   {
533     /* Get the Tx CRC register */
534     crcreg = SPIx->TXCRCR;
535   }
536   else
537   {
538     /* Get the Rx CRC register */
539     crcreg = SPIx->RXCRCR;
540   }
541   /* Return the selected CRC register */
542   return crcreg;
543 }
544 
545 /**
546   * @brief  Returns the CRC Polynomial register value for the specified SPI.
547   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
548   * @retval The CRC Polynomial register value.
549   */
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)550 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
551 {
552   /* Check the parameters */
553   assert_param(IS_SPI_ALL_PERIPH(SPIx));
554 
555   /* Return the CRC polynomial register */
556   return SPIx->CRCPR;
557 }
558 
559 /**
560   * @}
561   */
562 /**
563   * @brief  Enables or disables the SPIx/I2Sx DMA interface.
564   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
565   *         the SPI peripheral.
566   * @param  SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled.
567   *          This parameter can be any combination of the following values:
568   *            @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
569   *            @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
570   * @param  NewState: new state of the selected SPI DMA transfer request.
571   *          This parameter can be: ENABLE or DISABLE.
572   * @retval None
573   */
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)574 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
575 {
576   /* Check the parameters */
577   assert_param(IS_SPI_ALL_PERIPH(SPIx));
578   assert_param(IS_FUNCTIONAL_STATE(NewState));
579   assert_param(IS_SPI_I2S_DMA_REQ(SPI_I2S_DMAReq));
580 
581   if (NewState != DISABLE)
582   {
583     /* Enable the selected SPI DMA requests */
584     SPIx->CR2 |= SPI_I2S_DMAReq;
585   }
586   else
587   {
588     /* Disable the selected SPI DMA requests */
589     SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
590   }
591 }
592 
593 /**
594   * @brief  Configures the number of data to transfer type(Even/Odd) for the DMA
595   *         last transfers and for the selected SPI.
596   * @note   This function have a meaning only if DMA mode is selected and if
597   *         the packing mode is used (data length <= 8 and DMA transfer size halfword)
598   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
599   * @param  SPI_LastDMATransfer: specifies the SPI last DMA transfers state.
600   *          This parameter can be one of the following values:
601   *            @arg SPI_LastDMATransfer_TxEvenRxEven: Number of data for transmission Even
602   *                                                   and number of data for reception Even.
603   *            @arg SPI_LastDMATransfer_TxOddRxEven: Number of data for transmission Odd
604   *                                                  and number of data for reception Even.
605   *            @arg SPI_LastDMATransfer_TxEvenRxOdd: Number of data for transmission Even
606   *                                                  and number of data for reception Odd.
607   *            @arg SPI_LastDMATransfer_TxOddRxOdd: Number of data for transmission Odd
608   *                                                 and number of data for reception Odd.
609   * @retval None
610   */
SPI_LastDMATransferCmd(SPI_TypeDef * SPIx,uint16_t SPI_LastDMATransfer)611 void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer)
612 {
613   /* Check the parameters */
614   assert_param(IS_SPI_ALL_PERIPH(SPIx));
615   assert_param(IS_SPI_LAST_DMA_TRANSFER(SPI_LastDMATransfer));
616 
617   /* Clear LDMA_TX and LDMA_RX bits */
618   SPIx->CR2 &= CR2_LDMA_MASK;
619 
620   /* Set new LDMA_TX and LDMA_RX bits value */
621   SPIx->CR2 |= SPI_LastDMATransfer;
622 }
623 
624 /**
625   * @}
626   */
627 /**
628   * @brief  Enables or disables the specified SPI/I2S interrupts.
629   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
630   *         the SPI peripheral.
631   * @param  SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
632   *          This parameter can be one of the following values:
633   *            @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
634   *            @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
635   *            @arg SPI_I2S_IT_ERR: Error interrupt mask
636   * @param  NewState: new state of the specified SPI interrupt.
637   *          This parameter can be: ENABLE or DISABLE.
638   * @retval None
639   */
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)640 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
641 {
642   uint16_t itpos = 0, itmask = 0 ;
643 
644   /* Check the parameters */
645   assert_param(IS_SPI_ALL_PERIPH(SPIx));
646   assert_param(IS_FUNCTIONAL_STATE(NewState));
647   assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
648 
649   /* Get the SPI IT index */
650   itpos = SPI_I2S_IT >> 4;
651 
652   /* Set the IT mask */
653   itmask = (uint16_t)1 << (uint16_t)itpos;
654 
655   if (NewState != DISABLE)
656   {
657     /* Enable the selected SPI interrupt */
658     SPIx->CR2 |= itmask;
659   }
660   else
661   {
662     /* Disable the selected SPI interrupt */
663     SPIx->CR2 &= (uint16_t)~itmask;
664   }
665 }
666 
667 /**
668   * @brief  Returns the current SPIx Transmission FIFO filled level.
669   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
670   * @retval The Transmission FIFO filling state.
671   *          - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty
672   *          - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
673   *          - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full.
674   *          - SPI_TransmissionFIFOStatus_Full: when FIFO is full.
675   */
SPI_GetTransmissionFIFOStatus(SPI_TypeDef * SPIx)676 uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx)
677 {
678   /* Get the SPIx Transmission FIFO level bits */
679   return (uint16_t)((SPIx->SR & SPI_SR_FTLVL));
680 }
681 
682 /**
683   * @brief  Returns the current SPIx Reception FIFO filled level.
684   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
685   * @retval The Reception FIFO filling state.
686   *          - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty
687   *          - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
688   *          - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full.
689   *          - SPI_ReceptionFIFOStatus_Full: when FIFO is full.
690   */
SPI_GetReceptionFIFOStatus(SPI_TypeDef * SPIx)691 uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx)
692 {
693   /* Get the SPIx Reception FIFO level bits */
694   return (uint16_t)((SPIx->SR & SPI_SR_FRLVL));
695 }
696 
697 /**
698   * @brief  Checks whether the specified SPI flag is set or not.
699   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
700   *         the SPI peripheral.
701   * @param  SPI_I2S_FLAG: specifies the SPI flag to check.
702   *          This parameter can be one of the following values:
703   *            @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
704   *            @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
705   *            @arg SPI_I2S_FLAG_BSY: Busy flag.
706   *            @arg SPI_I2S_FLAG_OVR: Overrun flag.
707   *            @arg SPI_FLAG_MODF: Mode Fault flag.
708   *            @arg SPI_FLAG_CRCERR: CRC Error flag.
709   *            @arg SPI_I2S_FLAG_FRE: TI frame format error flag.
710   *            @arg I2S_FLAG_UDR: Underrun Error flag.
711   *            @arg I2S_FLAG_CHSIDE: Channel Side flag.
712   * @retval The new state of SPI_I2S_FLAG (SET or RESET).
713   */
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)714 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
715 {
716   FlagStatus bitstatus = RESET;
717   /* Check the parameters */
718   assert_param(IS_SPI_ALL_PERIPH(SPIx));
719   assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
720 
721   /* Check the status of the specified SPI flag */
722   if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
723   {
724     /* SPI_I2S_FLAG is set */
725     bitstatus = SET;
726   }
727   else
728   {
729     /* SPI_I2S_FLAG is reset */
730     bitstatus = RESET;
731   }
732   /* Return the SPI_I2S_FLAG status */
733   return  bitstatus;
734 }
735 
736 /**
737   * @brief  Clears the SPIx CRC Error (CRCERR) flag.
738   * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
739   * @param  SPI_I2S_FLAG: specifies the SPI flag to clear.
740   *         This function clears only CRCERR flag.
741   * @note   OVR (OverRun error) flag is cleared by software sequence: a read
742   *         operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by
743   *         a read operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
744   * @note   MODF (Mode Fault) flag is cleared by software sequence: a read/write
745   *         operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by
746   *         a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
747   * @retval None
748   */
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)749 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
750 {
751   /* Check the parameters */
752   assert_param(IS_SPI_ALL_PERIPH(SPIx));
753   assert_param(IS_SPI_CLEAR_FLAG(SPI_I2S_FLAG));
754 
755   /* Clear the selected SPI CRC Error (CRCERR) flag */
756   SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
757 }
758 
759 /**
760   * @brief  Checks whether the specified SPI/I2S interrupt has occurred or not.
761   * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
762   *         the SPI peripheral.
763   * @param  SPI_I2S_IT: specifies the SPI interrupt source to check.
764   *          This parameter can be one of the following values:
765   *            @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
766   *            @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
767   *            @arg SPI_IT_MODF: Mode Fault interrupt.
768   *            @arg SPI_I2S_IT_OVR: Overrun interrupt.
769   *            @arg I2S_IT_UDR: Underrun interrupt.
770   *            @arg SPI_I2S_IT_FRE: Format Error interrupt.
771   * @retval The new state of SPI_I2S_IT (SET or RESET).
772   */
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)773 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
774 {
775   ITStatus bitstatus = RESET;
776   uint16_t itpos = 0, itmask = 0, enablestatus = 0;
777 
778   /* Check the parameters */
779   assert_param(IS_SPI_ALL_PERIPH(SPIx));
780   assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
781 
782   /* Get the SPI_I2S_IT index */
783   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
784 
785   /* Get the SPI_I2S_IT IT mask */
786   itmask = SPI_I2S_IT >> 4;
787 
788   /* Set the IT mask */
789   itmask = 0x01 << itmask;
790 
791   /* Get the SPI_I2S_IT enable bit status */
792   enablestatus = (SPIx->CR2 & itmask) ;
793 
794   /* Check the status of the specified SPI interrupt */
795   if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
796   {
797     /* SPI_I2S_IT is set */
798     bitstatus = SET;
799   }
800   else
801   {
802     /* SPI_I2S_IT is reset */
803     bitstatus = RESET;
804   }
805   /* Return the SPI_I2S_IT status */
806   return bitstatus;
807 }
808 
809 /**
810   * @}
811   */
812 
813 /**
814   * @}
815   */
816 
817 /**
818   * @}
819   */
820 
821 /**
822   * @}
823   */
824 
825 /************************ (C) COPYRIGHT FMD *****END OF FILE****/
826