EmbeddedRelated.com
Forums

SD(HC) support on LPC21XX? Using pre-written driver, SC works but HC fails CRC16

Started by lawzaz July 1, 2012
Hi,

I'm trying to log data to an SD card on the LPC2129. I have a good SPI driver written, and I can read/write regular SDSC and MMC cards using the driver here:

https://github.com/vsergeev/embedded-drivers/blob/master/sd.c

This seems to follow SD spec (with the possible exception of querying voltage using CMD58 early), and works great for standard capacity cards. However, anything high capacity simply fails. While it attempts to set all V2 and V3 cards to high capacity, even HCS cards fail the test of CCS in OCR read (line 1284):

if ((response[3] & (1<<6)) != 0x00)...

If I force SDHC support and tell it to use block rather than byte addressing, initialization still fails.

In both cases, it starts off:
CMD0 - Go idle
CMD8 - Determine version, set voltage
CMD58 - Check voltage
Loop:
CMD55 - prepare for ACMD41
ACMD41 - initialize
Break:
CMD58 - read OCR, check CCS for HCS
Then, because it doesn't read this right, it proceeds to set block length (CMD16) in both cases. CMD16 returns valid for SDSC and SDHC.

SDSC cards continue with CMD12, and then 18 and continue sworking. SDSC cards continue with CMD18, which fails CRC16, and then stops on CMD12, failing initialization.

Does anyone have experience they can share re: SDSC/SDHC over SPI? I'm using SanDisk cards, so they should be compliant with the spec...

Thanks!

(I'm using Chan's FatFS and there is a possibility that there may be an issue addressing 2gb & larger cards, but I doubt it since this FS supports IDE HDDs)

An Engineer's Guide to the LPC2100 Series

--- In l..., "lawzaz" wrote:
>
> Hi,
>
> I'm trying to log data to an SD card on the LPC2129. I have a good SPI driver written, and I can read/write regular SDSC and MMC cards using the driver here:
>
> https://github.com/vsergeev/embedded-drivers/blob/master/sd.c
>
> This seems to follow SD spec (with the possible exception of querying voltage using CMD58 early), and works great for standard capacity cards. However, anything high capacity simply fails. While it attempts to set all V2 and V3 cards to high capacity, even HCS cards fail the test of CCS in OCR read (line 1284):
>
> if ((response[3] & (1<<6)) != 0x00)...
>
> If I force SDHC support and tell it to use block rather than byte addressing, initialization still fails.
>
> In both cases, it starts off:
> CMD0 - Go idle
> CMD8 - Determine version, set voltage
> CMD58 - Check voltage
> Loop:
> CMD55 - prepare for ACMD41
> ACMD41 - initialize
> Break:
> CMD58 - read OCR, check CCS for HCS
> Then, because it doesn't read this right, it proceeds to set block length (CMD16) in both cases. CMD16 returns valid for SDSC and SDHC.
>
> SDSC cards continue with CMD12, and then 18 and continue sworking. SDSC cards continue with CMD18, which fails CRC16, and then stops on CMD12, failing initialization.
>
> Does anyone have experience they can share re: SDSC/SDHC over SPI? I'm using SanDisk cards, so they should be compliant with the spec...
>
> Thanks!
>
> (I'm using Chan's FatFS and there is a possibility that there may be an issue addressing 2gb & larger cards, but I doubt it since this FS supports IDE HDDs)

This interests me too. I use FATfs as well and, with my cardboard box of ancient, small SD/MMC cards, everything works just fine. Last week, I pugged in a large, modern card as a test and the FS failed to mount, presumably because the driver failed to init(). I did check that it was not formatted NTFS - I've been caught out by that before :(

I agree it's probably not an FATfs issue.

Unlike yourself, I haven't looked too deeply into the problem yet since my app has other 'issues' that need fixing, but I will have to get back to it. If I cannot init() it, I cannot even format it.

Rgds,
Martin
I also use FATfs but, as you suspect, the problem is lowe down than that since disk init() is a driver function. I

I may be recalling incorrectly, but I vaguely remember that high capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC nibble mode.
--- In l..., "mjames_doveridge" wrote:
>
> --- In l..., "lawzaz" wrote:
> >
> > Hi,
> >
> > I'm trying to log data to an SD card on the LPC2129. I have a good SPI driver written, and I can read/write regular SDSC and MMC cards using the driver here:
> >
> > https://github.com/vsergeev/embedded-drivers/blob/master/sd.c
> >
> > This seems to follow SD spec (with the possible exception of querying voltage using CMD58 early), and works great for standard capacity cards. However, anything high capacity simply fails. While it attempts to set all V2 and V3 cards to high capacity, even HCS cards fail the test of CCS in OCR read (line 1284):
> >
> > if ((response[3] & (1<<6)) != 0x00)...
> >
> > If I force SDHC support and tell it to use block rather than byte addressing, initialization still fails.
> >
> > In both cases, it starts off:
> > CMD0 - Go idle
> > CMD8 - Determine version, set voltage
> > CMD58 - Check voltage
> > Loop:
> > CMD55 - prepare for ACMD41
> > ACMD41 - initialize
> > Break:
> > CMD58 - read OCR, check CCS for HCS
> > Then, because it doesn't read this right, it proceeds to set block length (CMD16) in both cases. CMD16 returns valid for SDSC and SDHC.
> >
> > SDSC cards continue with CMD12, and then 18 and continue sworking. SDSC cards continue with CMD18, which fails CRC16, and then stops on CMD12, failing initialization.
> >
> > Does anyone have experience they can share re: SDSC/SDHC over SPI? I'm using SanDisk cards, so they should be compliant with the spec...
> >
> > Thanks!
> >
> > (I'm using Chan's FatFS and there is a possibility that there may be an issue addressing 2gb & larger cards, but I doubt it since this FS supports IDE HDDs)
>
> This interests me too. I use FATfs as well and, with my cardboard box of ancient, small SD/MMC cards, everything works just fine. Last week, I pugged in a large, modern card as a test and the FS failed to mount, presumably because the driver failed to init(). I did check that it was not formatted NTFS - I've been caught out by that before :(
>
> I agree it's probably not an FATfs issue.
>
> Unlike yourself, I haven't looked too deeply into the problem yet since my app has other 'issues' that need fixing, but I will have to get back to it. If I cannot init() it, I cannot even format it.
>
> Rgds,
> Martin
> I also use FATfs but, as you suspect, the problem is lowe down than that since disk init() is a driver function. I
>

Interesting. Supposedly, it's an "option," but SanDisk generally supports the SD spec the best. If it didn't support SPI, it shouldn't handle the other commands, though...

I tried a 2GB SDSC card today and that failed as well. I also tried changing the block size to 1024 and running that, it still failed. Failure mode was
58
16
18
12

(bad CRC16 again). I've also tried turning CRC mode off.

--- In l..., "stevec" wrote:
>
> I may be recalling incorrectly, but I vaguely remember that high capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC nibble mode.
> --- In l..., "mjames_doveridge" wrote:
> >
> >
> >
> > --- In l..., "lawzaz" wrote:
> > >
> > > Hi,
> > >
> > > I'm trying to log data to an SD card on the LPC2129. I have a good SPI driver written, and I can read/write regular SDSC and MMC cards using the driver here:
> > >
> > > https://github.com/vsergeev/embedded-drivers/blob/master/sd.c
> > >
> > > This seems to follow SD spec (with the possible exception of querying voltage using CMD58 early), and works great for standard capacity cards. However, anything high capacity simply fails. While it attempts to set all V2 and V3 cards to high capacity, even HCS cards fail the test of CCS in OCR read (line 1284):
> > >
> > > if ((response[3] & (1<<6)) != 0x00)...
> > >
> > > If I force SDHC support and tell it to use block rather than byte addressing, initialization still fails.
> > >
> > > In both cases, it starts off:
> > > CMD0 - Go idle
> > > CMD8 - Determine version, set voltage
> > > CMD58 - Check voltage
> > > Loop:
> > > CMD55 - prepare for ACMD41
> > > ACMD41 - initialize
> > > Break:
> > > CMD58 - read OCR, check CCS for HCS
> > > Then, because it doesn't read this right, it proceeds to set block length (CMD16) in both cases. CMD16 returns valid for SDSC and SDHC.
> > >
> > > SDSC cards continue with CMD12, and then 18 and continue sworking. SDSC cards continue with CMD18, which fails CRC16, and then stops on CMD12, failing initialization.
> > >
> > > Does anyone have experience they can share re: SDSC/SDHC over SPI? I'm using SanDisk cards, so they should be compliant with the spec...
> > >
> > > Thanks!
> > >
> > > (I'm using Chan's FatFS and there is a possibility that there may be an issue addressing 2gb & larger cards, but I doubt it since this FS supports IDE HDDs)
> >
> > This interests me too. I use FATfs as well and, with my cardboard box of ancient, small SD/MMC cards, everything works just fine. Last week, I pugged in a large, modern card as a test and the FS failed to mount, presumably because the driver failed to init(). I did check that it was not formatted NTFS - I've been caught out by that before :(
> >
> > I agree it's probably not an FATfs issue.
> >
> > Unlike yourself, I haven't looked too deeply into the problem yet since my app has other 'issues' that need fixing, but I will have to get back to it. If I cannot init() it, I cannot even format it.
> >
> > Rgds,
> > Martin
> >
> >
> > I also use FATfs but, as you suspect, the problem is lowe down than that since disk init() is a driver function. I
>

--- In l..., "lawzaz" wrote:
> Does anyone have experience they can share re: SDSC/SDHC over SPI? I'm using SanDisk cards, so they should be compliant with the spec...
>

There was a discussion titled "SD snd SDHC card differences" in the comp.arch.embedded Usenet newsgroup a couple of years ago. If you do not have Usenet access you can view it here:

http://compgroups.net/comp.arch.embedded/sd-snd-sdhc-card-differences/198869

Regards,
Chris Burrows
Astrobe v4.2: Oberon for Cortex-M3 Development System
http://www.astrobe.com

--- In l..., "stevec" wrote:
>
> I may be recalling incorrectly, but I vaguely remember that high capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC nibble mode.
>

I have my controller in 4-bit mode. It is, of course, quite possible that the OP and I have completely different bugs with the same symptoms :(

Rgds,
Martin

That may be the case. I am using SPI mode.

My 2GB card has 1024 byte sectors, so I modified the MAX_SS in FatFS to 1024 and change block size command to no avail. It fails on 2GB SDSC cards as well as the HC cards. I'm really at a loss here, and unfortunately 1GB microSD cards are hard to find local.

--- In l..., "mjames_doveridge" wrote:
>
> --- In l..., "stevec" wrote:
> >
> > I may be recalling incorrectly, but I vaguely remember that high capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC nibble mode.
> > I have my controller in 4-bit mode. It is, of course, quite possible that the OP and I have completely different bugs with the same symptoms :(
>
> Rgds,
> Martin
>

I'm using a regular SD card, in SPI mode on a LPC2148 and can use any
card up to 8GB. I haven't tried anything higher, but I assume it would
work the same. Your sequence of commands is pretty much what I do.
What status are you getting when you issue a CMD8? What is your CMD8
command sequence? You state 'set voltage', but I think it's only a
command that helps determine whether VER1, VER2 or HC card. At least
that's what I have documented. It's been a few years since I messed
with it.

Sutton

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr. #100
Kennesaw, GA 30144
800-207-6269, 770-514-7999, 770-514-1285 FAX
s...@lookoutportablesecurity.com
On 7/2/2012 12:21 PM, lawzaz wrote:
>
> That may be the case. I am using SPI mode.
>
> My 2GB card has 1024 byte sectors, so I modified the MAX_SS in FatFS
> to 1024 and change block size command to no avail. It fails on 2GB
> SDSC cards as well as the HC cards. I'm really at a loss here, and
> unfortunately 1GB microSD cards are hard to find local.
>
> --- In l... ,
> "mjames_doveridge" wrote:
> >
> >
> >
> > --- In l... ,
> "stevec" wrote:
> > >
> > > I may be recalling incorrectly, but I vaguely remember that high
> capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC
> nibble mode.
> > >
> >
> > I have my controller in 4-bit mode. It is, of course, quite possible
> that the OP and I have completely different bugs with the same symptoms :(
> >
> > Rgds,
> > Martin
> >


Thank you for looking. I found a few parts of the program that I had to change and I'm further along, but still not quite there. To give my part back to the community, I'll post what I've changed and what I learned.

Change 1:
MSB/LSB error in the driver code. There is a line
if (((response[3] & (1<<6)) != 0x00)
that should be
if (((response[1] & (1<<6)) != 0x00)
Now, I can correctly identify SDSC or SDHC. Small victory.

Change 2:
When I mount the FS and open the directory, the FS mounts but f_opendir returns a DISK_ERR. If I repeat the process of doing f_mount and then f_opendir, both succeed the second time. I don't know why this works, but it does. Not all cards require this loop.

Now, all SDSC cards <= 1GB work. I don't care about 2GB cards with their 1024 byte sectors, but SDHC still does not work. f_mount is successful, but f_opendir still fails. Specifically, CMD18 fails with a bad CRC16. If SDHC, I set address /= 512; . Do I need to do the same with dataLen?

Thanks again for the eyes and time. Hopefully someone else is learning along with me.

--- In l..., Sutton Mehaffey wrote:
>
> I'm using a regular SD card, in SPI mode on a LPC2148 and can use any
> card up to 8GB. I haven't tried anything higher, but I assume it would
> work the same. Your sequence of commands is pretty much what I do.
> What status are you getting when you issue a CMD8? What is your CMD8
> command sequence? You state 'set voltage', but I think it's only a
> command that helps determine whether VER1, VER2 or HC card. At least
> that's what I have documented. It's been a few years since I messed
> with it.
>
> Sutton
>
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr. #100
> Kennesaw, GA 30144
> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> sutton@...
> On 7/2/2012 12:21 PM, lawzaz wrote:
> >
> > That may be the case. I am using SPI mode.
> >
> > My 2GB card has 1024 byte sectors, so I modified the MAX_SS in FatFS
> > to 1024 and change block size command to no avail. It fails on 2GB
> > SDSC cards as well as the HC cards. I'm really at a loss here, and
> > unfortunately 1GB microSD cards are hard to find local.
> >
> > --- In l... ,
> > "mjames_doveridge" wrote:
> > >
> > >
> > >
> > > --- In l... ,
> > "stevec" wrote:
> > > >
> > > > I may be recalling incorrectly, but I vaguely remember that high
> > capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC
> > nibble mode.
> > > >
> > >
> > > I have my controller in 4-bit mode. It is, of course, quite possible
> > that the OP and I have completely different bugs with the same symptoms :(
> > >
> > > Rgds,
> > > Martin
> > >
> >
> >
>
>

Here are my comments for card init. This is after CMD0 was successful.

// Determines whether card type is SD-Version 1, SD-Version 2 or HCSD card
// MMC card not supported, for now

// this uses the SD Spec, Version 2.00, Sept. 25, 2006, p. 95

// Initialization procedure (must be done after every RESET - CMD0)
// - issue CMD8 - check to see if card supports this command.
// - this command is only valid in SD Version 2 and HCSD cards.
// - save status of CMD8 for later - 0x05 is invalid command, 0x01 is
accepted.
// - Read_OCR - operating condition register - 4 bytes.
// - status should be 0x01, since card is not initialized yet.
// - check voltage level to be sure card can be used.
// - issue CMD55-ACMD41 combination and wait for status on ACMD41 to be
0x00.
// - status of 0x01 means initialization is not complete yet.
// - all ACMD commands MUST be preceeded by CMD55.
// - ACMD41 is the card initialization command.
// - after card init is OK (status = 0x01), Read_OCR a second time - 4
bytes.
// - the status should be 0x00, since card is initialized.
// - make sure the voltage is still OK.
// - check bit 30 of the OCR.
// - if '1', then HCSD card.
// - if '0' and CMD8 status accepted, then 'SD-Version 2'.
// - if '0' and CMD8 rejected, then 'SD-Version 1".

I use my own library for manipulating files after initialization, so I'm
not sure I'd be any help on the correct sequences for your library
functions. As, I don't have any knowledge on specifically what each of
those functions entails as far as command sequences. Is that driver
code something you wrote, or was it something that you found somewhere
and are editing? I wrote my own init functions and all my other
functions, so I knew exactly what was happening on the card.

Sutton

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr. #100
Kennesaw, GA 30144
800-207-6269, 770-514-7999, 770-514-1285 FAX
s...@lookoutportablesecurity.com
On 7/2/2012 10:19 PM, lawzaz wrote:
>
> Thank you for looking. I found a few parts of the program that I had
> to change and I'm further along, but still not quite there. To give my
> part back to the community, I'll post what I've changed and what I
> learned.
>
> Change 1:
> MSB/LSB error in the driver code. There is a line
> if (((response[3] & (1<<6)) != 0x00)
> that should be
> if (((response[1] & (1<<6)) != 0x00)
> Now, I can correctly identify SDSC or SDHC. Small victory.
>
> Change 2:
> When I mount the FS and open the directory, the FS mounts but
> f_opendir returns a DISK_ERR. If I repeat the process of doing f_mount
> and then f_opendir, both succeed the second time. I don't know why
> this works, but it does. Not all cards require this loop.
>
> Now, all SDSC cards <= 1GB work. I don't care about 2GB cards with
> their 1024 byte sectors, but SDHC still does not work. f_mount is
> successful, but f_opendir still fails. Specifically, CMD18 fails with
> a bad CRC16. If SDHC, I set address /= 512; . Do I need to do the same
> with dataLen?
>
> Thanks again for the eyes and time. Hopefully someone else is learning
> along with me.
> --- In l... ,
> Sutton Mehaffey wrote:
> >
> > I'm using a regular SD card, in SPI mode on a LPC2148 and can use any
> > card up to 8GB. I haven't tried anything higher, but I assume it would
> > work the same. Your sequence of commands is pretty much what I do.
> > What status are you getting when you issue a CMD8? What is your CMD8
> > command sequence? You state 'set voltage', but I think it's only a
> > command that helps determine whether VER1, VER2 or HC card. At least
> > that's what I have documented. It's been a few years since I messed
> > with it.
> >
> > Sutton
> >
> > Sutton Mehaffey
> > Lookout Portable Security
> > 4040 Royal Dr. #100
> > Kennesaw, GA 30144
> > 800-207-6269, 770-514-7999, 770-514-1285 FAX
> > sutton@...
> >
> >
> > On 7/2/2012 12:21 PM, lawzaz wrote:
> > >
> > > That may be the case. I am using SPI mode.
> > >
> > > My 2GB card has 1024 byte sectors, so I modified the MAX_SS in FatFS
> > > to 1024 and change block size command to no avail. It fails on 2GB
> > > SDSC cards as well as the HC cards. I'm really at a loss here, and
> > > unfortunately 1GB microSD cards are hard to find local.
> > >
> > > --- In l...
> ,
> > > "mjames_doveridge" wrote:
> > > >
> > > >
> > > >
> > > > --- In l...
> ,
> > > "stevec" wrote:
> > > > >
> > > > > I may be recalling incorrectly, but I vaguely remember that high
> > > capacity cards (SDHC) cannot use SPI mode, only the proprietary MMC
> > > nibble mode.
> > > > >
> > > >
> > > > I have my controller in 4-bit mode. It is, of course, quite
> possible
> > > that the OP and I have completely different bugs with the same
> symptoms :(
> > > >
> > > > Rgds,
> > > > Martin
> > > >
> > >
> > >
> >
> >
> >
> >