1 /*!
2     \file    gd32f4xx_sdio.c
3     \brief   SDIO driver
4 
5     \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6     \version 2018-12-12, V2.0.1, firmware for GD32F4xx
7     \version 2020-09-30, V2.1.0, firmware for GD32F4xx
8     \version 2022-03-09, V3.0.0, firmware for GD32F4xx
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32f4xx_sdio.h"
39 
40 /*!
41     \brief    deinitialize the SDIO
42     \param[in]  none
43     \param[out] none
44     \retval     none
45 */
sdio_deinit(void)46 void sdio_deinit(void)
47 {
48     rcu_periph_reset_enable(RCU_SDIORST);
49     rcu_periph_reset_disable(RCU_SDIORST);
50 }
51 
52 /*!
53     \brief    configure the SDIO clock
54     \param[in]  clock_edge: SDIO_CLK clock edge
55                 only one parameter can be selected which is shown as below:
56       \arg        SDIO_SDIOCLKEDGE_RISING: select the rising edge of the SDIOCLK to generate SDIO_CLK
57       \arg        SDIO_SDIOCLKEDGE_FALLING: select the falling edge of the SDIOCLK to generate SDIO_CLK
58     \param[in]  clock_bypass: clock bypass
59                 only one parameter can be selected which is shown as below:
60       \arg        SDIO_CLOCKBYPASS_ENABLE: clock bypass
61       \arg        SDIO_CLOCKBYPASS_DISABLE: no bypass
62     \param[in]  clock_powersave: SDIO_CLK clock dynamic switch on/off for power saving
63                 only one parameter can be selected which is shown as below:
64       \arg        SDIO_CLOCKPWRSAVE_ENABLE: SDIO_CLK closed when bus is idle
65       \arg        SDIO_CLOCKPWRSAVE_DISABLE: SDIO_CLK clock is always on
66     \param[in]  clock_division: clock division, less than 512
67     \param[out] none
68     \retval     none
69 */
sdio_clock_config(uint32_t clock_edge,uint32_t clock_bypass,uint32_t clock_powersave,uint16_t clock_division)70 void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division)
71 {
72     uint32_t clock_config = 0U;
73     clock_config = SDIO_CLKCTL;
74     /* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */
75     clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV);
76     /* if the clock division is greater or equal to 256, set the DIV[8] */
77     if(clock_division >= 256U) {
78         clock_config |= SDIO_CLKCTL_DIV8;
79         clock_division -= 256U;
80     }
81     /* configure the SDIO_CLKCTL according to the parameters */
82     clock_config |= (clock_edge | clock_bypass | clock_powersave | clock_division);
83     SDIO_CLKCTL = clock_config;
84 }
85 
86 /*!
87     \brief    enable hardware clock control
88     \param[in]  none
89     \param[out] none
90     \retval     none
91 */
sdio_hardware_clock_enable(void)92 void sdio_hardware_clock_enable(void)
93 {
94     SDIO_CLKCTL |= SDIO_CLKCTL_HWCLKEN;
95 }
96 
97 /*!
98     \brief    disable hardware clock control
99     \param[in]  none
100     \param[out] none
101     \retval     none
102 */
sdio_hardware_clock_disable(void)103 void sdio_hardware_clock_disable(void)
104 {
105     SDIO_CLKCTL &= ~SDIO_CLKCTL_HWCLKEN;
106 }
107 
108 /*!
109     \brief    set different SDIO card bus mode
110     \param[in]  bus_mode: SDIO card bus mode
111                 only one parameter can be selected which is shown as below:
112       \arg        SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode
113       \arg        SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode
114       \arg        SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode
115     \param[out] none
116     \retval     none
117 */
sdio_bus_mode_set(uint32_t bus_mode)118 void sdio_bus_mode_set(uint32_t bus_mode)
119 {
120     /* reset the SDIO card bus mode bits and set according to bus_mode */
121     SDIO_CLKCTL &= ~SDIO_CLKCTL_BUSMODE;
122     SDIO_CLKCTL |= bus_mode;
123 }
124 
125 /*!
126     \brief    set the SDIO power state
127     \param[in]  power_state: SDIO power state
128                 only one parameter can be selected which is shown as below:
129       \arg        SDIO_POWER_ON: SDIO power on
130       \arg        SDIO_POWER_OFF: SDIO power off
131     \param[out] none
132     \retval     none
133 */
sdio_power_state_set(uint32_t power_state)134 void sdio_power_state_set(uint32_t power_state)
135 {
136     SDIO_PWRCTL = power_state;
137 }
138 
139 /*!
140     \brief    get the SDIO power state
141     \param[in]  none
142     \param[out] none
143     \retval     SDIO power state
144       \arg        SDIO_POWER_ON: SDIO power on
145       \arg        SDIO_POWER_OFF: SDIO power off
146 */
sdio_power_state_get(void)147 uint32_t sdio_power_state_get(void)
148 {
149     return SDIO_PWRCTL;
150 }
151 
152 /*!
153     \brief    enable SDIO_CLK clock output
154     \param[in]  none
155     \param[out] none
156     \retval     none
157 */
sdio_clock_enable(void)158 void sdio_clock_enable(void)
159 {
160     SDIO_CLKCTL |= SDIO_CLKCTL_CLKEN;
161 }
162 
163 /*!
164     \brief    disable SDIO_CLK clock output
165     \param[in]  none
166     \param[out] none
167     \retval     none
168 */
sdio_clock_disable(void)169 void sdio_clock_disable(void)
170 {
171     SDIO_CLKCTL &= ~SDIO_CLKCTL_CLKEN;
172 }
173 
174 /*!
175     \brief    configure the command and response
176     \param[in]  cmd_index: command index, refer to the related specifications
177     \param[in]  cmd_argument: command argument, refer to the related specifications
178     \param[in]  response_type: response type
179                 only one parameter can be selected which is shown as below:
180       \arg        SDIO_RESPONSETYPE_NO: no response
181       \arg        SDIO_RESPONSETYPE_SHORT: short response
182       \arg        SDIO_RESPONSETYPE_LONG: long response
183     \param[out] none
184     \retval     none
185 */
sdio_command_response_config(uint32_t cmd_index,uint32_t cmd_argument,uint32_t response_type)186 void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type)
187 {
188     uint32_t cmd_config = 0U;
189     /* disable the CSM */
190     SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN;
191     /* reset the command index, command argument and response type */
192     SDIO_CMDAGMT &= ~SDIO_CMDAGMT_CMDAGMT;
193     SDIO_CMDAGMT = cmd_argument;
194     cmd_config = SDIO_CMDCTL;
195     cmd_config &= ~(SDIO_CMDCTL_CMDIDX | SDIO_CMDCTL_CMDRESP);
196     /* configure SDIO_CMDCTL and SDIO_CMDAGMT according to the parameters */
197     cmd_config |= (cmd_index | response_type);
198     SDIO_CMDCTL = cmd_config;
199 }
200 
201 /*!
202     \brief    set the command state machine wait type
203     \param[in]  wait_type: wait type
204                 only one parameter can be selected which is shown as below:
205       \arg        SDIO_WAITTYPE_NO: not wait interrupt
206       \arg        SDIO_WAITTYPE_INTERRUPT: wait interrupt
207       \arg        SDIO_WAITTYPE_DATAEND: wait the end of data transfer
208     \param[out] none
209     \retval     none
210 */
sdio_wait_type_set(uint32_t wait_type)211 void sdio_wait_type_set(uint32_t wait_type)
212 {
213     /* reset INTWAIT and WAITDEND */
214     SDIO_CMDCTL &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND);
215     /* set the wait type according to wait_type */
216     SDIO_CMDCTL |= wait_type;
217 }
218 
219 /*!
220     \brief    enable the CSM(command state machine)
221     \param[in]  none
222     \param[out] none
223     \retval     none
224 */
sdio_csm_enable(void)225 void sdio_csm_enable(void)
226 {
227     SDIO_CMDCTL |= SDIO_CMDCTL_CSMEN;
228 }
229 
230 /*!
231     \brief    disable the CSM(command state machine)
232     \param[in]  none
233     \param[out] none
234     \retval     none
235 */
sdio_csm_disable(void)236 void sdio_csm_disable(void)
237 {
238     SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN;
239 }
240 
241 /*!
242     \brief    get the last response command index
243     \param[in]  none
244     \param[out] none
245     \retval     last response command index
246 */
sdio_command_index_get(void)247 uint8_t sdio_command_index_get(void)
248 {
249     return (uint8_t)SDIO_RSPCMDIDX;
250 }
251 
252 /*!
253     \brief    get the response for the last received command
254     \param[in]  sdio_responsex: SDIO response
255                 only one parameter can be selected which is shown as below:
256       \arg       SDIO_RESPONSE0: card response[31:0]/card response[127:96]
257       \arg       SDIO_RESPONSE1: card response[95:64]
258       \arg       SDIO_RESPONSE2: card response[63:32]
259       \arg       SDIO_RESPONSE3: card response[31:1], plus bit 0
260     \param[out] none
261     \retval     response for the last received command
262 */
sdio_response_get(uint32_t sdio_responsex)263 uint32_t sdio_response_get(uint32_t sdio_responsex)
264 {
265     uint32_t resp_content = 0U;
266     switch(sdio_responsex) {
267     case SDIO_RESPONSE0:
268         resp_content = SDIO_RESP0;
269         break;
270     case SDIO_RESPONSE1:
271         resp_content = SDIO_RESP1;
272         break;
273     case SDIO_RESPONSE2:
274         resp_content = SDIO_RESP2;
275         break;
276     case SDIO_RESPONSE3:
277         resp_content = SDIO_RESP3;
278         break;
279     default:
280         break;
281     }
282     return resp_content;
283 }
284 
285 /*!
286     \brief    configure the data timeout, data length and data block size
287     \param[in]  data_timeout: data timeout period in card bus clock periods
288     \param[in]  data_length: number of data bytes to be transferred
289     \param[in]  data_blocksize: size of data block for block transfer
290                 only one parameter can be selected which is shown as below:
291       \arg        SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte
292       \arg        SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes
293       \arg        SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes
294       \arg        SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes
295       \arg        SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes
296       \arg        SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes
297       \arg        SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes
298       \arg        SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes
299       \arg        SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes
300       \arg        SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes
301       \arg        SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes
302       \arg        SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes
303       \arg        SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes
304       \arg        SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes
305       \arg        SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes
306     \param[out] none
307     \retval     none
308 */
sdio_data_config(uint32_t data_timeout,uint32_t data_length,uint32_t data_blocksize)309 void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize)
310 {
311     /* reset data timeout, data length and data block size */
312     SDIO_DATATO &= ~SDIO_DATATO_DATATO;
313     SDIO_DATALEN &= ~SDIO_DATALEN_DATALEN;
314     SDIO_DATACTL &= ~SDIO_DATACTL_BLKSZ;
315     /* configure the related parameters of data */
316     SDIO_DATATO = data_timeout;
317     SDIO_DATALEN = data_length;
318     SDIO_DATACTL |= data_blocksize;
319 }
320 
321 /*!
322     \brief    configure the data transfer mode and direction
323     \param[in]  transfer_mode: mode of data transfer
324                 only one parameter can be selected which is shown as below:
325       \arg       SDIO_TRANSMODE_BLOCK: block transfer
326       \arg       SDIO_TRANSMODE_STREAM: stream transfer or SDIO multibyte transfer
327     \param[in]  transfer_direction: data transfer direction, read or write
328                 only one parameter can be selected which is shown as below:
329       \arg       SDIO_TRANSDIRECTION_TOCARD: write data to card
330       \arg       SDIO_TRANSDIRECTION_TOSDIO: read data from card
331     \param[out] none
332     \retval     none
333 */
sdio_data_transfer_config(uint32_t transfer_mode,uint32_t transfer_direction)334 void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction)
335 {
336     uint32_t data_trans = 0U;
337     /* reset the data transfer mode, transfer direction and set according to the parameters */
338     data_trans = SDIO_DATACTL;
339     data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR);
340     data_trans |= (transfer_mode | transfer_direction);
341     SDIO_DATACTL = data_trans;
342 }
343 
344 /*!
345     \brief    enable the DSM(data state machine) for data transfer
346     \param[in]  none
347     \param[out] none
348     \retval     none
349 */
sdio_dsm_enable(void)350 void sdio_dsm_enable(void)
351 {
352     SDIO_DATACTL |= SDIO_DATACTL_DATAEN;
353 }
354 
355 /*!
356     \brief    disable the DSM(data state machine)
357     \param[in]  none
358     \param[out] none
359     \retval     none
360 */
sdio_dsm_disable(void)361 void sdio_dsm_disable(void)
362 {
363     SDIO_DATACTL &= ~SDIO_DATACTL_DATAEN;
364 }
365 
366 /*!
367     \brief    write data(one word) to the transmit FIFO
368     \param[in]  data: 32-bit data write to card
369     \param[out] none
370     \retval     none
371 */
sdio_data_write(uint32_t data)372 void sdio_data_write(uint32_t data)
373 {
374     SDIO_FIFO = data;
375 }
376 
377 /*!
378     \brief    read data(one word) from the receive FIFO
379     \param[in]  none
380     \param[out] none
381     \retval     received data
382 */
sdio_data_read(void)383 uint32_t sdio_data_read(void)
384 {
385     return SDIO_FIFO;
386 }
387 
388 /*!
389     \brief    get the number of remaining data bytes to be transferred to card
390     \param[in]  none
391     \param[out] none
392     \retval     number of remaining data bytes to be transferred
393 */
sdio_data_counter_get(void)394 uint32_t sdio_data_counter_get(void)
395 {
396     return SDIO_DATACNT;
397 }
398 
399 /*!
400     \brief    get the number of words remaining to be written or read from FIFO
401     \param[in]  none
402     \param[out] none
403     \retval     remaining number of words
404 */
sdio_fifo_counter_get(void)405 uint32_t sdio_fifo_counter_get(void)
406 {
407     return SDIO_FIFOCNT;
408 }
409 
410 /*!
411     \brief    enable the DMA request for SDIO
412     \param[in]  none
413     \param[out] none
414     \retval     none
415 */
sdio_dma_enable(void)416 void sdio_dma_enable(void)
417 {
418     SDIO_DATACTL |= SDIO_DATACTL_DMAEN;
419 }
420 
421 /*!
422     \brief    disable the DMA request for SDIO
423     \param[in]  none
424     \param[out] none
425     \retval     none
426 */
sdio_dma_disable(void)427 void sdio_dma_disable(void)
428 {
429     SDIO_DATACTL &= ~SDIO_DATACTL_DMAEN;
430 }
431 
432 /*!
433     \brief    get the flags state of SDIO
434     \param[in]  flag: flags state of SDIO
435                 one or more parameters can be selected which are shown as below:
436       \arg        SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
437       \arg        SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
438       \arg        SDIO_FLAG_CMDTMOUT: command response timeout flag
439       \arg        SDIO_FLAG_DTTMOUT: data timeout flag
440       \arg        SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
441       \arg        SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
442       \arg        SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
443       \arg        SDIO_FLAG_CMDSEND: command sent (no response required) flag
444       \arg        SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
445       \arg        SDIO_FLAG_STBITE: start bit error in the bus flag
446       \arg        SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
447       \arg        SDIO_FLAG_CMDRUN: command transmission in progress flag
448       \arg        SDIO_FLAG_TXRUN: data transmission in progress flag
449       \arg        SDIO_FLAG_RXRUN: data reception in progress flag
450       \arg        SDIO_FLAG_TFH: transmit FIFO is half empty flag: at least 8 words can be written into the FIFO
451       \arg        SDIO_FLAG_RFH: receive FIFO is half full flag: at least 8 words can be read in the FIFO
452       \arg        SDIO_FLAG_TFF: transmit FIFO is full flag
453       \arg        SDIO_FLAG_RFF: receive FIFO is full flag
454       \arg        SDIO_FLAG_TFE: transmit FIFO is empty flag
455       \arg        SDIO_FLAG_RFE: receive FIFO is empty flag
456       \arg        SDIO_FLAG_TXDTVAL: data is valid in transmit FIFO flag
457       \arg        SDIO_FLAG_RXDTVAL: data is valid in receive FIFO flag
458       \arg        SDIO_FLAG_SDIOINT: SD I/O interrupt received flag
459       \arg        SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
460     \param[out] none
461     \retval     FlagStatus: SET or RESET
462 */
sdio_flag_get(uint32_t flag)463 FlagStatus sdio_flag_get(uint32_t flag)
464 {
465     FlagStatus temp_flag = RESET;
466     if(RESET != (SDIO_STAT & flag)) {
467         temp_flag = SET;
468     }
469     return temp_flag;
470 }
471 
472 /*!
473     \brief    clear the pending flags of SDIO
474     \param[in]  flag: flags state of SDIO
475                 one or more parameters can be selected which are shown as below:
476       \arg        SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
477       \arg        SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
478       \arg        SDIO_FLAG_CMDTMOUT: command response timeout flag
479       \arg        SDIO_FLAG_DTTMOUT: data timeout flag
480       \arg        SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
481       \arg        SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
482       \arg        SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
483       \arg        SDIO_FLAG_CMDSEND: command sent (no response required) flag
484       \arg        SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
485       \arg        SDIO_FLAG_STBITE: start bit error in the bus flag
486       \arg        SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
487       \arg        SDIO_FLAG_SDIOINT: SD I/O interrupt received flag
488       \arg        SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
489     \param[out] none
490     \retval     none
491 */
sdio_flag_clear(uint32_t flag)492 void sdio_flag_clear(uint32_t flag)
493 {
494     SDIO_INTC = flag;
495 }
496 
497 /*!
498     \brief    enable the SDIO interrupt
499     \param[in]  int_flag: interrupt flags state of SDIO
500                 one or more parameters can be selected which are shown as below:
501       \arg        SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
502       \arg        SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
503       \arg        SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
504       \arg        SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
505       \arg        SDIO_INT_TXURE: SDIO TXURE interrupt
506       \arg        SDIO_INT_RXORE: SDIO RXORE interrupt
507       \arg        SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
508       \arg        SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
509       \arg        SDIO_INT_DTEND: SDIO DTEND interrupt
510       \arg        SDIO_INT_STBITE: SDIO STBITE interrupt
511       \arg        SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
512       \arg        SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
513       \arg        SDIO_INT_TXRUN: SDIO TXRUN interrupt
514       \arg        SDIO_INT_RXRUN: SDIO RXRUN interrupt
515       \arg        SDIO_INT_TFH: SDIO TFH interrupt
516       \arg        SDIO_INT_RFH: SDIO RFH interrupt
517       \arg        SDIO_INT_TFF: SDIO TFF interrupt
518       \arg        SDIO_INT_RFF: SDIO RFF interrupt
519       \arg        SDIO_INT_TFE: SDIO TFE interrupt
520       \arg        SDIO_INT_RFE: SDIO RFE interrupt
521       \arg        SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
522       \arg        SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
523       \arg        SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
524       \arg        SDIO_INT_ATAEND: SDIO ATAEND interrupt
525     \param[out] none
526     \retval     none
527 */
sdio_interrupt_enable(uint32_t int_flag)528 void sdio_interrupt_enable(uint32_t int_flag)
529 {
530     SDIO_INTEN |= int_flag;
531 }
532 
533 /*!
534     \brief    disable the SDIO interrupt
535     \param[in]  int_flag: interrupt flags state of SDIO
536                 one or more parameters can be selected which are shown as below:
537       \arg        SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
538       \arg        SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
539       \arg        SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
540       \arg        SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
541       \arg        SDIO_INT_TXURE: SDIO TXURE interrupt
542       \arg        SDIO_INT_RXORE: SDIO RXORE interrupt
543       \arg        SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
544       \arg        SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
545       \arg        SDIO_INT_DTEND: SDIO DTEND interrupt
546       \arg        SDIO_INT_STBITE: SDIO STBITE interrupt
547       \arg        SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
548       \arg        SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
549       \arg        SDIO_INT_TXRUN: SDIO TXRUN interrupt
550       \arg        SDIO_INT_RXRUN: SDIO RXRUN interrupt
551       \arg        SDIO_INT_TFH: SDIO TFH interrupt
552       \arg        SDIO_INT_RFH: SDIO RFH interrupt
553       \arg        SDIO_INT_TFF: SDIO TFF interrupt
554       \arg        SDIO_INT_RFF: SDIO RFF interrupt
555       \arg        SDIO_INT_TFE: SDIO TFE interrupt
556       \arg        SDIO_INT_RFE: SDIO RFE interrupt
557       \arg        SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
558       \arg        SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
559       \arg        SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
560       \arg        SDIO_INT_ATAEND: SDIO ATAEND interrupt
561     \param[out] none
562     \retval     none
563 */
sdio_interrupt_disable(uint32_t int_flag)564 void sdio_interrupt_disable(uint32_t int_flag)
565 {
566     SDIO_INTEN &= ~int_flag;
567 }
568 
569 /*!
570     \brief    get the interrupt flags state of SDIO
571     \param[in]  int_flag: interrupt flags state of SDIO
572                 one or more parameters can be selected which are shown as below:
573       \arg        SDIO_INT_FLAG_CCRCERR: SDIO CCRCERR interrupt flag
574       \arg        SDIO_INT_FLAG_DTCRCERR: SDIO DTCRCERR interrupt flag
575       \arg        SDIO_INT_FLAG_CMDTMOUT: SDIO CMDTMOUT interrupt flag
576       \arg        SDIO_INT_FLAG_DTTMOUT: SDIO DTTMOUT interrupt flag
577       \arg        SDIO_INT_FLAG_TXURE: SDIO TXURE interrupt flag
578       \arg        SDIO_INT_FLAG_RXORE: SDIO RXORE interrupt flag
579       \arg        SDIO_INT_FLAG_CMDRECV: SDIO CMDRECV interrupt flag
580       \arg        SDIO_INT_FLAG_CMDSEND: SDIO CMDSEND interrupt flag
581       \arg        SDIO_INT_FLAG_DTEND: SDIO DTEND interrupt flag
582       \arg        SDIO_INT_FLAG_STBITE: SDIO STBITE interrupt flag
583       \arg        SDIO_INT_FLAG_DTBLKEND: SDIO DTBLKEND interrupt flag
584       \arg        SDIO_INT_FLAG_CMDRUN: SDIO CMDRUN interrupt flag
585       \arg        SDIO_INT_FLAG_TXRUN: SDIO TXRUN interrupt flag
586       \arg        SDIO_INT_FLAG_RXRUN: SDIO RXRUN interrupt flag
587       \arg        SDIO_INT_FLAG_TFH: SDIO TFH interrupt flag
588       \arg        SDIO_INT_FLAG_RFH: SDIO RFH interrupt flag
589       \arg        SDIO_INT_FLAG_TFF: SDIO TFF interrupt flag
590       \arg        SDIO_INT_FLAG_RFF: SDIO RFF interrupt flag
591       \arg        SDIO_INT_FLAG_TFE: SDIO TFE interrupt flag
592       \arg        SDIO_INT_FLAG_RFE: SDIO RFE interrupt flag
593       \arg        SDIO_INT_FLAG_TXDTVAL: SDIO TXDTVAL interrupt flag
594       \arg        SDIO_INT_FLAG_RXDTVAL: SDIO RXDTVAL interrupt flag
595       \arg        SDIO_INT_FLAG_SDIOINT: SDIO SDIOINT interrupt flag
596       \arg        SDIO_INT_FLAG_ATAEND: SDIO ATAEND interrupt flag
597     \param[out] none
598     \retval     FlagStatus: SET or RESET
599 */
sdio_interrupt_flag_get(uint32_t int_flag)600 FlagStatus sdio_interrupt_flag_get(uint32_t int_flag)
601 {
602     FlagStatus temp_flag = RESET;
603     if(RESET != (SDIO_STAT & int_flag)) {
604         temp_flag = SET;
605     }
606     return temp_flag;
607 }
608 
609 /*!
610     \brief    clear the interrupt pending flags of SDIO
611     \param[in]  int_flag: interrupt flags state of SDIO
612                 one or more parameters can be selected which are shown as below:
613       \arg        SDIO_INT_FLAG_CCRCERR: command response received (CRC check failed) flag
614       \arg        SDIO_INT_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
615       \arg        SDIO_INT_FLAG_CMDTMOUT: command response timeout flag
616       \arg        SDIO_INT_FLAG_DTTMOUT: data timeout flag
617       \arg        SDIO_INT_FLAG_TXURE: transmit FIFO underrun error occurs flag
618       \arg        SDIO_INT_FLAG_RXORE: received FIFO overrun error occurs flag
619       \arg        SDIO_INT_FLAG_CMDRECV: command response received (CRC check passed) flag
620       \arg        SDIO_INT_FLAG_CMDSEND: command sent (no response required) flag
621       \arg        SDIO_INT_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
622       \arg        SDIO_INT_FLAG_STBITE: start bit error in the bus flag
623       \arg        SDIO_INT_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
624       \arg        SDIO_INT_FLAG_SDIOINT: SD I/O interrupt received flag
625       \arg        SDIO_INT_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
626     \param[out] none
627     \retval     none
628 */
sdio_interrupt_flag_clear(uint32_t int_flag)629 void sdio_interrupt_flag_clear(uint32_t int_flag)
630 {
631     SDIO_INTC = int_flag;
632 }
633 
634 /*!
635     \brief    enable the read wait mode(SD I/O only)
636     \param[in]  none
637     \param[out] none
638     \retval     none
639 */
sdio_readwait_enable(void)640 void sdio_readwait_enable(void)
641 {
642     SDIO_DATACTL |= SDIO_DATACTL_RWEN;
643 }
644 
645 /*!
646     \brief    disable the read wait mode(SD I/O only)
647     \param[in]  none
648     \param[out] none
649     \retval     none
650 */
sdio_readwait_disable(void)651 void sdio_readwait_disable(void)
652 {
653     SDIO_DATACTL &= ~SDIO_DATACTL_RWEN;
654 }
655 
656 /*!
657     \brief    enable the function that stop the read wait process(SD I/O only)
658     \param[in]  none
659     \param[out] none
660     \retval     none
661 */
sdio_stop_readwait_enable(void)662 void sdio_stop_readwait_enable(void)
663 {
664     SDIO_DATACTL |= SDIO_DATACTL_RWSTOP;
665 }
666 
667 /*!
668     \brief    disable the function that stop the read wait process(SD I/O only)
669     \param[in]  none
670     \param[out] none
671     \retval     none
672 */
sdio_stop_readwait_disable(void)673 void sdio_stop_readwait_disable(void)
674 {
675     SDIO_DATACTL &= ~SDIO_DATACTL_RWSTOP;
676 }
677 
678 /*!
679     \brief    set the read wait type(SD I/O only)
680     \param[in]  readwait_type: SD I/O read wait type
681                 only one parameter can be selected which is shown as below:
682       \arg        SDIO_READWAITTYPE_CLK: read wait control by stopping SDIO_CLK
683       \arg        SDIO_READWAITTYPE_DAT2: read wait control using SDIO_DAT[2]
684     \param[out] none
685     \retval     none
686 */
sdio_readwait_type_set(uint32_t readwait_type)687 void sdio_readwait_type_set(uint32_t readwait_type)
688 {
689     if(SDIO_READWAITTYPE_CLK == readwait_type) {
690         SDIO_DATACTL |= SDIO_DATACTL_RWTYPE;
691     } else {
692         SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE;
693     }
694 }
695 
696 /*!
697     \brief    enable the SD I/O mode specific operation(SD I/O only)
698     \param[in]  none
699     \param[out] none
700     \retval     none
701 */
sdio_operation_enable(void)702 void sdio_operation_enable(void)
703 {
704     SDIO_DATACTL |= SDIO_DATACTL_IOEN;
705 }
706 
707 /*!
708     \brief    disable the SD I/O mode specific operation(SD I/O only)
709     \param[in]  none
710     \param[out] none
711     \retval     none
712 */
sdio_operation_disable(void)713 void sdio_operation_disable(void)
714 {
715     SDIO_DATACTL &= ~SDIO_DATACTL_IOEN;
716 }
717 
718 /*!
719     \brief    enable the SD I/O suspend operation(SD I/O only)
720     \param[in]  none
721     \param[out] none
722     \retval     none
723 */
sdio_suspend_enable(void)724 void sdio_suspend_enable(void)
725 {
726     SDIO_CMDCTL |= SDIO_CMDCTL_SUSPEND;
727 }
728 
729 /*!
730     \brief    disable the SD I/O suspend operation(SD I/O only)
731     \param[in]  none
732     \param[out] none
733     \retval     none
734 */
sdio_suspend_disable(void)735 void sdio_suspend_disable(void)
736 {
737     SDIO_CMDCTL &= ~SDIO_CMDCTL_SUSPEND;
738 }
739 
740 /*!
741     \brief    enable the CE-ATA command(CE-ATA only)
742     \param[in]  none
743     \param[out] none
744     \retval     none
745 */
sdio_ceata_command_enable(void)746 void sdio_ceata_command_enable(void)
747 {
748     SDIO_CMDCTL |= SDIO_CMDCTL_ATAEN;
749 }
750 
751 /*!
752     \brief    disable the CE-ATA command(CE-ATA only)
753     \param[in]  none
754     \param[out] none
755     \retval     none
756 */
sdio_ceata_command_disable(void)757 void sdio_ceata_command_disable(void)
758 {
759     SDIO_CMDCTL &= ~SDIO_CMDCTL_ATAEN;
760 }
761 
762 /*!
763     \brief    enable the CE-ATA interrupt(CE-ATA only)
764     \param[in]  none
765     \param[out] none
766     \retval     none
767 */
sdio_ceata_interrupt_enable(void)768 void sdio_ceata_interrupt_enable(void)
769 {
770     SDIO_CMDCTL &= ~SDIO_CMDCTL_NINTEN;
771 }
772 
773 /*!
774     \brief    disable the CE-ATA interrupt(CE-ATA only)
775     \param[in]  none
776     \param[out] none
777     \retval     none
778 */
sdio_ceata_interrupt_disable(void)779 void sdio_ceata_interrupt_disable(void)
780 {
781     SDIO_CMDCTL |= SDIO_CMDCTL_NINTEN;
782 }
783 
784 /*!
785     \brief    enable the CE-ATA command completion signal(CE-ATA only)
786     \param[in]  none
787     \param[out] none
788     \retval     none
789 */
sdio_ceata_command_completion_enable(void)790 void sdio_ceata_command_completion_enable(void)
791 {
792     SDIO_CMDCTL |= SDIO_CMDCTL_ENCMDC;
793 }
794 
795 /*!
796     \brief    disable the CE-ATA command completion signal(CE-ATA only)
797     \param[in]  none
798     \param[out] none
799     \retval     none
800 */
sdio_ceata_command_completion_disable(void)801 void sdio_ceata_command_completion_disable(void)
802 {
803     SDIO_CMDCTL &= ~SDIO_CMDCTL_ENCMDC;
804 }
805