Seabright Technology Header Image

SD Card Protocol

There's a ton of information out there on using the MMC/SD SPI protocol to access SD cards but not much on the native protocol. This page hopes to rectify that with information helpful to those implementing a SD host or trying to understand what they're seeing on an oscilloscope.

References

Compatibility

MMC, SD, and SDHC cards are broadly compatible at the electrical and framing level. A properly designed controller should be able to handle them all. Some differences are:

  • MMC cards are available in both High Voltage (2.7 - 3.6 V) and Dual Voltage (2.7 - 3.6 and 1.70 - 1.95 V)
  • MMC is designed to support multiple cards on the same bus
  • During initialisation MMC cards are clocked at 400 kHz or less
  • MMC, SD, and SDHC all have different initialisation sequences

Protocol

The protocol is a strict master/slave arrangement where data is clocked synchronously from the host to the card or from the card to the host over digital lines. Commands are sent from the host to the card and all commands have either no response, a 48 bit response, or a 136 bit response. Some commands may also start a data transfer to or from the card.

There are three types of signal:

  • CLK, carrying the clock signal from the host
  • CMD, carrying commands from the host and responses from the card
  • DAT, carrying data from the host or data from the card

There may be 1, 4, or 8 DAT lines. SD Cards can run at 0 - 25 MHz in Default Mode or 0 to 50 MHz in High-Speed Mode. MMC cards come in different grades that can run at up to 20, 26, or 52 MHz. No matter what all cards start up in 3.3 V, single DAT, and low speed mode with any other features negotiated during the initialisation.

Physical layer

All communication are at 3.3 V logic levels with 3.3 V being a high and 0 V being a low. CLK comes from the host and idles low. CMD and DAT are bidirectional and idle high. All are driven in a push/pull mode for speed.

Data is clocked into the host or card on the rising edge of CLK and changes on the falling edge. This is equivalent to the SPI (0, 0) mode.

Framing

The framing is a bit unusual. It feels like it was written by a embedded software engineer instead of a hardware or protocol engineer as the framing and use of CRCs is unusual and inconsistent. The advantage is that the framing maps through to a software only implementation pretty well.

All transfers start with a zero start bit and finish with a one stop bit. A card may signal that it is still working on the response by keeping the CMD line high until the response is ready.

All commands are 48 bits (6 bytes) long and all responses are either 48 bits (6 bytes) or 136 bits (17 bytes) long. The 48 bit transfers can be thought of as an 8 bit message ID, 32 bit argument, and 8 bit checksum.

Bytes are transferred most significant bit first. Words are transferred most significant byte first.

Commands and Responses

A command or response has the following format:

Bit # Value Name
47 1 0 Start bit
46 1 1 for commands, 0 for responses Transmitter bit
45-40 6 Command ID
39-8 32 Argument
7-1 7 CRC
0 1 1 Stop bit

The CRC is a 7 bit CRC with polynomial x7 + x3 + 1. A table driven form can be found in the Linux kernel under  lib/crc7.c. Bitwise forms may be generated using  pycrc with the parameters

--width=7 --poly=9 --reflect-in=0 --reflect-out=0 --xor-out=0 --xor-in=0 --generate c --algorithm=bit-by-bit-fast

such as

for (int b = 0; b < 8; b++)
{
    uint bit = crc & 0x40;

    if ((data & 0x80UL) != 0)
    {
        bit ^= 0x40;
    }

    data <<= 1;
    crc <<= 1;

    if (bit != 0)
    {
        crc ^= 0x09;
    }
}

Note that the final CRC must be ANDed with 0x7F.

The CRC seed is zero and is calculated over the start, transmitter, command ID, and argument fields. The resulting CRC is compared for equality with the CRC from the message.

Some examples are:

An APP_CMD (55) command that prefixes a SD specific command

Bytes: 0x770000000065

Bits: 0 1 110111 00000000000000000000000000000000 0110010 1

Fields:

  • Start bit = 0
  • Transmitter = 1
  • Command = 55 (decimal)
  • Argument = 00000000
  • CRC = 0x32
  • Stop bit = 1

The CRC can be generated by feeding 0x77, 0x00, 0x00, 0x00, 0x00 into the CRC function above.

The response to the APP_CMD

Bytes: 0x370000012083

Bits: 0 0 110111 00000000000000000000000100100000 1000001 1

Fields:

  • Start bit = 0
  • Transmitter = 0 (this is a response)
  • Response = 55 (decimal)
  • Argument = 00000120
  • CRC = 0x41
  • Stop bit = 1

The response to CMD3 SEND_RELATIVE_ADDR

Bytes: 0x03B368050019

Bits: 0 0 000011 10110011011010000000010100000000 0001100 1

Fields:

  • Start bit = 0
  • Transmitter = 0 (this is a response)
  • Response = 3 (decimal)
  • Argument = 0xB3680500
  • CRC = 0x0C
  • Stop bit = 1

Note that this cards Relative Card Address (RCA) is 0xB368

Data

Data has the following format:

Bit # Value Name
4113 1 0 Start bit
4112-17 512*8 Data bits
16-1 16 CRC
0 1 1 Stop bit

Note that this is for a typical transfer of a block of 512 bytes. The host knows from the command that was sent how many bytes to expect back. There is no other way of knowing the message length.

The CRC is is the ITU-T V.41 16 bit CRC with polynomial 0x1021. A table driven version can be found in the Linux kernel under  lib/crc-itu-t.c. Note that there is no such thing as 'the' CRC16 so make sure you get the right one.

Unlike the commands or responses the CRC is calculated over all of the data bytes and does not include the start bit. The calculated CRC is checked for equality with the received CRC.

PENDING: Add an example data message with CRC.

Handover

The CMD and DAT lines are bidirectional. Handover occurs at the end of a command where both the host and the card switch to input mode for two clocks before the card starts driving in push/pull mode. Some commands must be responded to in a fixed number of clocks but most allow an arbitrary time before the response must start.

Initialisation

To initialise a SD or SDHC card, send the following:

  • Write 74 clocks with CMD and DAT high
  • Write CMD0 GO_IDLE_STATE. This will reset the card.
  • Write CMD8 SEND_IF_COND for 3.3 V parts. If any SDHC cards are

present then you will get a wired-OR response with 0x3F as the command and 0xFF as the CRC and stop bit. Note that this must be sent or SDHC cards will not respond to the following steps

  • Write CMD55 APP_CMD
  • Receive a 55 response
  • Write ACMD41 SD_SEND_OP_COND
  • Expect a wired-OR response with 0x3F as the command and 0xFF as the CRC and stop bit
  • Check the ready bit in the previous response. If the card is not

ready then repeat the CMD55/ACMD41 until it is

  • Write CMD2 ALL_SEND_CID
  • Expect a wired-OR response with 0x3F as the command and 0xFF as the CRC and stop bit
  • Write CMD3 SEND_RELATIVE_ADDR
  • Expect a 3 response. The upper two bytes of the argument is the

Relative Card Address (RCA) which is used in the next step

  • Write CMD7 SELECT_CARD with the RCA
  • Expect a 7 response

The card is now selected and ready to transfer data. See Figure 4-1 'SD Memory Card State Diagram' in the simplified spec for more information.

See section 4.7.4 'Detailed Command Description' in the simplified spec for more information on the commands and responses.

MMC cards are initialised using a similar but different method.

An example flow captured from Linux on a SC2440 is:

Phase Command Response Notes
CMD0 400000000095 None
CMD55 770000000065 370000012083
ACMD41 SEND_OP_COND 69001000005F 3F00FF8000FF Card is busy
CMD55 770000000065 370000012083
ACMD41 69001000005F 3F00FF8000FF Card is still busy
CMD55 770000000065 370000012083
ACMD41 SEND_OP_COND 69001000005F 3F80FF8000FF Card is ready
CMD2 ALL_SEND_CID 42000000004D 3F1D4144534420202010A0400BC10088ADFF
CMD3 SEND_RELATIVE_ADDR 43000100007F 03B368050019 RCA of 0xB368

Note the missing CMD8 as this controller does not support SDHC. I didn't capture the final CMD7.

Reading

Once initialised reading from a card is straight forward.

To read a single page:

  • Send CMD17 READ_SINGLE_BLOCK with the offset to read from as the argument
  • Receive on the DAT lines
  • Send CMD12 STOP_TRANSMISSION once the block has been received

To read consecutive pages:

  • Send CMD18 READ_MULTIPLE_BLOCK with the starting offset as the argument
  • Receive as many blocks as you want on the DAT lines
  • Send CMD12 STOP_TRANSMISSION once the done

Note that there will be a response to these commands and the response may be interleaved with the data. See Figure 3-3: (Multiple) Block Read Operation for more information.

On SDHC cards the offset is in terms of 512 byte blocks. On SD cards the offset is in bytes and the number of bytes received depends on CMD16 SET_BLOCKLEN

Exceptions for MMC

MMC cards are rare these days. Rather than clutter the write up above with the MMC exceptions they have all been gathered up into this exception.

The CMD line on a MMC card can operate in input, push/pull, or open collector modes. The open collector mode is used during initialisation as a wired-OR to allow multiple cards to talk on the bus at once. This is also why MMC initilisation mode is limited to 400 kHz.

Dual Voltage MMC cards are rare. They start at 3.3 V and may be negotiated down to 1.8 V.

One great thing about MMC is the Boot Operation Mode. This is a very simple protocol that allows the host to easily address and clock in the specially configured boot partition off the card. As far as I can tell this is only available on eMMC parts though which normally come in BGAs.