This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Reading an SD card on an OMAP L138 eXperimenter Kit

Other Parts Discussed in Thread: OMAP-L138, OMAPL138

Hello,

I'm trying to read an SD card with my OMAP L138 eXperimenter Kit, so I've followed the OMAP-L138 DSP+ARM Processor Technical Reference Manual (SPRUH77A), and first try to identify the card connected to the board. It is explained with command to send and when to expect an answer, but I simply never communicate, I have monitored the sd0_clk and sd0_cmd pin of the board with an oscilloscope and I was able to set the clock, but there is simply nothing on the cmd pin. So my question is after setting witch command to send is there a special instruction to trigger the sending of the command ?

Here is the code of my two function is something missing to be at least able to send the commands for the identification process ?

/*
 * bootloader_omapL138_SDCard.c
 *
 *  Created on: Mar 26, 2013
 *      Author: Omap
 */

#include "..\OMAPL138_common.h"
#include "bootloader_omapL138_SDCard.h"
#include <pspiom/cslr/cslr_mmcsd.h>

void SDCardInit(void) {
	// Open Permissions to SYSCFG Registers
	_call_swi(ARM_PRIV_MODE_KEY);

	CSL_FINS(sysRegs->KICK0R, SYSCFG_KICK0R_KICK0, KICK0_KEY);
	CSL_FINS(sysRegs->KICK1R, SYSCFG_KICK1R_KICK1, KICK1_KEY);

	CSL_FINST(sysRegs->PINMUX11, SYSCFG_PINMUX11_PINMUX11_7_4, MMCSD0_DAT7);
	CSL_FINST(sysRegs->PINMUX11, SYSCFG_PINMUX11_PINMUX11_3_0, MMCSD0_DAT6);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_31_28, MMCSD0_DAT5);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_27_24, MMCSD0_DAT4);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_23_20, MMCSD0_DAT3);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_19_16, MMCSD0_DAT2);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_15_12, MMCSD0_DAT1);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_11_8, MMCSD0_DAT0);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_7_4, MMCSD0_CMD);
	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_3_0, MMCSD0_CLK);

	// Enable power for DDR2/mDDR controler
//	1. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0. You must wait for any
//	previously initiated transitions to finish before initiating a new transition.
	while (CSL_FEXT(psc0Regs->PTSTAT, PSC_PTSTAT_GOSTAT0) != 0) {
		;
	}
//	2. Set the NEXT bit in MDCTLn to SwRstDisable (0), SyncReset (1), Disable (2h),
//	Enable (3h), Auto Sleep (4h) or Auto Wake (5h).
	CSL_FINST(psc0Regs->MDCTL[CSL_PSC_MMCSD0], PSC_MDCTL_NEXT, ENABLE);
//	3. Set the GO[x] bit in PTCMD to 1 to initiate the transition(s).
	CSL_FINST(psc0Regs->PTCMD, PSC_PTCMD_GO0, SET);
//	4. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0. The modules are safely
//	in the new states only after the GOSTAT[x] bit in PTSTAT is cleared to 0.
	while (CSL_FEXT(psc0Regs->PTSTAT, PSC_PTSTAT_GOSTAT0) != 0) {
		;
	}

//	1. Place the MMC/SD controller in its reset state by setting the CMDRST bit
//	and DATRST bit in the MMC control register (MMCCTL). You can set other bits
//	in MMCCTL after reset.
	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_CMDRST, DISABLE);
	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_DATRST, DISABLE);

//	if an SD card is connected, specify a 4-bit data bus (WIDTH = 1 in MMCCTL).
	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_WIDTH0, 4BIT);

//	2. Write the required values to other registers to complete the MMC/SD
//	controller configuration.

//	A clock divider in the MMC/SD controller divides-down the function clock to
//	produce the memory clock. Load the divide-down value into the CLKRT bits in
//	the MMC memory clock control register (MMCCLK).
//	The divide-down value is determined by the following equation:
//		when DIV4 = 0 in MMCCLK:
//	memory clock frequency = function clock frequency/(2 � (CLKRT + 1))
//		when DIV4 = 1 in MMCCLK:
//	memory clock frequency = function clock frequency/(4 � (CLKRT + 1))
//
//	The CLKEN bit in MMCCLK determines whether the memory clock appears on the
//	MMCSD_CLK pin. If you clear the CLKEN to 0, the memory clock is not provided
//	except when required.

//	The function clock frequency will be 150Mhz and the memory clock frequency has to be
//	400 KHz or less during the initialization.
//	CLKRT = 187 = 0xBB

	CSL_FINS(mmcsd0Regs->MMCCLK, MMCSD_MMCCLK_CLKRT, 0xBB);

//	In doubt set timouts to maximums
	CSL_FINS(mmcsd0Regs->MMCTOR, MMCSD_MMCTOR_TOR, 0xFF);
	CSL_FINS(mmcsd0Regs->MMCTOR, MMCSD_MMCTOR_TOD_25_16, 0x3FF);
	CSL_FINS(mmcsd0Regs->MMCTOD, MMCSD_MMCTOD_TOD_15_0, 0xFFFF);

//	3. Clear the CMDRST bit and the DATRST bit in MMCCTL to release the MMC/SD
//	controller from its	reset state. It is recommended not to rewrite the values
//	that are written to the other bits of MMCCTL in .
	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_CMDRST, ENABLE);
	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_DATRST, ENABLE);

//	4. Enable the MMCSD_CLK pin so that the memory clock is sent to the memory
//	card by setting the CLKEN bit in the MMC memory clock control register (MMCCLK).
	CSL_FINST(mmcsd0Regs->MMCCLK, MMCSD_MMCCLK_CLKEN, ENABLE);
}

void SDCardIdentification(void) {
//	1. Use the MMC command register (MMCCMD) to issue the GO_IDLE_STATE (CMD0)
//	command to the MMC cards. Using MMCMD to issue the CMD0 command puts all cards
//	(MMC and SD) in the idle state and no response from the cards is expected.
	//allow 74+ clock cycle to the card for initialization after power up
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_INITCK, INIT);
	//set no data transfer with this command
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_WDATX, NO);
	//no response is expected
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, NORSP);
	//set CMD0
	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 0);

	//wait for the response/command to be done
	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
		;
	}

//	2. Use MMCCMD to issue the APP_CMD (CMD55) command (R1 response is expected) to
//	indicate that the command that follows is an application command.
	//unallow 74+ clock cycle to the card for initialization after power up
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_INITCK, NO);
	//set no data transfer with this command
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_WDATX, NO);
	//R1 response is expected
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R1);
	//the response is not expected to be a R1b
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_BSYEXP, NO);
	//set CMD55
	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 55);

	//wait for the response/command to be done
	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
		;
	}

//	3. Use MMCCMD to send the SD_SEND_OP_COND (ACMD41) command with the voltage
//	range supported (R3 response is expected) to SD cards. Using MMCCMD to send the
//	ACMD41 command allows the host to identify and reject cards that do not match
//	the VDD range that the host supports.
	//R3 response is expected
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R3);
	//set CMD41
	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 41);

	//wait for the response/command to be done
	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
		;
	}

//	4. Use MMCCMD to send the ALL_SEND_CID (CMD2) command (R2 response is expected)
//	to the MMC cards. Using MMCCMD to send the CMD2 command notifies all cards to
//	send their unique card identification (CID) number. There should only be one
//	card that successfully sends its full CID number to the host. The successful
//	card goes into identification state and does not respond to this command
//	again.
	//R2 response is expected
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R2);
	//set CMD2
	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 2);

	//wait for the response/command to be done
	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
		;
	}

//	5. Use MMCMD to issue the SEND_RELATIVE_ADDR (CMD3) command (R1 response is
//	expected) in order to ask the card to publish a new relative address for future
//	use to address the card in data transfer mode.
	//R2 response is expected
	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R2);
	//set CMD2
	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 2);

	//wait for the response/command to be done
	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
		;
	}
//	6. Repeat Step 4 and Step 5 to identify and retrieve relative addresses from all
//	remaining SD cards until no card responds to the CMD2 command. No card
//	responding within 5 memory clock cycles indicates that all cards have been
//	identified and the MMC card and the identification procedure terminates.
}

Thank you for any help you can provide me.

Arthur

  • Hi Arthur,

                Kindly clarify which code you have used in your omap-L138.Is it your custom code / TI proprietary code ?

    Further if you would like to look at the sequence of the SD card identification, you can look into the OMAP-L138 starterware –gpio example(C:\ti\OMAPL138_StarterWare_1_10_03_03\examples\evmOMAPL138\gpio) which uses MMCSD.

    Hope this helps.

    Regards,

    Iyshwarya

    If this answers your question, please click the Verify Answer button below. If not, please reply back with more information.

  • Hi Iyshwarya,

    Thank you for your answer.

    The code I have posted is mostly my custom code made from the documentation of the OMAP L138 Reference manual, and I use in this code the CSLs macro provided by TI.

    I have this week success fully send 3 commands and read the answers, but I don't know how to interpret this answers can you tell me more about the R1, R2 and R3 answer format ?

    Here is the new code :

    /*
     * bootloader_omapL138_SDCard.c
     *
     *  Created on: Mar 26, 2013
     *      Author: Omap
     */
    
    #include "..\OMAPL138_common.h"
    #include "../Types.h"
    #include "bootloader_omapL138_SDCard.h"
    #include <pspiom/cslr/cslr_mmcsd.h>
    #include <stdio.h>
    #include "clock.h"
    
    void SDCardInit(void) {
    	// Open Permissions to SYSCFG Registers
    	_call_swi(ARM_PRIV_MODE_KEY);
    
    	CSL_FINS(sysRegs->KICK0R, SYSCFG_KICK0R_KICK0, KICK0_KEY);
    	CSL_FINS(sysRegs->KICK1R, SYSCFG_KICK1R_KICK1, KICK1_KEY);
    
    	CSL_FINST(sysRegs->PINMUX11, SYSCFG_PINMUX11_PINMUX11_7_4, MMCSD0_DAT7);
    	CSL_FINST(sysRegs->PINMUX11, SYSCFG_PINMUX11_PINMUX11_3_0, MMCSD0_DAT6);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_31_28, MMCSD0_DAT5);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_27_24, MMCSD0_DAT4);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_23_20, MMCSD0_DAT3);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_19_16, MMCSD0_DAT2);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_15_12, MMCSD0_DAT1);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_11_8, MMCSD0_DAT0);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_7_4, MMCSD0_CMD);
    	CSL_FINST(sysRegs->PINMUX10, SYSCFG_PINMUX10_PINMUX10_3_0, MMCSD0_CLK);
    
    	// Enable power for DDR2/mDDR controler
    //	1. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0. You must wait for any
    //	previously initiated transitions to finish before initiating a new transition.
    	while (CSL_FEXT(psc0Regs->PTSTAT, PSC_PTSTAT_GOSTAT0) != 0) {
    		;
    	}
    //	2. Set the NEXT bit in MDCTLn to SwRstDisable (0), SyncReset (1), Disable (2h),
    //	Enable (3h), Auto Sleep (4h) or Auto Wake (5h).
    	CSL_FINST(psc0Regs->MDCTL[CSL_PSC_MMCSD0], PSC_MDCTL_NEXT, ENABLE);
    //	3. Set the GO[x] bit in PTCMD to 1 to initiate the transition(s).
    	CSL_FINST(psc0Regs->PTCMD, PSC_PTCMD_GO0, SET);
    //	4. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0. The modules are safely
    //	in the new states only after the GOSTAT[x] bit in PTSTAT is cleared to 0.
    	while (CSL_FEXT(psc0Regs->PTSTAT, PSC_PTSTAT_GOSTAT0) != 0) {
    		;
    	}
    
    //	1. Place the MMC/SD controller in its reset state by setting the CMDRST bit
    //	and DATRST bit in the MMC control register (MMCCTL). You can set other bits
    //	in MMCCTL after reset.
    	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_CMDRST, DISABLE);
    	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_DATRST, DISABLE);
    
    //	if an SD card is connected, specify a 4-bit data bus (WIDTH = 1 in MMCCTL).
    	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_WIDTH0, 4BIT);
    
    //	2. Write the required values to other registers to complete the MMC/SD
    //	controller configuration.
    
    //	A clock divider in the MMC/SD controller divides-down the function clock to
    //	produce the memory clock. Load the divide-down value into the CLKRT bits in
    //	the MMC memory clock control register (MMCCLK).
    //	The divide-down value is determined by the following equation:
    //		when DIV4 = 0 in MMCCLK:
    //	memory clock frequency = function clock frequency/(2 � (CLKRT + 1))
    //		when DIV4 = 1 in MMCCLK:
    //	memory clock frequency = function clock frequency/(4 � (CLKRT + 1))
    //
    //	The CLKEN bit in MMCCLK determines whether the memory clock appears on the
    //	MMCSD_CLK pin. If you clear the CLKEN to 0, the memory clock is not provided
    //	except when required.
    
    //	The function clock frequency will be 150Mhz and the memory clock frequency has to be
    //	400 KHz or less during the initialization.
    //	CLKRT = 187 = 0xBB
    
    	CSL_FINS(mmcsd0Regs->MMCCLK, MMCSD_MMCCLK_CLKRT, 0xBB);
    
    //	In doubt set timouts to maximums
    	CSL_FINS(mmcsd0Regs->MMCTOR, MMCSD_MMCTOR_TOR, 0xFF);
    	CSL_FINS(mmcsd0Regs->MMCTOR, MMCSD_MMCTOR_TOD_25_16, 0x3FF);
    	CSL_FINS(mmcsd0Regs->MMCTOD, MMCSD_MMCTOD_TOD_15_0, 0xFFFF);
    
    //	3. Clear the CMDRST bit and the DATRST bit in MMCCTL to release the MMC/SD
    //	controller from its	reset state. It is recommended not to rewrite the values
    //	that are written to the other bits of MMCCTL in .
    	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_CMDRST, ENABLE);
    	CSL_FINST(mmcsd0Regs->MMCCTL, MMCSD_MMCCTL_DATRST, ENABLE);
    
    //	4. Enable the MMCSD_CLK pin so that the memory clock is sent to the memory
    //	card by setting the CLKEN bit in the MMC memory clock control register (MMCCLK).
    	CSL_FINST(mmcsd0Regs->MMCCLK, MMCSD_MMCCLK_CLKEN, ENABLE);
    }
    
    void SDCardIdentification(void) {
    	UINT64 start;
    	UINT8 R1, R3[5], cidx;
    	UINT16 R2;
    
    	while (CSL_FEXT(mmcsd0Regs->MMCST1, MMCSD_MMCST1_BUSY)) {
    		;
    	}
    
    //	1. Use the MMC command register (MMCCMD) to issue the GO_IDLE_STATE (CMD0)
    //	command to the MMC cards. Using MMCMD to issue the CMD0 command puts all cards
    //	(MMC and SD) in the idle state and no response from the cards is expected.
    	//allow 74+ clock cycle to the card for initialization after power up
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_INITCK, INIT);
    	//set no data transfer with this command
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_WDATX, NO);
    	//no response is expected
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, NORSP);
    
    	mmcsd0Regs->MMCRSP01 = 0;
    	mmcsd0Regs->MMCRSP23 = 0;
    	mmcsd0Regs->MMCRSP45 = 0;
    	mmcsd0Regs->MMCRSP67 = 0;
    //	CLRBIT(mmcsd0Regs->MMCCIDX, CIDX_MASK);
    	CSL_FINST(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX, RESETVAL);
    
    	CSL_FINST(mmcsd0Regs->MMCARGHL, MMCSD_MMCARGHL_ARGH, RESETVAL);
    	CSL_FINST(mmcsd0Regs->MMCARGHL, MMCSD_MMCARGHL_ARGL, RESETVAL);
    
    	//set CMD0
    	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 0);
    
    	//wait for the response/command to be done
    //	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
    //		;
    //	}
    
    	start = readInfiniteTimer() + infiniteTimerBitsPerMilliSecond;
    	while (readInfiniteTimer() < start)
    		;
    
    	while (1) {
    		UINT32 stat_reg = mmcsd0Regs->MMCST0;
    
    		//
    		if (CSL_FEXT(stat_reg, MMCSD_MMCST0_RSPDNE)) {
    			printf("OK 1\n");
    			break;
    		} else if (CSL_FEXT(stat_reg, MMCSD_MMCST0_TOUTRS)) {
    			printf("timeout 1\n");
    			break;
    		}
    	}
    
    	start = readInfiniteTimer() + 200 * infiniteTimerBitsPerMilliSecond;
    	while (readInfiniteTimer() < start) {
    		;
    	}
    
    	while (CSL_FEXT(mmcsd0Regs->MMCST1, MMCSD_MMCST1_BUSY)) {
    		;
    	}
    
    //	2. Use MMCCMD to issue the APP_CMD (CMD55) command (R1 response is expected) to
    //	indicate that the command that follows is an application command.
    	//set CMD55
    	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 55);
    
    	//unallow 74+ clock cycle to the card for initialization after power up
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_INITCK, NO);
    	//set no data transfer with this command
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_WDATX, NO);
    	//R1 response is expected
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R1);
    	//the response is not expected to be a R1b
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_BSYEXP, NO);
    
    	mmcsd0Regs->MMCRSP01 = 0;
    	mmcsd0Regs->MMCRSP23 = 0;
    	mmcsd0Regs->MMCRSP45 = 0;
    	mmcsd0Regs->MMCRSP67 = 0;
    //	CLRBIT(mmcsd0Regs->MMCCIDX, CIDX_MASK);
    	CSL_FINST(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX, RESETVAL);
    
    	CSL_FINST(mmcsd0Regs->MMCARGHL, MMCSD_MMCARGHL_ARGH, RESETVAL);
    	CSL_FINST(mmcsd0Regs->MMCARGHL, MMCSD_MMCARGHL_ARGL, RESETVAL);
    
    	start = readInfiniteTimer() + infiniteTimerBitsPerMilliSecond;
    	while (readInfiniteTimer() < start)
    		;
    
    	//wait for the response/command to be done
    //	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
    //		;
    //	}
    
    	while (1) {
    		UINT32 stat_reg = mmcsd0Regs->MMCST0;
    
    		//
    		if (CSL_FEXT(stat_reg, MMCSD_MMCST0_RSPDNE)) {
    			printf("OK 2\n");
    			break;
    		} else if (CSL_FEXT(stat_reg, MMCSD_MMCST0_TOUTRS)) {
    			printf("timeout 2\n");
    			break;
    		}
    	}
    
    	R1 = CSL_FEXT(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX);
    	cidx = R1;
    
    	while (CSL_FEXT(mmcsd0Regs->MMCST1, MMCSD_MMCST1_BUSY)) {
    		;
    	}
    
    //	3. Use MMCCMD to send the SD_SEND_OP_COND (ACMD41) command with the voltage
    //	range supported (R3 response is expected) to SD cards. Using MMCCMD to send the
    //	ACMD41 command allows the host to identify and reject cards that do not match
    //	the VDD range that the host supports.
    	//set CMD41
    	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 41);
    
    	//R3 response is expected
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R3);
    
    	mmcsd0Regs->MMCRSP01 = 0;
    	mmcsd0Regs->MMCRSP23 = 0;
    	mmcsd0Regs->MMCRSP45 = 0;
    	mmcsd0Regs->MMCRSP67 = 0;
    //	CLRBIT(mmcsd0Regs->MMCCIDX, CIDX_MASK);
    	CSL_FINST(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX, RESETVAL);
    
    	//wait for the response/command to be done
    //	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
    //		;
    //	}
    
    	start = readInfiniteTimer() + infiniteTimerBitsPerMilliSecond;
    	while (readInfiniteTimer() < start)
    		;
    
    	while (1) {
    		UINT32 stat_reg = mmcsd0Regs->MMCST0;
    
    		//
    		if (CSL_FEXT(stat_reg, MMCSD_MMCST0_RSPDNE)) {
    			printf("OK 3\n");
    			break;
    		} else if (CSL_FEXT(stat_reg, MMCSD_MMCST0_TOUTRS)) {
    			printf("timeout 3\n");
    			break;
    		}
    	}
    
    	R3[0] = CSL_FEXT(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX);
    	R3[1] = CSL_FEXT(mmcsd0Regs->MMCRSP67, MMCSD_MMCRSP67_MMCRSP6) & 0xFF;
    	R3[2] = CSL_FEXT(mmcsd0Regs->MMCRSP67, MMCSD_MMCRSP67_MMCRSP6) >> 8;
    	R3[3] = CSL_FEXT(mmcsd0Regs->MMCRSP67, MMCSD_MMCRSP67_MMCRSP7) & 0xFF;
    	R3[4] = CSL_FEXT(mmcsd0Regs->MMCRSP67, MMCSD_MMCRSP67_MMCRSP7) >> 8;
    	cidx = R3[0];
    
    //	R1 = CSL_FEXT(mmcsd0Regs->MMCRSP45, MMCSD_MMCRSP45_MMCRSP5);
    //	cidx = CSL_FEXT(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX);
    
    	while (CSL_FEXT(mmcsd0Regs->MMCST1, MMCSD_MMCST1_BUSY)) {
    		;
    	}
    
    
    //	4. Use MMCCMD to send the ALL_SEND_CID (CMD2) command (R2 response is expected)
    //	to the MMC cards. Using MMCCMD to send the CMD2 command notifies all cards to
    //	send their unique card identification (CID) number. There should only be one
    //	card that successfully sends its full CID number to the host. The successful
    //	card goes into identification state and does not respond to this command
    //	again.
    	//R2 response is expected
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R2);
    	//set CMD2
    	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 2);
    
    	mmcsd0Regs->MMCRSP01 = 0;
    	mmcsd0Regs->MMCRSP23 = 0;
    	mmcsd0Regs->MMCRSP45 = 0;
    	mmcsd0Regs->MMCRSP67 = 0;
    //	CLRBIT(mmcsd0Regs->MMCCIDX, CIDX_MASK);
    	CSL_FINST(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX, RESETVAL);
    
    	//wait for the response/command to be done
    //	while (CSL_FEXT(mmcsd0Regs->MMCST0, MMCSD_MMCST0_RSPDNE) != 1) {
    //		;
    //	}
    
    	start = readInfiniteTimer() + 25*infiniteTimerBitsPerMilliSecond;
    	while (readInfiniteTimer() < start)
    		;
    
    	while (1) {
    		UINT32 stat_reg = mmcsd0Regs->MMCST0;
    
    		//
    		if (CSL_FEXT(stat_reg, MMCSD_MMCST0_RSPDNE)) {
    			printf("OK 4\n");
    			break;
    		} else if (CSL_FEXT(stat_reg, MMCSD_MMCST0_TOUTRS)) {
    			printf("timeout 4\n");
    			break;
    		}
    	}
    
    	R2 = CSL_FEXT(mmcsd0Regs->MMCRSP01, MMCSD_MMCRSP01_MMCRSP0);
    	cidx = CSL_FEXT(mmcsd0Regs->MMCCIDX, MMCSD_MMCCIDX_CIDX);
    
    //	5. Use MMCMD to issue the SEND_RELATIVE_ADDR (CMD3) command (R1 response is
    //	expected) in order to ask the card to publish a new relative address for future
    //	use to address the card in data transfer mode.
    	//R1 response is expected
    	CSL_FINST(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_RSPFMT, R1);
    	//set CMD2
    	CSL_FINS(mmcsd0Regs->MMCCMD, MMCSD_MMCCMD_CMD, 2);
    
    	//wait for the response/command to be done
    	while (1) {
    		UINT32 stat_reg = mmcsd0Regs->MMCST0;
    
    		//
    		if (CSL_FEXT(stat_reg, MMCSD_MMCST0_RSPDNE)) {
    			printf("OK 5\n");
    			break;
    		} else if (CSL_FEXT(stat_reg, MMCSD_MMCST0_TOUTRS)) {
    			printf("timeout 5\n");
    			break;
    		}
    	}
    //	6. Repeat Step 4 and Step 5 to identify and retrieve relative addresses from all
    //	remaining SD cards until no card responds to the CMD2 command. No card
    //	responding within 5 memory clock cycles indicates that all cards have been
    //	identified and the MMC card and the identification procedure terminates.
    }
    

    Are you sure about your gpio example from starterWare 1_10_03_3 ? because it seems that in this example the only thing that is check is the button inside the MMC/SD port triggered by the card when it is inserted and each time a card is inserted or removed a sentence is send on the serial link. I'm still interested in a fully functional example on how to initialize, read from and write to an SD card.

    Cordially

    Arthur