Question

I'm using a microSD card in an embedded design. The card is connected to a microcontroller using the SPI interface. It worked fine for all cards I've used before, but now my new card will not initialize. The card is a Transcend 2 GB microSD card (TS2GUSD).

After sending the initial clock train to switch to SPI mode, I do the following:

  1. CMD0 (Argument 0, CRC 0x95) -> Response 0x01 -> OK

  2. CMD8 (Argument 0x000001AA, CRC 0x87) -> Response 0x01 0x000001AA -> Means it's SDC V2+ card, the voltage range 2.7 V - 3.6 V is supported -> OK

Then I should send the ACMD41 command, but when sending the CMD55 (argument 0, CRC 0) that must precede CMD41, I get response 0x05 -> Illegal Command. I've also tried to send CMD1 (for MMC cards), but it gives a similar illegal command response. The code works fine with my Sandisk 2 GB microSD card.

How do I fix this problem?

Was it helpful?

Solution

I seem to have found the issue. When I calculate the correct CRC for CMD55 and send that instead of a dummy CRC, the command is accepted (result 0x01). If you look at the physical layer specification in section 7.2.2, it explicitly says that:

The SPI interface is initialized in the CRC OFF mode in default. (except for commands CMD0 and CMD8).

This doesn't seem to be the case with this series of Transcend cards, thus violating the specification. Also in case of a CRC error the reply should be 0x09 instead of 0x05. I've tried to explicitly turn off CRC checking with CMD59, but that doesn't seem to help.

=> Calculating the correct CRC for (all?) commands makes the card work.

I'm in contact with Transcend support about this. If I learn something useful I'll you know here.

Note that I used other 2 GB Transcend cards before, but they were made in Taiwan, while the new one is made in Korea (and seems to be a Samsung card (MMAGR02GUDCA)).

OTHER TIPS

I had almost the same issue. When sending ACMD41, I sent CMD55 followed by CMD41. The response for CMD55 was 0x01, indicating idle state and running the initialization process (this is normal, I think). CMD41 would respond with 0x05, indicating illegal command. It turns out that my particular card does the CRC check by default, even in SPI mode, and misreports CRC errors as illegal commands (i.e., it doesn't follow the SD spec). When I calculate the proper CRC, it works fine. Here is the CRC7 calculation code I used, it has worked well for me:

https://github.com/hazelnusse/crc7

Unless you have taken care to disable CRC checking, I think it is probably best to assume it isn't disabled and make sure you calculate the proper CRC for each command frame. From what I can tell, some cards disable it by default in SPI mode and others enable it, even though the SD specification states it should be disabled by default in SPI mode except for CMD8.

You said you used CRC 0 for the failing command. I assume that you meant that you sent the whole last byte as 0x00. Note that the CRC7 is only the first 7 bits of the last byte - the last bit called end bit should always be 1. So if you were sending 0x00 as the last byte, with 0 as the last bit, the failure would be understandable, and even the error code would make sense. If you send 1 as the last bit, it should work, ie. use something like 0x01 or 0xFF as the last byte.

It's normal, it's likely the internal charge-pump used to make erase voltage that takes longer than usual to be ready... you have to insist on the CMD55+ACMD41 combo until initialization finishes.

The CMD58 could also help you to check if you're supplying correct voltage levels (sometimes sockets have contact problems).

Sending CMD0 with chip select(0) alone does not initialize the card in SPI mode. This only sets SPI mode. Card is not initialized until ACMD41 returns accepted. Then CRC is off by default.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top