I am using the following sequence of commands at 250 kHz SPI to initialize SD cards:

  • (1 ms wait, then 80 clocks)
  • CMD0 with argument 0x00000000
  • CMD59 with argument 0x00000001 (turn on CRC checking)
  • CMD8 with argument 0x000001AA
  • CMD55 with argument 0x00000000 (prefix for ACMD)
  • ACMD41 with argument 0x40000000 (HCS bit set)

Of course repeating the CMD55-ACMD41 until getting out of Idle state. The CRCs are correct (they are calculated with the appropriate algorithm). Chip Select is released after every command (including between CMD55 and ACMD41) with eight trailing clocks.

This sequence works fine for three SDSC cards I have; I can read data from them after the completion of the initialization. However, the two SDHC cards I have fail with it.

They both progress properly until CMD55 (including experiencing a 0x01 R1 response from CMD8), then to CMD55 they react the following manner:

  • Maxell X Series SDHC Class 4 8 GB (S708G1249 TP2T0M2B49059): No R1 even after receiving 256 0xFF stuff bytes.

  • PQI SDHC Class 4 4 GB (BH1013316030G): 0xC2 comes after 5 0xFF stuff bytes, which has bit 7 set (an R1 shouldn't have this bit set), otherwise it doesn't even have bit 0 set (Idle) as it should be.

Issuing ACMD41 after this on either card results in an R1 of 0x05 (Illegal command + Idle). Now what? I didn't try to initialize them with CMD1 yet (but as they are SDHC, they shouldn't react to that).

(Both cards operate normally when accessed by a PC or in a digital camera I have.)

I tried issuing other commands; they also fail in this manner. So it rather seems like after CMD8 the card somehow became totally inaccessible despite the valid R1.

  • \$\begingroup\$ I am currently trying to read/write data using an SDHC card in SPI mode. I'm having a very similar issue. \$\endgroup\$ – Calvin Wallen IV Sep 30 '17 at 22:47
  • \$\begingroup\$ I get a proper R1 back after sending CMD8, but my CMD55+ACMD41 command sequence fails. The main difference is that CMD55 returns what I believe is a correct R1 (I get 0x00; I think 0x00 AND 0x01 are acceptable values), but my ACMD41 returns 0x01 when it's supposed to return 0x00 (at least from what I understand). Also, I haven't seen CMD59 used in any of the SPI initialization flowcharts. Why did you use it and how did it help? Anyways, I was hoping you might post the code you wrote allowing you to read the full R7? \$\endgroup\$ – Calvin Wallen IV Sep 30 '17 at 22:47
  • \$\begingroup\$ @CalvinWallenIV You get proper response for that ACMD41 (Idle), you need to poll the card (could be several dozen milliseconds) until the card crawls out of Idle. If you want, you could check the code, it is a new bootloader for the Uzebox game console here: uzebox.org/forums/viewtopic.php?f=3&t=9405 , full AVR assembler (later it will be added to the project's GitHub repo, currently it is just there as an experimental thing). \$\endgroup\$ – Jubatian Nov 16 '17 at 12:10
  • \$\begingroup\$ @CalvinWallenIV CMD59 is not necessary, you can init the card without it. This command can be used to turn on CRC checking which was proven to be useful as cards or card-converters might have sloppy contacts (and in the case of Uzebox on home-made versions inadequate wiring or soldering may also come in play as potential sources for corruption). It ensures that you are getting the right data. \$\endgroup\$ – Jubatian Nov 16 '17 at 12:44

I found it at last.

You have to read the full R7 from CMD8, otherwise seemingly SDHC cards deadlock in some manner so they are no longer accessible at all (I accidentally omitted reading beyond the R1).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.