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