1 /*!
2 \file gd32f3x0_spi.c
3 \brief SPI driver
4
5 \version 2017-06-06, V1.0.0, firmware for GD32F3x0
6 \version 2019-06-01, V2.0.0, firmware for GD32F3x0
7 \version 2020-09-30, V2.1.0, firmware for GD32F3x0
8 */
9
10 /*
11 Copyright (c) 2020, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #include "gd32f3x0_spi.h"
38
39 #define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */
40 #define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */
41
42 #define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */
43
44 /*!
45 \brief reset SPI and I2S
46 \param[in] spi_periph: SPIx(x=0,1)
47 \param[out] none
48 \retval none
49 */
spi_i2s_deinit(uint32_t spi_periph)50 void spi_i2s_deinit(uint32_t spi_periph)
51 {
52 switch(spi_periph){
53 case SPI0:
54 /* reset SPI0 and I2S0 */
55 rcu_periph_reset_enable(RCU_SPI0RST);
56 rcu_periph_reset_disable(RCU_SPI0RST);
57 break;
58 case SPI1:
59 /* reset SPI1 */
60 rcu_periph_reset_enable(RCU_SPI1RST);
61 rcu_periph_reset_disable(RCU_SPI1RST);
62 break;
63 default :
64 break;
65 }
66 }
67
68 /*!
69 \brief initialize the parameters of SPI struct with the default values
70 \param[in] spi_struct: SPI parameter stuct
71 \param[out] none
72 \retval none
73 */
spi_struct_para_init(spi_parameter_struct * spi_struct)74 void spi_struct_para_init(spi_parameter_struct* spi_struct)
75 {
76 /* set the SPI struct with the default values */
77 spi_struct->device_mode = SPI_SLAVE;
78 spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX;
79 spi_struct->frame_size = SPI_FRAMESIZE_8BIT;
80 spi_struct->nss = SPI_NSS_HARD;
81 spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
82 spi_struct->prescale = SPI_PSC_2;
83 }
84
85 /*!
86 \brief initialize SPI parameter
87 \param[in] spi_periph: SPIx(x=0,1)
88 \param[in] spi_struct: SPI parameter initialization stuct members of the structure
89 and the member values are shown as below:
90 device_mode: SPI_MASTER, SPI_SLAVE
91 trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY,
92 SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT
93 frame_size: SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT
94 nss: SPI_NSS_SOFT, SPI_NSS_HARD
95 endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB
96 clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE
97 SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE
98 prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256)
99 \param[out] none
100 \retval none
101 */
spi_init(uint32_t spi_periph,spi_parameter_struct * spi_struct)102 void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct)
103 {
104 uint32_t reg = 0U;
105 reg = SPI_CTL0(spi_periph);
106 reg &= SPI_INIT_MASK;
107
108 /* select SPI as master or slave */
109 reg |= spi_struct->device_mode;
110 /* select SPI transfer mode */
111 reg |= spi_struct->trans_mode;
112 /* select SPI frame size */
113 reg |= spi_struct->frame_size;
114 /* select SPI NSS use hardware or software */
115 reg |= spi_struct->nss;
116 /* select SPI LSB or MSB */
117 reg |= spi_struct->endian;
118 /* select SPI polarity and phase */
119 reg |= spi_struct->clock_polarity_phase;
120 /* select SPI prescale to adjust transmit speed */
121 reg |= spi_struct->prescale;
122
123 /* write to SPI_CTL0 register */
124 SPI_CTL0(spi_periph) = (uint32_t)reg;
125
126 /* select SPI mode */
127 SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
128 }
129
130 /*!
131 \brief enable SPI
132 \param[in] spi_periph: SPIx(x=0,1)
133 \param[out] none
134 \retval none
135 */
spi_enable(uint32_t spi_periph)136 void spi_enable(uint32_t spi_periph)
137 {
138 SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
139 }
140
141 /*!
142 \brief disable SPI
143 \param[in] spi_periph: SPIx(x=0,1)
144 \param[out] none
145 \retval none
146 */
spi_disable(uint32_t spi_periph)147 void spi_disable(uint32_t spi_periph)
148 {
149 SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
150 }
151
152
153 #ifdef GD32F350
154 /*!
155 \brief initialize I2S parameter
156 \param[in] spi_periph: SPI0
157 \param[in] mode: I2S operation mode
158 only one parameter can be selected which is shown as below:
159 \arg I2S_MODE_SLAVETX: I2S slave transmit mode
160 \arg I2S_MODE_SLAVERX: I2S slave receive mode
161 \arg I2S_MODE_MASTERTX: I2S master transmit mode
162 \arg I2S_MODE_MASTERRX: I2S master receive mode
163 \param[in] standard: I2S standard
164 only one parameter can be selected which is shown as below:
165 \arg I2S_STD_PHILLIPS: I2S phillips standard
166 \arg I2S_STD_MSB: I2S MSB standard
167 \arg I2S_STD_LSB: I2S LSB standard
168 \arg I2S_STD_PCMSHORT: I2S PCM short standard
169 \arg I2S_STD_PCMLONG: I2S PCM long standard
170 \param[in] ckpl: I2S idle state clock polarity
171 only one parameter can be selected which is shown as below:
172 \arg I2S_CKPL_LOW: I2S clock polarity low level
173 \arg I2S_CKPL_HIGH: I2S clock polarity high level
174 \param[out] none
175 \retval none
176 */
i2s_init(uint32_t spi_periph,uint32_t mode,uint32_t standard,uint32_t ckpl)177 void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl)
178 {
179 uint32_t reg = 0U;
180 reg = SPI_I2SCTL(spi_periph);
181 reg &= I2S_INIT_MASK;
182
183 /* enable I2S mode */
184 reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
185 /* select I2S mode */
186 reg |= (uint32_t)mode;
187 /* select I2S standard */
188 reg |= (uint32_t)standard;
189 /* select I2S polarity */
190 reg |= (uint32_t)ckpl;
191
192 /* write to SPI_I2SCTL register */
193 SPI_I2SCTL(spi_periph) = (uint32_t)reg;
194 }
195
196 /*!
197 \brief configure I2S prescaler
198 \param[in] spi_periph: SPI0
199 \param[in] audiosample: I2S audio sample rate
200 only one parameter can be selected which is shown as below:
201 \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz
202 \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz
203 \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz
204 \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz
205 \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz
206 \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz
207 \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz
208 \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz
209 \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz
210 \param[in] frameformat: I2S data length and channel length
211 only one parameter can be selected which is shown as below:
212 \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
213 \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
214 \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
215 \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
216 \param[in] mckout: I2S master clock output
217 only one parameter can be selected which is shown as below:
218 \arg I2S_MCKOUT_ENABLE: I2S master clock output enable
219 \arg I2S_MCKOUT_DISABLE: I2S master clock output disable
220 \param[out] none
221 \retval none
222 */
i2s_psc_config(uint32_t spi_periph,uint32_t audiosample,uint32_t frameformat,uint32_t mckout)223 void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout)
224 {
225 uint32_t i2sdiv = 2U, i2sof = 0U;
226 uint32_t clks = 0U;
227 uint32_t i2sclock = 0U;
228
229 /* deinit SPI_I2SPSC register */
230 SPI_I2SPSC(spi_periph) = SPI_I2SPSC_DEFAULT_VALUE;
231
232 /* get system clock */
233 i2sclock = rcu_clock_freq_get(CK_SYS);
234
235 /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
236 if(I2S_MCKOUT_ENABLE == mckout){
237 clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample);
238 }else{
239 if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){
240 clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample);
241 }else{
242 clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample);
243 }
244 }
245
246 /* remove the floating point */
247 clks = (clks + 5U) / 10U;
248 i2sof = (clks & 0x00000001U);
249 i2sdiv = ((clks - i2sof) / 2U);
250 i2sof = (i2sof << 8U);
251
252 /* set the default values */
253 if((i2sdiv < 2U) || (i2sdiv > 255U)){
254 i2sdiv = 2U;
255 i2sof = 0U;
256 }
257
258 /* configure SPI_I2SPSC */
259 SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | mckout);
260
261 /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */
262 SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN));
263 /* configure data frame format */
264 SPI_I2SCTL(spi_periph) |= (uint32_t)frameformat;
265 }
266
267 /*!
268 \brief enable I2S
269 \param[in] spi_periph: SPI0
270 \param[out] none
271 \retval none
272 */
i2s_enable(uint32_t spi_periph)273 void i2s_enable(uint32_t spi_periph)
274 {
275 SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
276 }
277
278 /*!
279 \brief disable I2S
280 \param[in] spi_periph: SPI0
281 \param[out] none
282 \retval none
283 */
i2s_disable(uint32_t spi_periph)284 void i2s_disable(uint32_t spi_periph)
285 {
286 SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
287 }
288
289 #endif /* GD32F350 */
290
291 /*!
292 \brief enable SPI NSS output
293 \param[in] spi_periph: SPIx(x=0,1)
294 \param[out] none
295 \retval none
296 */
spi_nss_output_enable(uint32_t spi_periph)297 void spi_nss_output_enable(uint32_t spi_periph)
298 {
299 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
300 }
301
302 /*!
303 \brief disable SPI NSS output
304 \param[in] spi_periph: SPIx(x=0,1)
305 \param[out] none
306 \retval none
307 */
spi_nss_output_disable(uint32_t spi_periph)308 void spi_nss_output_disable(uint32_t spi_periph)
309 {
310 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV);
311 }
312
313 /*!
314 \brief pull NSS pin high in software mode
315 \param[in] spi_periph: SPIx(x=0,1)
316 \param[out] none
317 \retval none
318 */
spi_nss_internal_high(uint32_t spi_periph)319 void spi_nss_internal_high(uint32_t spi_periph)
320 {
321 SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS;
322 }
323
324 /*!
325 \brief pull NSS pin low in software mode
326 \param[in] spi_periph: SPIx(x=0,1)
327 \param[out] none
328 \retval none
329 */
spi_nss_internal_low(uint32_t spi_periph)330 void spi_nss_internal_low(uint32_t spi_periph)
331 {
332 SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
333 }
334
335 /*!
336 \brief enable SPI DMA send or receive
337 \param[in] spi_periph: SPIx(x=0,1)
338 \param[in] dma: SPI DMA mode
339 only one parameter can be selected which is shown as below:
340 \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA
341 \arg SPI_DMA_RECEIVE: SPI receive data using DMA
342 \param[out] none
343 \retval none
344 */
spi_dma_enable(uint32_t spi_periph,uint8_t dma)345 void spi_dma_enable(uint32_t spi_periph, uint8_t dma)
346 {
347 if(SPI_DMA_TRANSMIT == dma){
348 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
349 }else{
350 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
351 }
352 }
353
354 /*!
355 \brief disable SPI DMA send or receive
356 \param[in] spi_periph: SPIx(x=0,1)
357 \param[in] dma: SPI DMA mode
358 only one parameter can be selected which is shown as below:
359 \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA
360 \arg SPI_DMA_RECEIVE: SPI receive data using DMA
361 \param[out] none
362 \retval none
363 */
spi_dma_disable(uint32_t spi_periph,uint8_t dma)364 void spi_dma_disable(uint32_t spi_periph, uint8_t dma)
365 {
366 if(SPI_DMA_TRANSMIT == dma){
367 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN);
368 }else{
369 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN);
370 }
371 }
372
373 /*!
374 \brief configure SPI/I2S data frame format
375 \param[in] spi_periph: SPIx(x=0,1)
376 \param[in] frame_format: SPI frame size
377 only one parameter can be selected which is shown as below:
378 \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits
379 \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
380 \param[out] none
381 \retval none
382 */
spi_i2s_data_frame_format_config(uint32_t spi_periph,uint16_t frame_format)383 void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
384 {
385 /* clear SPI_CTL0_FF16 bit */
386 SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
387 /* confige SPI_CTL0_FF16 bit */
388 SPI_CTL0(spi_periph) |= (uint32_t)frame_format;
389 }
390
391 /*!
392 \brief SPI transmit data
393 \param[in] spi_periph: SPIx(x=0,1)
394 \param[in] data: 16-bit data
395 \param[out] none
396 \retval none
397 */
spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data)398 void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data)
399 {
400 SPI_DATA(spi_periph) = (uint32_t)data;
401 }
402
403 /*!
404 \brief SPI receive data
405 \param[in] spi_periph: SPIx(x=0,1)
406 \param[out] none
407 \retval 16-bit data
408 */
spi_i2s_data_receive(uint32_t spi_periph)409 uint16_t spi_i2s_data_receive(uint32_t spi_periph)
410 {
411 return ((uint16_t)SPI_DATA(spi_periph));
412 }
413
414 /*!
415 \brief configure SPI bidirectional transfer direction
416 \param[in] spi_periph: SPIx(x=0,1)
417 \param[in] transfer_direction: SPI transfer direction
418 only one parameter can be selected which is shown as below:
419 \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode
420 \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
421 \param[out] none
422 \retval none
423 */
spi_bidirectional_transfer_config(uint32_t spi_periph,uint32_t transfer_direction)424 void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
425 {
426 if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){
427 /* set the transmit only mode */
428 SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT;
429 }else{
430 /* set the receive only mode */
431 SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
432 }
433 }
434
435 /*!
436 \brief set CRC polynomial
437 \param[in] spi_periph: SPIx(x=0,1)
438 \param[in] crc_poly: CRC polynomial value
439 \param[out] none
440 \retval none
441 */
spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly)442 void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly)
443 {
444 /* enable SPI CRC */
445 SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
446 /* set SPI CRC polynomial */
447 SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly;
448 }
449
450 /*!
451 \brief get SPI CRC polynomial
452 \param[in] spi_periph: SPIx(x=0,1)
453 \param[out] none
454 \retval 16-bit CRC polynomial
455 */
spi_crc_polynomial_get(uint32_t spi_periph)456 uint16_t spi_crc_polynomial_get(uint32_t spi_periph)
457 {
458 return ((uint16_t)SPI_CRCPOLY(spi_periph));
459 }
460
461 /*!
462 \brief turn on CRC function
463 \param[in] spi_periph: SPIx(x=0,1)
464 \param[out] none
465 \retval none
466 */
spi_crc_on(uint32_t spi_periph)467 void spi_crc_on(uint32_t spi_periph)
468 {
469 SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
470 }
471
472 /*!
473 \brief turn off CRC function
474 \param[in] spi_periph: SPIx(x=0,1)
475 \param[out] none
476 \retval none
477 */
spi_crc_off(uint32_t spi_periph)478 void spi_crc_off(uint32_t spi_periph)
479 {
480 SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
481 }
482
483 /*!
484 \brief SPI next data is CRC value
485 \param[in] spi_periph: SPIx(x=0,1)
486 \param[out] none
487 \retval none
488 */
spi_crc_next(uint32_t spi_periph)489 void spi_crc_next(uint32_t spi_periph)
490 {
491 SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT;
492 }
493
494 /*!
495 \brief get SPI CRC send value or receive value
496 \param[in] spi_periph: SPIx(x=0,1)
497 \param[in] crc: SPI crc value
498 \arg SPI_CRC_TX: get transmit crc value
499 \arg SPI_CRC_RX: get receive crc value
500 \param[out] none
501 \retval 16-bit CRC value
502 */
spi_crc_get(uint32_t spi_periph,uint8_t crc)503 uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc)
504 {
505 if(SPI_CRC_TX == crc){
506 return ((uint16_t)(SPI_TCRC(spi_periph)));
507 }else{
508 return ((uint16_t)(SPI_RCRC(spi_periph)));
509 }
510 }
511
512 /*!
513 \brief enable SPI TI mode
514 \param[in] spi_periph: SPIx(x=0,1)
515 \param[out] none
516 \retval none
517 */
spi_ti_mode_enable(uint32_t spi_periph)518 void spi_ti_mode_enable(uint32_t spi_periph)
519 {
520 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD;
521 }
522
523 /*!
524 \brief disable SPI TI mode
525 \param[in] spi_periph: SPIx(x=0,1)
526 \param[out] none
527 \retval none
528 */
spi_ti_mode_disable(uint32_t spi_periph)529 void spi_ti_mode_disable(uint32_t spi_periph)
530 {
531 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
532 }
533
534 /*!
535 \brief enable SPI NSS pulse mode
536 \param[in] spi_periph: SPIx(x=0,1)
537 \param[out] none
538 \retval none
539 */
spi_nssp_mode_enable(uint32_t spi_periph)540 void spi_nssp_mode_enable(uint32_t spi_periph)
541 {
542 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP;
543 }
544
545 /*!
546 \brief disable SPI NSS pulse mode
547 \param[in] spi_periph: SPIx(x=0,1)
548 \param[out] none
549 \retval none
550 */
spi_nssp_mode_disable(uint32_t spi_periph)551 void spi_nssp_mode_disable(uint32_t spi_periph)
552 {
553 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP);
554 }
555
556 /*!
557 \brief enable quad wire SPI
558 \param[in] spi_periph: SPI1
559 \param[out] none
560 \retval none
561 */
qspi_enable(uint32_t spi_periph)562 void qspi_enable(uint32_t spi_periph)
563 {
564 SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
565 }
566
567 /*!
568 \brief disable quad wire SPI
569 \param[in] spi_periph: SPI1
570 \param[out] none
571 \retval none
572 */
qspi_disable(uint32_t spi_periph)573 void qspi_disable(uint32_t spi_periph)
574 {
575 SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
576 }
577
578 /*!
579 \brief enable quad wire SPI write
580 \param[in] spi_periph: SPI1
581 \param[out] none
582 \retval none
583 */
qspi_write_enable(uint32_t spi_periph)584 void qspi_write_enable(uint32_t spi_periph)
585 {
586 SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
587 }
588
589 /*!
590 \brief enable quad wire SPI read
591 \param[in] spi_periph: SPI1
592 \param[out] none
593 \retval none
594 */
qspi_read_enable(uint32_t spi_periph)595 void qspi_read_enable(uint32_t spi_periph)
596 {
597 SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
598 }
599
600 /*!
601 \brief enable SPI_IO2 and SPI_IO3 pin output
602 \param[in] spi_periph: SPI1
603 \param[out] none
604 \retval none
605 */
qspi_io23_output_enable(uint32_t spi_periph)606 void qspi_io23_output_enable(uint32_t spi_periph)
607 {
608 SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
609 }
610
611 /*!
612 \brief disable SPI_IO2 and SPI_IO3 pin output
613 \param[in] spi_periph: SPI1
614 \param[out] none
615 \retval none
616 */
qspi_io23_output_disable(uint32_t spi_periph)617 void qspi_io23_output_disable(uint32_t spi_periph)
618 {
619 SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
620 }
621
622 /*!
623 \brief enable SPI and I2S interrupt
624 \param[in] spi_periph: SPIx(x=0,1)
625 \param[in] interrupt: SPI/I2S interrupt
626 only one parameter can be selected which is shown as below:
627 \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
628 \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
629 \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
630 transmission underrun error and format error interrupt
631 \param[out] none
632 \retval none
633 */
spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t interrupt)634 void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt)
635 {
636 switch(interrupt){
637 /* SPI/I2S transmit buffer empty interrupt */
638 case SPI_I2S_INT_TBE:
639 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
640 break;
641 /* SPI/I2S receive buffer not empty interrupt */
642 case SPI_I2S_INT_RBNE:
643 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
644 break;
645 /* SPI/I2S error */
646 case SPI_I2S_INT_ERR:
647 SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
648 break;
649 default:
650 break;
651 }
652 }
653
654 /*!
655 \brief disable SPI and I2S interrupt
656 \param[in] spi_periph: SPIx(x=0,1)
657 \param[in] interrupt: SPI/I2S interrupt
658 only one parameter can be selected which is shown as below:
659 \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
660 \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
661 \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
662 transmission underrun error and format error interrupt
663 \param[out] none
664 \retval none
665 */
spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t interrupt)666 void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt)
667 {
668 switch(interrupt){
669 /* SPI/I2S transmit buffer empty interrupt */
670 case SPI_I2S_INT_TBE:
671 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
672 break;
673 /* SPI/I2S receive buffer not empty interrupt */
674 case SPI_I2S_INT_RBNE:
675 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
676 break;
677 /* SPI/I2S error */
678 case SPI_I2S_INT_ERR:
679 SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
680 break;
681 default :
682 break;
683 }
684 }
685
686 /*!
687 \brief get SPI and I2S interrupt flag status
688 \param[in] spi_periph: SPIx(x=0,1)
689 \param[in] interrupt: SPI/I2S interrupt flag status
690 only one parameter can be selected which is shown as below:
691 \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag
692 \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag
693 \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag
694 \arg SPI_INT_FLAG_CONFERR: config error interrupt flag
695 \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag
696 \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag
697 \arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag
698 \param[out] none
699 \retval FlagStatus: SET or RESET
700 */
spi_i2s_interrupt_flag_get(uint32_t spi_periph,uint8_t interrupt)701 FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
702 {
703 uint32_t reg1 = SPI_STAT(spi_periph);
704 uint32_t reg2 = SPI_CTL1(spi_periph);
705
706 switch(interrupt){
707 /* SPI/I2S transmit buffer empty interrupt */
708 case SPI_I2S_INT_FLAG_TBE:
709 reg1 = reg1 & SPI_STAT_TBE;
710 reg2 = reg2 & SPI_CTL1_TBEIE;
711 break;
712 /* SPI/I2S receive buffer not empty interrupt */
713 case SPI_I2S_INT_FLAG_RBNE:
714 reg1 = reg1 & SPI_STAT_RBNE;
715 reg2 = reg2 & SPI_CTL1_RBNEIE;
716 break;
717 /* SPI/I2S overrun interrupt */
718 case SPI_I2S_INT_FLAG_RXORERR:
719 reg1 = reg1 & SPI_STAT_RXORERR;
720 reg2 = reg2 & SPI_CTL1_ERRIE;
721 break;
722 /* SPI config error interrupt */
723 case SPI_INT_FLAG_CONFERR:
724 reg1 = reg1 & SPI_STAT_CONFERR;
725 reg2 = reg2 & SPI_CTL1_ERRIE;
726 break;
727 /* SPI CRC error interrupt */
728 case SPI_INT_FLAG_CRCERR:
729 reg1 = reg1 & SPI_STAT_CRCERR;
730 reg2 = reg2 & SPI_CTL1_ERRIE;
731 break;
732 /* I2S underrun error interrupt */
733 case I2S_INT_FLAG_TXURERR:
734 reg1 = reg1 & SPI_STAT_TXURERR;
735 reg2 = reg2 & SPI_CTL1_ERRIE;
736 break;
737 /* SPI/I2S format error interrupt */
738 case SPI_I2S_INT_FLAG_FERR:
739 reg1 = reg1 & SPI_STAT_FERR;
740 reg2 = reg2 & SPI_CTL1_ERRIE;
741 break;
742 default :
743 break;
744 }
745 /*get SPI/I2S interrupt flag status */
746 if((0U != reg1) && (0U != reg2)){
747 return SET;
748 }else{
749 return RESET;
750 }
751 }
752
753 /*!
754 \brief get SPI and I2S flag status
755 \param[in] spi_periph: SPIx(x=0,1)
756 \param[in] flag: SPI/I2S flag status
757 one or more parameters can be selected which are shown as below:
758 \arg SPI_FLAG_TBE: transmit buffer empty flag
759 \arg SPI_FLAG_RBNE: receive buffer not empty flag
760 \arg SPI_FLAG_TRANS: transmit on-going flag
761 \arg SPI_FLAG_RXORERR: receive overrun error flag
762 \arg SPI_FLAG_CONFERR: mode config error flag
763 \arg SPI_FLAG_CRCERR: CRC error flag
764 \arg SPI_FLAG_FERR: format error interrupt flag
765 \arg I2S_FLAG_TBE: transmit buffer empty flag
766 \arg I2S_FLAG_RBNE: receive buffer not empty flag
767 \arg I2S_FLAG_TRANS: transmit on-going flag
768 \arg I2S_FLAG_RXORERR: overrun error flag
769 \arg I2S_FLAG_TXURERR: underrun error flag
770 \arg I2S_FLAG_CH: channel side flag
771 \arg I2S_FLAG_FERR: format error interrupt flag
772 \param[out] none
773 \retval FlagStatus: SET or RESET
774 */
spi_i2s_flag_get(uint32_t spi_periph,uint32_t flag)775 FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag)
776 {
777 if(RESET != (SPI_STAT(spi_periph) & flag)){
778 return SET;
779 }else{
780 return RESET;
781 }
782 }
783
784 /*!
785 \brief clear SPI CRC error flag status
786 \param[in] spi_periph: SPIx(x=0,1)
787 \param[out] none
788 \retval none
789 */
spi_crc_error_clear(uint32_t spi_periph)790 void spi_crc_error_clear(uint32_t spi_periph)
791 {
792 SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
793 }
794