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