AVR

SD/MMC SPI Initialization Waveforms

Synopsis: This is an example AVR ATMega128 interaction with an SD/MMC Flash memory card using the SPI protocol. Until you’ve worked with the SPI protocol for reading or writing an SD/MMC card, it can be a little hard to visualize how SPI works with flash memory devices. It doesn’t show the code but focuses on the waveforms and timing on the wire for the 4 SPI signals - MOSI, MISO, SCK, and SS. It also shows how the protocol behaves in a real test with a Lexar or Kodak SD Card and what kind of timing is realistic.

[update 9/21/09: somewhere along the line the web tool I use stopped generating the correct link for the enlarged waveform shots. My apologies - it’s corrected now - can click on images to expand.]


These images clearly show how an AVR ATMega128 talks to an SD card through the SPI interface. The SPI physical level consists of 4 pins - MOSI (master out slave in), MISO (master in slave out), SS (slave select) and SCK (clock). These screen shots will show the state of the various SPI lines for slave select, MOSI, MISO, and Clock during the initialization sequence of an SD card.

This initialization sequence below demonstrates how to wake up an SD card and put it into SPI mode (vs an SD native mode API.)

This timing is taken from a working AVR ATMega128 to SD (Lexar 128MB) flash card initialization, so it’s known to work well. The clock needs to be relatively slow - 125kHz - SPI on the AVR ATMega128 can go up to 4MHz. Start slow and when you get something working, then you can try higher speeds. I’ve tried faster clocks and have not been able to get all SD’s to respond to the initialization sequence. I’ve seen code examples which do initialization at a very slow clock, then after the SD is in SPI mode (after this initialization sequence), they crank the clock speed up. I haven’t done enough experimentation to say what to crank it up to in order to achieve consistent results with various SD cards.

If you click on the screen shot you’ll get a full size image of the waveforms. These are wide images so either you may need to scroll horizontally to see it all or you will need to expand your browser window very wide to see it all

Waking Up an SD Card with SCK and CMD0

MMC-SPI-Initialization-Sequence
Click the images to enlarge - the SPI waveforms will be clearly seen in the large images.

The screen shot above shows the first stage of waking up an SD card. To start the sequence:

1.) Send 80 cycles of clock (usually 10 pokes of the AVR SPI register will clock these to the line as you see leading up to the sequence),
2.) Send a 0x40 (CMD0 | 0x40) per the specs for communicating to the SD card that it should switch to SPI mode), At the point you start this sequence, you’re technically in SD native mode, so you have to have a valid checksum byte (0x95.) After converting to SPI mode, the checksum byte may be ignored (or optionally enforced.)
3.) Send 4 bytes of 0x00. bytes are ignored but must be there as a placeholder
4.) Send checksum of 0x95.

Send 8-16 SCK cycles (2 spi() calls) and you should see a response from your SD Card. See the MISO line go from high to low about 16 clocks after the initial sequence was sent. The response you’re looking for after a CMD0 command is, 0x01. See the MISO data decode above. Unless you get that response, you can’t continue with the wake up sequence.

Notice that besides the clock (80 cycles) leading up to the main initialization sequence, the first action is the Slave Select line is pulled low because select is active low. If you have no other SPI devices on the bus, you can take it low and leave it there. It will stay low for the duration of the initialization sequence or at any other time you are reading or writing the device. For my tests, I take it low, go through initialization and leave it low for reads and writes because I have no other SPI devices on the bus.

CMD1, Continued Initialization of the SD Card

That simple sequence is the first part. You then follow it up with an SD CMD1 command (0x01 | 0x40 as it looks on the line.) The same protocol transpires as you clock it in. In the screenshot below, I’ve show the CMD1 sequence on the tail of the CMD0 sequence:

MMC-SPI-Initialization-Sequence-CMD01-Response

Notice the 0x41 to lead off the 6 byte packet...that’s the CMD1 | 0x40 byte. Also, notice the response on the MISO line starting 8 cycles after the checksum (0x95) is sent, it’s 0x01. This is a “busy” indication from the SD card. Continuing sending CMD1 while you continue to get a busy response. When the response is finally not busy, the card is initialized in SPI mode and ready for the other types of SD SPI bus commands.

For the SD Cards I was using, I only had to send two CMD1 commands before the SD Card was ready. Here’s the final CMD1 command:

MMC-SPI-Initialization-Sequence-CMD01


For completeness, the sequence below shows a portion of the 80 clock cycles that are required to lead into the first CMD0 command.
SD-MMC-SPI-Initialization-Waveforms

Best SPI to SD/MMC Protocol Tutorial On the Web

I learned a lot about SPI and SD/MMC communication from this article on the web: http://elm-chan.org/docs/mmc/mmc_e.html

While there is some visualization of a SPI waveform in the elm-chan tutorial, the SPI SD waveforms in the screenshots above are pulled from an actual SPI SD communication session and I think can fill in some visual and conceptual gaps if you’re not too familiar with the sequences.

About This Configuration

To capture these waveforms, I used the LogicPort 34 Channel Logic Analyzer.

I used a ET-AVR Stamp connected to an ET-AVR Development board and MMC/SD mini-board for SD testing. I used Kodak 2GB SD Card, Lexar 128MB SD Card, and Lexar 2GB SD Card to watch variations in behavior. The LogicPort analyzer leads are on the left side. The ET-AVR dev board’s nice because you can run jumpers using, say, male to male connections and there’s another row of connectors for every pin on the AVR that can be used for logic tracing. It’s just a very convenient board to work on with the exception of needing to use a squid to attach the JTAGICE mkii if you also want to use SPI.

DSCF1553


ET-AVR-DevBoard-WithSDMMC

Summary

These images help show how to communicate to an SD card from a SPI-capable microcontroller such as the ATMega128. The most important phase of this is initializing the SD Card for SPI protocol operation as the above images demonstrate.

Reading and writing to the card after this much has been accomplished is a much easier task.
asdfasdf