µSD Card on SPI - Reading blocks returns all-zeros

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am attempting to interface an XMEGA 256A3U to a µSD card using SPI.

I have the hardware working, and all seems to go well until CM17 to read a single block.

 

I am using Chan's fatFS, release 0.13c - which I think is the latest.

I'm using a SanDisk 2GB micro-sd card.

 

So here's the story so far...

Figure 1. Over of timing from my logic anlayser. From the top, signals are: CS, MOSI, MISO, SCLK

Timing Overview

 

 

And zooming in on the important parts...

Figure 2. First command sent - CMD0 - Enter Idle Mode. This puts the device into SPI mode.

The correct response "0x01" is received meaning "Everything's fine, and I'm in Idle mode"

CMD0 with Response

 

 

Fig 3. Then, CMD8 is sent, and the sync pattern is correctly returned:

CMD8 with correct response

 

Fig 4 & 5 ACMD41 is sent. This reports the hosts capacity support to the card, and activates initialisation process. 

Since ACMDxx are "App Commands" they are always prefixed with CMD55 So here is CMD55 followed by ACMD41:

CMD55 being sent, with correct response

 

ACMD41 being sent, with "still initialising" response

Note the 0x01 response which means "still initialising..."

 

And the ACMD41 is repeated until we get an 0x00 (ready) response as seen here:

ACMD41 with "ready" response

 

So now we can issue CMD58 to read the OCR register:

CMD58 - read OCR

 

So all is well and good up to this point, so now I issue CM17 - READ_SINGLE_BLOCK.

This command responds with 0xFF until it's ready to send data, then 0xFE to tell you the data follows, and then the DATA:

CMD 17 - Read single block

 

But as you can see, the data is all 0x00 - the first two bytes for a formatted card should really be:0x55AA

This car still works fine an a PC and is formatted for Fat32.

 

So why does the CM17 (Read single Block) return all zeros?

 

Anyone see where I have gone wrong?

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SpiderKenny wrote:
But as you can see, the data is all 0x00 - the first two bytes for a formatted card should really be:0x55AA
Err no - the last two bytes of the 512 sector.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Err no - the last two bytes of the 512 sector.

Ah yes... my mistake. Sorry.  

However the first bytes shouldn't be all zero anyway. We should have a 3-Byte JMP instruction, OEM Name, Bytes-Per-Sector and so on etc etc

Yet it's all zero.  

 

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SpiderKenny wrote:
. We should have a 3-Byte JMP instruction, OEM Name, Bytes-Per-Sector and so on etc etc
Err no.

 

Sure the MBR/BPB specs say that those things CAN be there but think about your Sony camera or your Samsung phone - an Intel X86 JMP intsruction (as used to be found in the FAT boot sector of PC floppy disks) is no use to the ARM processor in your phone/camera (which isn't going to try and "Boot" from the card anyway).

 

So these days when you buy preformatted SD/MMC you generally find an MBR that only has one partition entry in bytes 0x1BE to 0x1CD and then 0x55,0xAA in bytes and all the other bytes in the sector are 0x00.

 

Also note that a card can start with an MBR (though, like I say, it likely only defines 1 of the 4 possible partitions) OR it can start with a boot/BPB. If there's an MBR then the first sector of the partition it defines will be a boot/BPB sector.

 

The best bet is to get WinHex from Xways software (read only trial version is free) and actually read the sectors of the card and take a look at what is really in sector 0. (as I say, expect bytes from 0x1BE on wards).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK that make sense, but I do read all 512 Bytes, and they are ALL 0x00.

You can't count the clocks, but in my first figure you can see the MISO line stays on 0 for the whole 512 byte read operation.

 

In fact you can see it retry after while and the same thing repeats. I must be doing something wrong to upset the card. I'll keep digging.

 

Thanks for your help!

 

 

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK I think I've found the issue.

My ACMD41 has the 'HCS' bit set, but this is not an HC card.

I must have a bug in my card feature detection logic.

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SpiderKenny wrote:
I must have a bug in my card feature detection logic.
Which does make me wonder why everyone doesn't simply use FatFs? Even if you aren't going to use the f_*() layer then use the disk_*() layer. For example Chan's disk_init() (which, as far as I know, works for all kinds of card) is:

DSTATUS mmc_disk_initialize (void)
{
	BYTE n, cmd, ty, ocr[4];


	power_off();						/* Turn off the socket power to reset the card */
	for (Timer1 = 10; Timer1; ) ;		/* Wait for 100ms */
	if (Stat & STA_NODISK) return Stat;	/* No card in the socket? */

	power_on();							/* Turn on the socket power */
	FCLK_SLOW();
	for (n = 10; n; n--) xchg_spi(0xFF);	/* 80 dummy clocks */

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			/* Put the card SPI mode */
		Timer1 = 100;						/* Initialization timeout of 1000 msec */
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* Is the card SDv2? */
			for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);	/* Get trailing return value of R7 resp */
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* The card can work at vdd range of 2.7-3.6V */
				while (Timer1 && send_cmd(ACMD41, 1UL << 30));	/* Wait for leaving idle state (ACMD41 with HCS bit) */
				if (Timer1 && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
					for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* Check if the card is SDv2 */
				}
			}
		} else {							/* SDv1 or MMCv3 */
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
			} else {
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
			}
			while (Timer1 && send_cmd(cmd, 0));			/* Wait for leaving idle state */
			if (!Timer1 || send_cmd(CMD16, 512) != 0)	/* Set R/W block length to 512 */
				ty = 0;
		}
	}
	CardType = ty;
	deselect();

	if (ty) {			/* Initialization succeded */
		Stat &= ~STA_NOINIT;		/* Clear STA_NOINIT */
		FCLK_FAST();
	} else {			/* Initialization failed */
		power_off();
	}

	return Stat;
}

You can see the CMD/ACMD sequence he uses in there.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes - he explicitly sets the block size to 512 bytes.

This is ignored by HC cards, where the block size is always 512 bytes. But I wonder if it's required for non HC cards.

Other than that his initialisation sequence is the same as mine.

I will give it a go and see what happens.

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

SOLVED.

It was a signal integrity issue. Sending CMD16 made no difference.

I removed and replaced the SD CARD holder and it works now.  I only noticed it when I used my 'scope instead of the logic analyser.

The fingers in SD Card holder require pressure from the PCB to make good contact with the SD card pads. This hand soldered prototype wasn't making good contact.  

SpiderKenny
@spiderelectron
www.spider-e.com