Sometimes I worry about myself. I could have just been normal and used an SD card in SPI mode like everyone. But, no, I had to be special and try to use an SD card in SD mode. Unlike every. single. other. person who has ever posted anything about using SD cards.
So this post falls somewhere between a plea for help and a tutorial on how to use an SD card in SD mode.
The first problem I ran into (apart from nobody at all posting anything about SD mode) is that there are a dozen conflicting datasheets over about two decades; none of which contained the whole story. You might expect the SD card association would be the place to start but the
Simplified Physical Layer Specification is
three hundred pages. And unless you already know what you're looking for it is almost impossible to find anything in it.
For example: When is data on the CMD line read by the card? Is it when the CLK transitions high-to-low or low-to-high? Or something else? It's on page
273 under bus timings. Like. I. just... Aaaagh
Attachment:
SD Card Bus Timing.png [ 72.91 KiB | Viewed 2854 times ]
I only found that after a muddy version in a twenty year old SanDisk datasheet that clued me in on what to search for.
Incidentally, the answer is
low-to-high. The SD card reads data on the CMD line when the CLK goes low-to-high. And the host must similarly read data on the CMD line (presented by the card) when the CLK goes low-to-high.
Speaking of CMD, below is an SD card pin-out:
Attachment:
SD Card Pins.png [ 99.79 KiB | Viewed 2854 times ]
With that out the way let the adventure begin with trying to initialise an SD card.
Attachment:
SD Card Initialistion Flow.png [ 157.55 KiB | Viewed 2854 times ]
First you have to put a newly powered up card into IDLE mode by sending it cmd0 and then send it cmd8 to ask what voltages it supports.
Before you can send
cmd0 you you have to set CMD high and
tick the CLK 80 times at 100KHz. Or maybe you have to tick the clock 75 times. Or none. I ticked it 8 times and the category 10 SanDisk card I'm using seemed happy.
Again before cmd0 can be sent to put the card in SD mode
DAT3 must be set high too. In theory all you DAT lines should be set as high impedance inputs and each should have a 10KΩ+ pull up resistor on. I used pull down resistors (because of course I did) so I had to set DAT3 as a high output because I couldn't rely on the (non-existent) pull-up resistor to do it for me. Still worked fine though. CMD should also have a 10KΩ+ pull up resistor. If DAT3 is set a low output the SD card will switch into SPI mode at this point.
Next we're going to jump straight over how to send commands and take a look at what a successfully sent command looks like on an oscilloscope. A picture really is worth a thousand words.
Attachment:
SD Card Cmd0 Detail.png [ 128.49 KiB | Viewed 2854 times ]
A SD card command has the following form:
Attachment:
SD Card Command Format.png [ 17.16 KiB | Viewed 2765 times ]
It is sent on the CMD line at one bit per CLK tick from the highest bit first, bit 47, until the stop transmission bit, bit 0. The stop transmission bit basically just leaves CMD high so that the next transmission start bit can be detected. With that said it has been suggested that CLK should be ticked 8 times after cmd0 has been sent to allow the card to initialise itself. Is it necessary nowadays? I don't know but I'm afraid to not tick the clock of the idle command now.
The argument bits to cmd0 are ignored but best practice is to send all zeros. It's also worth noting there is a bit of confusion around the internet on what the CRC of an SD card command is (either in SD mode or SPI mode). The SD card command uses a crc7 with the generator polynomial: x7 + x3 + 1. For the five cmd0 zero bytes 0x40 00 00 00 00 that 7 bit crc is calculated to be 0x4a. To bring it to 8 bits the stop transmission bit is appended to the end making the 6 byte for cmd0 0x95.
0x95 is not the CRC 0x4a is.
In the attached oscilloscope screenshot you might have seen that I hold the clock high for some time after I'm done ticking cmd0. That's not intentional, it is an artifact from the Raspberry Pi Pico I'm using to bit-bang out the signal. I suspect it has something to do with the debugger but having it attached or not makes no difference. The Pico pauses occasionally but very consistently.
After the SD card has been placed in idle mode with cmd0 (and there is no response to cmd0 so in SD mode so you just have to hope it worked); then cmd8 must be sent to select the allowed supply voltage. Practically there is only one voltage option so set command bit 16 to a one. Bits 19 to 16 are the voltage arguments but I think it might be best to steer clear of low voltage SD cards for hobby projects.
Attachment:
SD Card Cmd8 Detail.png [ 120.25 KiB | Viewed 2854 times ]
cmd8 is useful in that it also has a check pattern that will be echoed back in its response. I've used 0xAA but the choice of bits is entirely optional.
Once I'm done banging out the command the CMD line must be set to input as cmd8 expects a response. The line briefly goes to a noise high impedance state from both the Pico (the host) and the SD card. I did eventually swap out my pull-down for pull-up resistors.
Within two clock ticks after completing the command send the SD card has grabbed the CMD line and started driving it high.
Attachment:
SD Card Cmd8 Response Detail.png [ 122.23 KiB | Viewed 2854 times ]
A few clock ticks later and the SD cards transmission start bit (a zero) is seen on the CMD line followed by another zero indicating it is the card transmitting. CLK is still being driven by the Pico and is never set to be an input.
The most interesting thing to note here (apart from getting any response at all from the blasted card) is the the check pattern being echoed back. Bit 16 will also be set to indicate the card supports 3.3V. The long clock on the last check bit is, again, the Pico doing some random wait thing.
And that's it for now. The start of a long journey but getting any response at all in SD mode is far from simple. I'm pretty happy with where it is and am going to leave it here for now.