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