1 /*!
2  * @file        apm32f0xx_spi.c
3  *
4  * @brief       This file contains all the functions for the SPI peripheral
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f0xx_spi.h"
27 #include "apm32f0xx_rcm.h"
28 
29 /** @addtogroup APM32F0xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup SPI_Driver SPI Driver
34   @{
35 */
36 
37 /** @defgroup SPI_Macros Macros
38   @{
39 */
40 
41 /**@} end of group SPI_Macros */
42 
43 /** @defgroup SPI_Enumerations Enumerations
44   @{
45 */
46 
47 /**@} end of group SPI_Enumerations */
48 
49 /** @defgroup SPI_Structures Structures
50   @{
51 */
52 
53 /**@} end of group SPI_Structures */
54 
55 /** @defgroup SPI_Variables Variables
56   @{
57 */
58 
59 /**@} end of group SPI_Variables */
60 
61 /** @defgroup SPI_Functions Functions
62   @{
63 */
64 
65 /*!
66  * @brief       Set the SPI peripheral registers to their default reset values
67  *
68  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
69  *
70  * @retval      None
71  */
SPI_Reset(SPI_T * spi)72 void SPI_Reset(SPI_T* spi)
73 {
74     if (spi == SPI1)
75     {
76         RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SPI1);
77         RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SPI1);
78     }
79     else
80     {
81         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_SPI2);
82         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_SPI2);
83     }
84 }
85 
86 /*!
87  * @brief       Config the SPI peripheral according to the specified parameters in the adcConfig
88  *
89  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
90  *
91  * @param       spiConfig:  Pointer to a SPI_Config_T structure that
92  *                          contains the configuration information for the SPI peripheral
93  *
94  * @retval      None
95  */
SPI_Config(SPI_T * spi,SPI_Config_T * spiConfig)96 void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig)
97 {
98     spi->CTRL1_B.MSMCFG = spiConfig->mode;
99     spi->CTRL2_B.DSCFG   = spiConfig->length;
100     spi->CTRL1_B.CPHA  = spiConfig->phase;
101     spi->CTRL1_B.CPOL  = spiConfig->polarity;
102     spi->CTRL1_B.SSEN = spiConfig->slaveSelect;
103     spi->CTRL1_B.LSBSEL = spiConfig->firstBit;
104 
105     spi->CTRL1 &= (uint16_t)~0xC400;
106     spi->CTRL1 |= (uint32_t)spiConfig->direction;
107 
108     spi->CTRL1_B.BRSEL = spiConfig->baudrateDiv;
109 
110     spi->CRCPOLY |= spiConfig->crcPolynomial;
111 }
112 
113 /*!
114  * @brief       Config the SPI peripheral according to the specified parameters in the adcConfig
115  *
116  * @param       spi:    Select the the SPI peripheral.It can be SPI1
117  *
118  * @param       i2sConfig:  Pointer to a SPI_Config_T structure that
119  *                          contains the configuration information for the SPI peripheral
120  *
121  * @retval      None
122  */
I2S_Config(SPI_T * spi,I2S_Config_T * i2sConfig)123 void I2S_Config(SPI_T* spi, I2S_Config_T* i2sConfig)
124 {
125     uint16_t i2sDiv = 2, i2sOdd = 0, i2sLen = 1;
126     uint32_t sourceClock = 0, value = 0, temp = 0;
127 
128     spi->I2SPSC = 0x0002;
129     spi->I2SCFG &= 0xF040;
130     temp = spi->I2SCFG;
131 
132     if (i2sConfig->audioDiv == I2S_AUDIO_DIV_DEFAULT)
133     {
134         i2sDiv = (uint16_t)2;
135         i2sOdd = (uint16_t)0;
136     }
137     else
138     {
139         if (i2sConfig->length == I2S_DATA_LENGTH_16B)
140         {
141             i2sLen = 1;
142         }
143         else
144         {
145             i2sLen = 2;
146         }
147 
148         sourceClock = RCM_ReadSYSCLKFreq();
149 
150         if (i2sConfig->MCLKOutput == I2S_MCLK_OUTPUT_ENABLE)
151         {
152             value = (uint16_t)(((((sourceClock / 256) * 10) / i2sConfig->audioDiv)) + 5);
153         }
154         else
155         {
156             value = (uint16_t)(((((sourceClock / (32 * i2sLen)) * 10) / i2sConfig->audioDiv)) + 5);
157         }
158 
159         value = value / 10;
160         i2sOdd = (uint16_t)(value & (uint16_t)0x0001);
161         i2sDiv = (uint16_t)((value - i2sOdd) / 2);
162     }
163 
164     if ((i2sDiv < 2) || (i2sDiv > 0xFF))
165     {
166         i2sDiv = 2;
167         i2sOdd = 0;
168     }
169 
170     spi->I2SPSC_B.I2SPSC = i2sDiv;
171     spi->I2SPSC_B.ODDPSC = i2sOdd;
172     spi->I2SPSC_B.MCOEN  = i2sConfig->MCLKOutput;
173     spi->I2SCFG_B.MODESEL = BIT_SET;
174     spi->I2SCFG_B.I2SMOD = i2sConfig->mode;
175     spi->I2SCFG_B.CPOL = i2sConfig->polarity;
176 
177     temp = (uint16_t)((uint16_t)i2sConfig->standard | (uint16_t)i2sConfig->length);
178     spi->I2SCFG |= temp;
179 }
180 
181 /*!
182  * @brief       Fills each spiConfig member with its default value
183  *
184  * @param       spiConfig:  Pointer to a SPI_Config_T structure which will be initialized
185  *
186  * @retval      None
187  */
SPI_ConfigStructInit(SPI_Config_T * spiConfig)188 void SPI_ConfigStructInit(SPI_Config_T* spiConfig)
189 {
190     spiConfig->mode      = SPI_MODE_SLAVE;
191     spiConfig->length    = SPI_DATA_LENGTH_8B;
192     spiConfig->phase     = SPI_CLKPHA_1EDGE;
193     spiConfig->polarity  = SPI_CLKPOL_HIGH;
194     spiConfig->slaveSelect = SPI_SSC_DISABLE;
195     spiConfig->firstBit    = SPI_FIRST_BIT_MSB;
196     spiConfig->direction   = SPI_DIRECTION_2LINES_FULLDUPLEX;
197     spiConfig->baudrateDiv = SPI_BAUDRATE_DIV_2;
198     spiConfig->crcPolynomial = 7;
199 }
200 
201 /*!
202  * @brief       Fills each i2sConfig member with its default value
203  *
204  * @param       i2sConfig:  Pointer to a SPI_Config_T structure which will be initialized
205  *
206  * @retval      None
207  */
I2S_ConfigStructInit(I2S_Config_T * i2sConfig)208 void I2S_ConfigStructInit(I2S_Config_T* i2sConfig)
209 {
210     i2sConfig->mode       =  I2S_MODE_SLAVER_TX;
211     i2sConfig->standard   =  I2S_STANDARD_PHILIPS;
212     i2sConfig->length     =  I2S_DATA_LENGTH_16B;
213     i2sConfig->MCLKOutput =  I2S_MCLK_OUTPUT_DISABLE;
214     i2sConfig->audioDiv   =  I2S_AUDIO_DIV_DEFAULT;
215     i2sConfig->polarity   =  I2S_CLKPOL_LOW;
216 }
217 
218 /*!
219  * @brief       Enable the SPI peripheral
220  *
221  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
222  *
223  * @retval      None
224  */
SPI_Enable(SPI_T * spi)225 void SPI_Enable(SPI_T* spi)
226 {
227     spi->CTRL1_B.SPIEN = BIT_SET;
228 }
229 
230 /*!
231  * @brief       Disable the SPI peripheral
232  *
233  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
234  *
235  * @retval      None
236  */
SPI_Disable(SPI_T * spi)237 void SPI_Disable(SPI_T* spi)
238 {
239     spi->CTRL1_B.SPIEN = BIT_RESET;
240 }
241 
242 /*!
243  * @brief       Enable the SPI peripheral
244  *
245  * @param       spi:    Select the the SPI peripheral.It can be SPI1
246  *
247  * @retval      None
248  *
249  * @note        Not supported for APM32F030 devices.
250  */
I2S_Enable(SPI_T * spi)251 void I2S_Enable(SPI_T* spi)
252 {
253     spi->I2SCFG_B.I2SEN = BIT_SET;
254 }
255 
256 /*!
257  * @brief       Disable the SPI peripheral
258  *
259  * @param       spi:    Select the the SPI peripheral.It can be SPI1
260  *
261  * @retval      None
262  *
263  * @note        Not supported for APM32F030 devices.
264  */
I2S_Disable(SPI_T * spi)265 void I2S_Disable(SPI_T* spi)
266 {
267     spi->I2SCFG_B.I2SEN = BIT_RESET;
268 }
269 
270 /*!
271  * @brief       Enable the frame format mode
272  *
273  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
274  *
275  * @retval      None
276  */
SPI_EnableFrameFormatMode(SPI_T * spi)277 void SPI_EnableFrameFormatMode(SPI_T* spi)
278 {
279     spi->CTRL2_B.FRFCFG = BIT_SET;
280 }
281 
282 /*!
283  * @brief       Disable the frame format mode
284  *
285  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
286  *
287  * @retval      None
288  */
SPI_DisableFrameFormatMode(SPI_T * spi)289 void SPI_DisableFrameFormatMode(SPI_T* spi)
290 {
291     spi->CTRL2_B.FRFCFG = BIT_RESET;
292 }
293 
294 /*!
295  * @brief       Configures the SPI data length
296  *
297  * @param       length:  specifies the SPI length
298  *                          The parameter can be one of following values:
299  *                          @arg SPI_DATA_LENGTH_4B:  Set data length to 4 bits
300  *                          @arg SPI_DATA_LENGTH_5B:  Set data length to 5 bits
301  *                          @arg SPI_DATA_LENGTH_6B:  Set data length to 6 bits
302  *                          @arg SPI_DATA_LENGTH_7B:  Set data length to 7 bits
303  *                          @arg SPI_DATA_LENGTH_8B:  Set data length to 8 bits
304  *                          @arg SPI_DATA_LENGTH_9B:  Set data length to 9 bits
305  *                          @arg SPI_DATA_LENGTH_10B:  Set data length to 10 bits
306  *                          @arg SPI_DATA_LENGTH_11B:  Set data length to 11 bits
307  *                          @arg SPI_DATA_LENGTH_12B:  Set data length to 12 bits
308  *                          @arg SPI_DATA_LENGTH_13B:  Set data length to 13 bits
309  *                          @arg SPI_DATA_LENGTH_14B:  Set data length to 14 bits
310  *                          @arg SPI_DATA_LENGTH_15B:  Set data length to 15 bits
311  *                          @arg SPI_DATA_LENGTH_16B:  Set data length to 16 bits
312  *
313  * @retval      None
314  */
SPI_ConfigDatalength(SPI_T * spi,uint8_t length)315 void SPI_ConfigDatalength(SPI_T* spi, uint8_t length)
316 {
317     spi->CTRL2_B.DSCFG = (uint8_t)length;
318 }
319 
320 /*!
321  * @brief       Configures the FIFO reception threshold
322  *
323  * @param       threshold: selects the SPI FIFO reception threshold
324  *                         The parameter can be one of following values:
325  *                         @arg SPI_RXFIFO_HALF:    FIFO level is greater than or equal to 1/2 (16-bit)
326  *                         @arg SPI_RXFIFO_QUARTER: FIFO level is greater than or equal to 1/4 (8-bit)
327  *
328  * @retval      None
329  */
SPI_ConfigFIFOThreshold(SPI_T * spi,SPI_RXFIFO_T threshold)330 void SPI_ConfigFIFOThreshold(SPI_T* spi, SPI_RXFIFO_T  threshold)
331 {
332     spi->CTRL2_B.FRTCFG  =  threshold;
333 }
334 
335 /*!
336  * @brief       Enable the data transfer direction
337  *
338  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
339  *
340  * @retval      None
341  */
SPI_EnableOutputDirection(SPI_T * spi)342 void SPI_EnableOutputDirection(SPI_T* spi)
343 {
344     spi->CTRL1_B.BMOEN  =  BIT_SET;
345 }
346 
347 /*!
348  * @brief       Disable the data transfer direction
349  *
350  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
351  *
352  * @retval      None
353  */
SPI_DisableOutputDirection(SPI_T * spi)354 void SPI_DisableOutputDirection(SPI_T* spi)
355 {
356     spi->CTRL1_B.BMOEN  =  BIT_RESET;
357 }
358 
359 /*!
360  * @brief       Enable internal slave select
361  *
362  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
363  *
364  * @retval      None
365  */
SPI_EnableInternalSlave(SPI_T * spi)366 void SPI_EnableInternalSlave(SPI_T* spi)
367 {
368     spi->CTRL1_B.ISSEL = BIT_SET;
369 }
370 
371 /*!
372  * @brief       Disable internal slave select
373  *
374  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
375  *
376  * @retval      None
377  */
SPI_DisableInternalSlave(SPI_T * spi)378 void SPI_DisableInternalSlave(SPI_T* spi)
379 {
380     spi->CTRL1_B.ISSEL = BIT_RESET;
381 }
382 
383 /*!
384  * @brief       Enable the SS output mode
385  *
386  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
387  *
388  * @retval      None
389  */
SPI_EnableSSoutput(SPI_T * spi)390 void SPI_EnableSSoutput(SPI_T* spi)
391 {
392     spi->CTRL2_B.SSOEN = BIT_SET;
393 }
394 
395 /*!
396  * @brief       Disable the SS output mode
397  *
398  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
399  *
400  * @retval      None
401  */
SPI_DisableSSoutput(SPI_T * spi)402 void SPI_DisableSSoutput(SPI_T* spi)
403 {
404     spi->CTRL2_B.SSOEN = BIT_RESET;
405 }
406 
407 /*!
408  * @brief       Enable the NSS pulse management mode
409  *
410  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
411  *
412  * @retval      None
413  */
SPI_EnableNSSPulse(SPI_T * spi)414 void SPI_EnableNSSPulse(SPI_T* spi)
415 {
416     spi->CTRL2_B.NSSPEN = BIT_SET;
417 }
418 
419 /*!
420  * @brief       Disable the NSS pulse management mode
421  *
422  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
423  *
424  * @retval      None
425  */
SPI_DisableNSSPulse(SPI_T * spi)426 void SPI_DisableNSSPulse(SPI_T* spi)
427 {
428     spi->CTRL2_B.NSSPEN = BIT_RESET;
429 }
430 
431 /*!
432  * @brief       Transmits a Data
433  *
434  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
435  *
436  * @param       data:   Byte to be transmitted
437  *
438  * @retval      None
439  */
SPI_I2S_TxData16(SPI_T * spi,uint16_t data)440 void SPI_I2S_TxData16(SPI_T* spi, uint16_t data)
441 {
442     spi->DATA = (uint16_t)data;
443 }
444 
445 /*!
446  * @brief       Transmits a  uint8_t Data
447  *
448  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
449  *
450  * @param       data:   Byte to be transmitted
451  *
452  * @retval      None
453  */
SPI_TxData8(SPI_T * spi,uint8_t data)454 void SPI_TxData8(SPI_T* spi, uint8_t data)
455 {
456     *((uint8_t*) & (spi->DATA)) = data;
457 }
458 
459 /*!
460  * @brief       Returns the most recent received data by the SPI peripheral
461  *
462  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
463  *
464  * @param       None
465  *
466  * @retval      The value of the received data
467  */
SPI_I2S_RxData16(SPI_T * spi)468 uint16_t SPI_I2S_RxData16(SPI_T* spi)
469 {
470     return ((uint16_t)spi->DATA);
471 }
472 
473 /*!
474  * @brief       Returns the most recent received data by the SPI peripheral
475  *
476  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
477  *
478  * @param       None
479  *
480  * @retval      The value of the received data
481  */
SPI_RxData8(SPI_T * spi)482 uint8_t SPI_RxData8(SPI_T* spi)
483 {
484     return  *((uint8_t*) & (spi->DATA));
485 }
486 
487 /*!
488  * @brief       Selects the data transfer direction
489  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
490  * @param       crcLength: selects the SPI transfer direction
491  *                         The parameter can be one of following values:
492  *                         @arg SPI_CRC_LENGTH_8B:  8-bit CRC length
493  *                         @arg SPI_CRC_LENGTH_16B: 16-bit CRC length
494  *
495  * @retval      None
496  */
SPI_CRCLength(SPI_T * spi,SPI_CRC_LENGTH_T crcLength)497 void SPI_CRCLength(SPI_T* spi, SPI_CRC_LENGTH_T  crcLength)
498 {
499     spi->CTRL1_B.CRCLSEL  =  crcLength;
500 }
501 
502 /*!
503  * @brief       Enable the CRC value calculation
504  *
505  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
506  *
507  * @retval      None
508  */
SPI_EnableCRC(SPI_T * spi)509 void SPI_EnableCRC(SPI_T* spi)
510 {
511     spi->CTRL1_B.CRCEN = BIT_SET;
512 }
513 
514 /*!
515  * @brief       Disable the CRC value calculation
516  *
517  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
518  *
519  * @retval      None
520  */
SPI_DisableCRC(SPI_T * spi)521 void SPI_DisableCRC(SPI_T* spi)
522 {
523     spi->CTRL1_B.CRCEN = BIT_RESET;
524 }
525 
526 /*!
527  * @brief       Transmit CRC value
528  *
529  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
530  *
531  * @retval      None
532  */
SPI_TxCRC(SPI_T * spi)533 void SPI_TxCRC(SPI_T* spi)
534 {
535     spi->CTRL1_B.CRCNXT = BIT_SET;
536 }
537 
538 /*!
539  * @brief       Returns the receive CRC register value
540  *
541  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
542  *
543  * @retval      None
544  *
545  * @note        None
546  */
SPI_ReadRxCRC(SPI_T * spi)547 uint16_t SPI_ReadRxCRC(SPI_T* spi)
548 {
549     return (uint16_t)spi->RXCRC;
550 }
551 
552 /*!
553  * @brief       Returns the transmit CRC register value
554  *
555  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
556  *
557  * @retval      None
558  *
559  * @note        None
560  */
SPI_ReadTxCRC(SPI_T * spi)561 uint16_t SPI_ReadTxCRC(SPI_T* spi)
562 {
563     return (uint16_t)spi->TXCRC;
564 }
565 
566 /*!
567  * @brief       Returns the CRC Polynomial register value
568  *
569  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
570  *
571  * @retval      None
572  */
SPI_ReadCRCPolynomial(SPI_T * spi)573 uint16_t SPI_ReadCRCPolynomial(SPI_T* spi)
574 {
575     return (uint16_t)spi->CRCPOLY;
576 }
577 
578 /*!
579  * @brief       Enable the DMA Rx buffer
580  *
581  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
582  *
583  * @retval      None
584  */
SPI_EnableDMARxBuffer(SPI_T * spi)585 void SPI_EnableDMARxBuffer(SPI_T* spi)
586 {
587     spi->CTRL2_B.RXDEN = BIT_SET;
588 }
589 
590 /*!
591  * @brief       Disable the DMA Rx buffer
592  *
593  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
594  *
595  * @retval      None
596  */
SPI_DisableDMARxBuffer(SPI_T * spi)597 void SPI_DisableDMARxBuffer(SPI_T* spi)
598 {
599     spi->CTRL2_B.RXDEN = BIT_RESET;
600 }
601 
602 /*!
603  * @brief       Enable the DMA Tx buffer
604  *
605  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
606  *
607  * @retval      None
608  */
SPI_EnableDMATxBuffer(SPI_T * spi)609 void SPI_EnableDMATxBuffer(SPI_T* spi)
610 {
611     spi->CTRL2_B.TXDEN = BIT_SET;
612 }
613 
614 /*!
615  * @brief       Disable the DMA Tx buffer
616  *
617  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
618  *
619  * @retval      None
620  */
SPI_DisableDMATxBuffer(SPI_T * spi)621 void SPI_DisableDMATxBuffer(SPI_T* spi)
622 {
623     spi->CTRL2_B.TXDEN = BIT_RESET;
624 }
625 
626 /*!
627  * @brief       Selects the last DMA transfer is type(Even/Odd)
628  *
629  * @param       crcLength: specifies the SPI last DMA transfers
630  *                         The parameter can be one of following values:
631  *                         @arg SPI_LAST_DMA_TXRXEVEN:    transmission Even reception Even
632  *                         @arg SPI_LAST_DMA_TXEVENRXODD: transmission Even reception Odd
633  *                         @arg SPI_LAST_DMA_TXODDRXEVEN: transmission Odd reception Even
634  *                         @arg SPI_LAST_DMA_TXRXODD:     transmission Odd reception Odd
635  *
636  * @retval      None
637  */
SPI_LastDMATransfer(SPI_T * spi,SPI_LAST_DMA_T lastDMA)638 void SPI_LastDMATransfer(SPI_T* spi, SPI_LAST_DMA_T  lastDMA)
639 {
640     spi->CTRL2 &= 0x9FFF;
641     spi->CTRL2 |= (uint16_t)lastDMA;
642 }
643 
644 /*!
645  * @brief       Returns the SPI Transmission FIFO filled level
646  *
647  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
648  *
649  * @retval      Transmission FIFO filled level:
650  *              SPI_TXFIFO_LEVEL_EMPTY:   Transmission FIFO filled level is empty
651  *              SPI_TXFIFO_LEVEL_QUARTER: Transmission FIFO filled level is more than quarter
652  *              SPI_TXFIFO_LEVEL_HALF:    Transmission FIFO filled level is more than half
653  *              SPI_TXFIFO_LEVEL_FULL:    Transmission FIFO filled level is full
654  */
SPI_ReadTransmissionFIFOLeve(SPI_T * spi)655 uint8_t SPI_ReadTransmissionFIFOLeve(SPI_T* spi)
656 {
657     return (uint8_t)((spi->STS_B.FTLSEL & 0x03));
658 }
659 
660 /*!
661  * @brief       Returns the SPI Reception FIFO filled level
662  *
663  * @param       spi:    Select the the SPI peripheral.It can be SPI1/SPI2
664  *
665  * @retval      Reception FIFO filled level:
666  *              SPI_RXFIFO_LEVEL_EMPTY:   Reception FIFO filled level is empty
667  *              SPI_RXFIFO_LEVEL_QUARTER: Reception FIFO filled level is more than quarter
668  *              SPI_RXFIFO_LEVEL_HALF:    Reception FIFO filled level is more than half
669  *              SPI_RXFIFO_LEVEL_FULL:    Reception FIFO filled level is full
670  */
SPI_ReadReceptionFIFOLeve(SPI_T * spi)671 uint8_t SPI_ReadReceptionFIFOLeve(SPI_T* spi)
672 {
673     return (uint8_t)((spi->STS_B.FRLSEL & 0x03));
674 }
675 
676 /*!
677  * @brief       Enable the SPI interrupts
678  *
679  * @param       interrupt:  Specifies the SPI interrupts sources
680  *                          The parameter can be combination of following values:
681  *                          @arg SPI_INT_ERRIE:    Error interrupt
682  *                          @arg SPI_INT_RXBNEIE:  Receive buffer not empty interrupt
683  *                          @arg SPI_INT_TXBEIE:   Transmit buffer empty interrupt
684  *
685  * @retval      None
686  */
SPI_EnableInterrupt(SPI_T * spi,uint8_t interrupt)687 void SPI_EnableInterrupt(SPI_T* spi, uint8_t interrupt)
688 {
689     spi->CTRL2 |= (uint8_t)interrupt;
690 }
691 
692 /*!
693  * @brief       Disable the SPI interrupts
694  *
695  * @param       interrupt:  Specifies the SPI interrupts sources
696  *                          The parameter can be combination of following values:
697  *                          @arg SPI_INT_ERRIE:    Error interrupt
698  *                          @arg SPI_INT_RXBNEIE:  Receive buffer not empty interrupt
699  *                          @arg SPI_INT_TXBEIE:   Transmit buffer empty interrupt
700  *
701  * @retval      None
702  */
SPI_DisableInterrupt(SPI_T * spi,uint8_t interrupt)703 void SPI_DisableInterrupt(SPI_T* spi, uint8_t interrupt)
704 {
705     spi->CTRL2 &= (uint8_t)~interrupt;
706 }
707 
708 /*!
709  * @brief       Checks whether the specified SPI flag is set or not
710  *
711  * @param       flag:   Specifies the flag to check
712  *                      This parameter can be one of the following values:
713  *                      @arg SPI_FLAG_RXBNE:    Receive buffer not empty flag
714  *                      @arg SPI_FLAG_TXBE:     Transmit buffer empty flag
715  *                      @arg I2S_FLAG_CHDIR:    Channel direction flag
716  *                      @arg I2S_FLAG_UDR:      Underrun flag
717  *                      @arg SPI_FLAG_CRCE:     CRC error flag
718  *                      @arg SPI_FLAG_MME:      Master mode error flag
719  *                      @arg SPI_FLAG_OVR:      Receive Overrun flag
720  *                      @arg SPI_FLAG_BUSY:     Busy flag
721  *                      @arg SPI_FLAG_FFE:      Frame format error flag
722  *
723  * @retval      The new state of flag (SET or RESET)
724  */
SPI_ReadStatusFlag(SPI_T * spi,SPI_FLAG_T flag)725 uint8_t SPI_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag)
726 {
727     uint16_t status;
728 
729     status = (uint16_t)(spi->STS & flag);
730 
731     if (status == flag)
732     {
733         return SET;
734     }
735 
736     return RESET;
737 }
738 
739 /*!
740  * @brief       Clear the specified SPI flag
741  *
742  * @param       flag:   Specifies the flag to clear
743  *                      This parameter can be any combination of the following values:
744  *                      @arg SPI_FLAG_CRCE:     CRC error flag
745 
746  * @retval      None
747  */
SPI_ClearStatusFlag(SPI_T * spi,uint8_t flag)748 void SPI_ClearStatusFlag(SPI_T* spi, uint8_t flag)
749 {
750     spi->STS &= (uint32_t)~flag;
751 }
752 
753 /*!
754  * @brief       Checks whether the specified interrupt has occurred or not
755  *
756  * @param       flag:   Specifies the SPI interrupt pending bit to check
757  *                      This parameter can be one of the following values:
758  *                      @arg SPI_INT_FLAG_RXBNE:    Receive buffer not empty flag
759  *                      @arg SPI_INT_FLAG_TXBE:     Transmit buffer empty flag
760  *                      @arg SPI_INT_FLAG_UDR:      Underrun flag interrupt flag
761  *                      @arg SPI_INT_FLAG_MME:      Master mode error flag
762  *                      @arg SPI_INT_FLAG_OVR:      Receive Overrun flag
763  *                      @arg SPI_INT_FLAG_FFE:      Frame format error interrupt flag
764  *
765  * @retval      None
766  */
SPI_ReadIntFlag(SPI_T * spi,SPI_INT_FLAG_T flag)767 uint8_t SPI_ReadIntFlag(SPI_T* spi, SPI_INT_FLAG_T flag)
768 {
769     uint32_t intEnable;
770     uint32_t intStatus;
771 
772     intEnable = (uint32_t)(spi->CTRL2 & (uint32_t)(flag >> 16));
773 
774     intStatus = (uint32_t)(spi->STS & (uint32_t)(flag & 0x1ff));
775 
776     if (intEnable && intStatus)
777     {
778         return SET;
779     }
780 
781     return RESET;
782 }
783 
784 /**@} end of group SPI_Functions*/
785 /**@} end of group SPI_Driver*/
786 /**@} end of group APM32F0xx_StdPeriphDriver*/
787