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