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