1 /********************************** (C) COPYRIGHT *******************************
2 * File Name          : ch32f20x_spi.c
3 * Author             : WCH
4 * Version            : V1.0.0
5 * Date               : 2021/08/08
6 * Description        : This file provides all the SPI firmware functions.
7 *********************************************************************************/
8 #include "ch32f20x_spi.h"
9 #include "ch32f20x_rcc.h"
10 
11 /* SPI SPE mask */
12 #define CTLR1_SPE_Set          ((uint16_t)0x0040)
13 #define CTLR1_SPE_Reset        ((uint16_t)0xFFBF)
14 
15 /* I2S I2SE mask */
16 #define I2SCFGR_I2SE_Set       ((uint16_t)0x0400)
17 #define I2SCFGR_I2SE_Reset     ((uint16_t)0xFBFF)
18 
19 /* SPI CRCNext mask */
20 #define CTLR1_CRCNext_Set      ((uint16_t)0x1000)
21 
22 /* SPI CRCEN mask */
23 #define CTLR1_CRCEN_Set        ((uint16_t)0x2000)
24 #define CTLR1_CRCEN_Reset      ((uint16_t)0xDFFF)
25 
26 /* SPI SSOE mask */
27 #define CTLR2_SSOE_Set         ((uint16_t)0x0004)
28 #define CTLR2_SSOE_Reset       ((uint16_t)0xFFFB)
29 
30 /* SPI registers Masks */
31 #define CTLR1_CLEAR_Mask       ((uint16_t)0x3040)
32 #define I2SCFGR_CLEAR_Mask     ((uint16_t)0xF040)
33 
34 /* SPI or I2S mode selection masks */
35 #define SPI_Mode_Select        ((uint16_t)0xF7FF)
36 #define I2S_Mode_Select        ((uint16_t)0x0800)
37 
38 /* I2S clock source selection masks */
39 #define I2S2_CLOCK_SRC         ((uint32_t)(0x00020000))
40 #define I2S3_CLOCK_SRC         ((uint32_t)(0x00040000))
41 #define I2S_MUL_MASK           ((uint32_t)(0x0000F000))
42 #define I2S_DIV_MASK           ((uint32_t)(0x000000F0))
43 
44 /*******************************************************************************
45 * Function Name  : SPI_I2S_DeInit
46 * Description    : Deinitializes the SPIx peripheral registers to their default
47 *      reset values (Affects also the I2Ss).
48 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
49 * Return         : None
50 *******************************************************************************/
SPI_I2S_DeInit(SPI_TypeDef * SPIx)51 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
52 {
53   if (SPIx == SPI1)
54   {
55     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
56     RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
57   }
58   else if (SPIx == SPI2)
59   {
60     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
61     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
62   }
63   else
64   {
65     if (SPIx == SPI3)
66     {
67       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
68       RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
69     }
70   }
71 }
72 
73 /*******************************************************************************
74 * Function Name  : SPI_Init
75 * Description    : Initializes the SPIx peripheral according to the specified
76 *      parameters in the SPI_InitStruct.
77 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
78 *                  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
79 *      contains the configuration information for the specified SPI peripheral.
80 * Return         : None
81 *******************************************************************************/
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)82 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
83 {
84   uint16_t tmpreg = 0;
85 
86   tmpreg = SPIx->CTLR1;
87   tmpreg &= CTLR1_CLEAR_Mask;
88   tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
89                   SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |
90                   SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
91                   SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
92 
93   SPIx->CTLR1 = tmpreg;
94   SPIx->I2SCFGR &= SPI_Mode_Select;
95   SPIx->CRCR = SPI_InitStruct->SPI_CRCPolynomial;
96 }
97 
98 /*******************************************************************************
99 * Function Name  : I2S_Init
100 * Description    : Initializes the SPIx peripheral according to the specified
101 *      parameters in the I2S_InitStruct.
102 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
103 *      (configured in I2S mode).
104 *                  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
105 *      contains the configuration information for the specified SPI peripheral
106 *      configured in I2S mode.
107 * Return         : None
108 *******************************************************************************/
I2S_Init(SPI_TypeDef * SPIx,I2S_InitTypeDef * I2S_InitStruct)109 void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
110 {
111   uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
112   uint32_t tmp = 0;
113   RCC_ClocksTypeDef RCC_Clocks;
114   uint32_t sourceclock = 0;
115 
116   SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
117   SPIx->I2SPR = 0x0002;
118   tmpreg = SPIx->I2SCFGR;
119 
120   if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
121   {
122     i2sodd = (uint16_t)0;
123     i2sdiv = (uint16_t)2;
124   }
125   else
126   {
127     if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
128     {
129       packetlength = 1;
130     }
131     else
132     {
133       packetlength = 2;
134     }
135 
136     if(((uint32_t)SPIx) == SPI2_BASE)
137     {
138       tmp = I2S2_CLOCK_SRC;
139     }
140     else
141     {
142       tmp = I2S3_CLOCK_SRC;
143     }
144 
145     RCC_GetClocksFreq(&RCC_Clocks);
146 
147     sourceclock = RCC_Clocks.SYSCLK_Frequency;
148 
149     if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
150     {
151       tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
152     }
153     else
154     {
155       tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
156     }
157 
158     tmp = tmp / 10;
159     i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
160     i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
161     i2sodd = (uint16_t) (i2sodd << 8);
162   }
163 
164   if ((i2sdiv < 2) || (i2sdiv > 0xFF))
165   {
166     i2sdiv = 2;
167     i2sodd = 0;
168   }
169 
170   SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
171   tmpreg |= (uint16_t)(I2S_Mode_Select | (uint16_t)(I2S_InitStruct->I2S_Mode | \
172                   (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
173                   (uint16_t)I2S_InitStruct->I2S_CPOL))));
174   SPIx->I2SCFGR = tmpreg;
175 }
176 
177 /*******************************************************************************
178 * Function Name  : SPI_StructInit
179 * Description    : Fills each SPI_InitStruct member with its default value.
180 * Input          : SPI_InitStruct : pointer to a SPI_InitTypeDef structure which
181 *      will be initialized.
182 * Return         : None
183 *******************************************************************************/
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)184 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
185 {
186   SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
187   SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
188   SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
189   SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
190   SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
191   SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
192   SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
193   SPI_InitStruct->SPI_CRCPolynomial = 7;
194 }
195 
196 /*******************************************************************************
197 * Function Name  : I2S_StructInit
198 * Description    : Fills each I2S_InitStruct member with its default value.
199 * Input          : I2S_InitStruct : pointer to a I2S_InitTypeDef structure which
200 *      will be initialized.
201 * Return         : None
202 *******************************************************************************/
I2S_StructInit(I2S_InitTypeDef * I2S_InitStruct)203 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
204 {
205   I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
206   I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
207   I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
208   I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
209   I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
210   I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
211 }
212 
213 /*******************************************************************************
214 * Function Name  : SPI_Cmd
215 * Description    : Enables or disables the specified SPI peripheral.
216 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
217 *                  NewState: ENABLE or DISABLE.
218 * Return         : None
219 *******************************************************************************/
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)220 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
221 {
222   if (NewState != DISABLE)
223   {
224     SPIx->CTLR1 |= CTLR1_SPE_Set;
225   }
226   else
227   {
228     SPIx->CTLR1 &= CTLR1_SPE_Reset;
229   }
230 }
231 
232 /*******************************************************************************
233 * Function Name  : I2S_Cmd
234 * Description    : Enables or disables the specified SPI peripheral (in I2S mode).
235 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
236 *                  NewState: ENABLE or DISABLE.
237 * Return         : None
238 *******************************************************************************/
I2S_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)239 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
240 {
241   if (NewState != DISABLE)
242   {
243     SPIx->I2SCFGR |= I2SCFGR_I2SE_Set;
244   }
245   else
246   {
247     SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset;
248   }
249 }
250 
251 /*******************************************************************************
252 * Function Name  : SPI_I2S_ITConfig
253 * Description    : Enables or disables the specified SPI/I2S interrupts.
254 * Input          : SPIx: where x can be
255 *                    - 1, 2 or 3 in SPI mode.
256 *                    - 2 or 3 in I2S mode.
257 *                  SPI_I2S_IT: specifies the SPI/I2S interrupt source to be
258 *      enabled or disabled.
259 *                    SPI_I2S_IT_TXE: Tx buffer empty interrupt mask.
260 *                    SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask.
261 *                    SPI_I2S_IT_ERR: Error interrupt mask.
262 *                  NewState: ENABLE or DISABLE.
263 * Return         : None
264 *******************************************************************************/
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)265 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
266 {
267   uint16_t itpos = 0, itmask = 0 ;
268 
269   itpos = SPI_I2S_IT >> 4;
270   itmask = (uint16_t)1 << (uint16_t)itpos;
271 
272   if (NewState != DISABLE)
273   {
274     SPIx->CTLR2 |= itmask;
275   }
276   else
277   {
278     SPIx->CTLR2 &= (uint16_t)~itmask;
279   }
280 }
281 
282 /*******************************************************************************
283 * Function Name  : SPI_I2S_DMACmd
284 * Description    : Enables or disables the SPIx/I2Sx DMA interface.
285 * Input          : SPIx: where x can be
286 *                    - 1, 2 or 3 in SPI mode.
287 *                    - 2 or 3 in I2S mode.
288 *                  SPI_I2S_DMAReq: specifies the SPI/I2S DMA transfer request to
289 *      be enabled or disabled.
290 *                    SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request.
291 *                    SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request.
292 *                  NewState: ENABLE or DISABLE.
293 * Return         : None
294 *******************************************************************************/
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)295 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
296 {
297   if (NewState != DISABLE)
298   {
299     SPIx->CTLR2 |= SPI_I2S_DMAReq;
300   }
301   else
302   {
303     SPIx->CTLR2 &= (uint16_t)~SPI_I2S_DMAReq;
304   }
305 }
306 
307 /*******************************************************************************
308 * Function Name  : SPI_I2S_SendData
309 * Description    : Transmits a Data through the SPIx/I2Sx peripheral.
310 * Input          : SPIx: where x can be
311 *                    - 1, 2 or 3 in SPI mode.
312 *                    - 2 or 3 in I2S mode.
313 *                  Data : Data to be transmitted.
314 * Return         : None
315 *******************************************************************************/
SPI_I2S_SendData(SPI_TypeDef * SPIx,uint16_t Data)316 void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
317 {
318   SPIx->DATAR = Data;
319 }
320 
321 /*******************************************************************************
322 * Function Name  : SPI_I2S_ReceiveData
323 * Description    : Returns the most recent received data by the SPIx/I2Sx peripheral.
324 * Input          : SPIx: where x can be
325 *                    - 1, 2 or 3 in SPI mode.
326 *                    - 2 or 3 in I2S mode.
327 *                  Data : Data to be transmitted.
328 * Return         : SPIx->DATAR: The value of the received data.
329 *******************************************************************************/
SPI_I2S_ReceiveData(SPI_TypeDef * SPIx)330 uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
331 {
332   return SPIx->DATAR;
333 }
334 
335 /*******************************************************************************
336 * Function Name  : SPI_NSSInternalSoftwareConfig
337 * Description    : Configures internally by software the NSS pin for the selected SPI.
338 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
339 *                  SPI_NSSInternalSoft:
340 *                    SPI_NSSInternalSoft_Set: Set NSS pin internally.
341 *                    SPI_NSSInternalSoft_Reset: Reset NSS pin internally.
342 * Return         : None
343 *******************************************************************************/
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)344 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
345 {
346   if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
347   {
348     SPIx->CTLR1 |= SPI_NSSInternalSoft_Set;
349   }
350   else
351   {
352     SPIx->CTLR1 &= SPI_NSSInternalSoft_Reset;
353   }
354 }
355 
356 /*******************************************************************************
357 * Function Name  : SPI_SSOutputCmd
358 * Description    : Enables or disables the SS output for the selected SPI.
359 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
360 *                  NewState: new state of the SPIx SS output.
361 * Return         : None
362 *******************************************************************************/
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)363 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
364 {
365   if (NewState != DISABLE)
366   {
367     SPIx->CTLR2 |= CTLR2_SSOE_Set;
368   }
369   else
370   {
371     SPIx->CTLR2 &= CTLR2_SSOE_Reset;
372   }
373 }
374 
375 /*******************************************************************************
376 * Function Name  : SPI_DataSizeConfig
377 * Description    : Configures the data size for the selected SPI.
378 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
379 *                  SPI_DataSize: specifies the SPI data size.
380 *                    SPI_DataSize_16b: Set data frame format to 16bit.
381 *                    SPI_DataSize_8b: Set data frame format to 8bit.
382 * Return         : None
383 *******************************************************************************/
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)384 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
385 {
386   SPIx->CTLR1 &= (uint16_t)~SPI_DataSize_16b;
387   SPIx->CTLR1 |= SPI_DataSize;
388 }
389 
390 /*******************************************************************************
391 * Function Name  : SPI_TransmitCRC
392 * Description    : Transmit the SPIx CRC value.
393 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
394 * Return         : None
395 *******************************************************************************/
SPI_TransmitCRC(SPI_TypeDef * SPIx)396 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
397 {
398   SPIx->CTLR1 |= CTLR1_CRCNext_Set;
399 }
400 
401 /*******************************************************************************
402 * Function Name  : SPI_CalculateCRC
403 * Description    : Enables or disables the CRC value calculation of the transferred bytes.
404 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
405 *                  NewState: new state of the SPIx CRC value calculation.
406 * Return         : None
407 *******************************************************************************/
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)408 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
409 {
410   if (NewState != DISABLE)
411   {
412     SPIx->CTLR1 |= CTLR1_CRCEN_Set;
413   }
414   else
415   {
416     SPIx->CTLR1 &= CTLR1_CRCEN_Reset;
417   }
418 }
419 
420 /*******************************************************************************
421 * Function Name  : SPI_GetCRC
422 * Description    : Returns the transmit or the receive CRC register value for the specified SPI.
423 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
424 *                  SPI_CRC: specifies the CRC register to be read.
425 *                    SPI_CRC_Tx: Selects Tx CRC register.
426 *                    SPI_CRC_Rx: Selects Rx CRC register.
427 * Return         : crcreg: The selected CRC register value.
428 *******************************************************************************/
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)429 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
430 {
431   uint16_t crcreg = 0;
432 
433   if (SPI_CRC != SPI_CRC_Rx)
434   {
435     crcreg = SPIx->TCRCR;
436   }
437   else
438   {
439     crcreg = SPIx->RCRCR;
440   }
441 
442   return crcreg;
443 }
444 
445 /*******************************************************************************
446 * Function Name  : SPI_GetCRCPolynomial
447 * Description    : Returns the CRC Polynomial register value for the specified SPI.
448 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
449 * Return         : SPIx->CRCR: The CRC Polynomial register value.
450 *******************************************************************************/
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)451 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
452 {
453   return SPIx->CRCR;
454 }
455 
456 /*******************************************************************************
457 * Function Name  : SPI_BiDirectionalLineConfig
458 * Description    : Selects the data transfer direction in bi-directional mode
459 *      for the specified SPI.
460 * Input          : SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
461 *                  SPI_Direction: specifies the data transfer direction in
462 *      bi-directional mode.
463 *                    SPI_Direction_Tx: Selects Tx transmission direction.
464 *                    SPI_Direction_Rx: Selects Rx receive direction.
465 * Return         : None
466 *******************************************************************************/
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)467 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
468 {
469   if (SPI_Direction == SPI_Direction_Tx)
470   {
471     SPIx->CTLR1 |= SPI_Direction_Tx;
472   }
473   else
474   {
475     SPIx->CTLR1 &= SPI_Direction_Rx;
476   }
477 }
478 
479 /*******************************************************************************
480 * Function Name  : SPI_I2S_GetFlagStatus
481 * Description    : Checks whether the specified SPI/I2S flag is set or not.
482 * Input          : SPIx: where x can be
483 *                    - 1, 2 or 3 in SPI mode.
484 *                    - 2 or 3 in I2S mode.
485 *                  SPI_I2S_FLAG: specifies the SPI/I2S flag to check.
486 *                    SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
487 *                    SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
488 *                    SPI_I2S_FLAG_BSY: Busy flag.
489 *                    SPI_I2S_FLAG_OVR: Overrun flag.
490 *                    SPI_FLAG_MODF: Mode Fault flag.
491 *                    SPI_FLAG_CRCERR: CRC Error flag.
492 *                    I2S_FLAG_UDR: Underrun Error flag.
493 *                    I2S_FLAG_CHSIDE: Channel Side flag.
494 * Return         : FlagStatus: SET or RESET.
495 *******************************************************************************/
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)496 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
497 {
498   FlagStatus bitstatus = RESET;
499 
500   if ((SPIx->STATR & SPI_I2S_FLAG) != (uint16_t)RESET)
501   {
502     bitstatus = SET;
503   }
504   else
505   {
506     bitstatus = RESET;
507   }
508 
509   return  bitstatus;
510 }
511 
512 /*******************************************************************************
513 * Function Name  : SPI_I2S_ClearFlag
514 * Description    : Clears the SPIx CRC Error (CRCERR) flag.
515 * Input          : SPIx: where x can be
516 *                    - 1, 2 or 3 in SPI mode.
517 *                    - 2 or 3 in I2S mode.
518 *                  SPI_I2S_FLAG: specifies the SPI flag to clear.
519 *                    SPI_FLAG_CRCERR: CRC Error flag.
520 * Return         : FlagStatus: SET or RESET.
521 *******************************************************************************/
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)522 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
523 {
524 	SPIx->STATR = (uint16_t)~SPI_I2S_FLAG;
525 }
526 
527 /*******************************************************************************
528 * Function Name  : SPI_I2S_GetITStatus
529 * Description    : Checks whether the specified SPI/I2S interrupt has occurred or not.
530 * Input          : SPIx: where x can be
531 *                    - 1, 2 or 3 in SPI mode.
532 *                    - 2 or 3 in I2S mode.
533 *                  SPI_I2S_IT: specifies the SPI/I2S interrupt source to check..
534 *                    SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
535 *                    SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
536 *                    SPI_I2S_IT_OVR: Overrun interrupt.
537 *                    SPI_IT_MODF: Mode Fault interrupt.
538 *                    SPI_IT_CRCERR: CRC Error interrupt.
539 *                    I2S_IT_UDR: Underrun Error interrupt.
540 * Return         : FlagStatus: SET or RESET.
541 *******************************************************************************/
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)542 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
543 {
544   ITStatus bitstatus = RESET;
545   uint16_t itpos = 0, itmask = 0, enablestatus = 0;
546 
547   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
548   itmask = SPI_I2S_IT >> 4;
549   itmask = 0x01 << itmask;
550   enablestatus = (SPIx->CTLR2 & itmask) ;
551 
552   if (((SPIx->STATR & itpos) != (uint16_t)RESET) && enablestatus)
553   {
554     bitstatus = SET;
555   }
556   else
557   {
558     bitstatus = RESET;
559   }
560 
561   return bitstatus;
562 }
563 
564 /*******************************************************************************
565 * Function Name  : SPI_I2S_ClearITPendingBit
566 * Description    : Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
567 * Input          : SPIx: where x can be
568 *                    - 1, 2 or 3 in SPI mode.
569 *                  SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.
570 *                    SPI_IT_CRCERR: CRC Error interrupt.
571 * Return         : FlagStatus: SET or RESET.
572 *******************************************************************************/
SPI_I2S_ClearITPendingBit(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)573 void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
574 {
575   uint16_t itpos = 0;
576 
577   itpos = 0x01 << (SPI_I2S_IT & 0x0F);
578   SPIx->STATR = (uint16_t)~itpos;
579 }
580 
581 
582 
583 
584 
585 
586 
587 
588