NodeLoop
MCU bring-up workflow

SD Card SPI Initialization Guide: CMD0, CMD8, ACMD41 Explained

A practical SPI-mode startup sequence for SD, SDHC, and SDXC card bring-up, with command frames, expected responses, and the failure patterns that usually waste the most time.

Guide Published Jul 22, 2025 Practical MCU bring-up workflow

Quick answer: minimal modern card flow

1. Power-up

Keep CS high, drive MOSI high, and send at least 74 clock pulses.

2. CMD0

Assert CS, send CMD0, expect R1 = 0x01.

3. CMD8

Send CMD8 with 0x1AA. Modern cards answer with an R7.

4. ACMD41 loop

Repeatedly send CMD55 then ACMD41 with HCS=1 until R1 = 0x00.

5. CMD58

Read OCR with CMD58, then decide whether later accesses use block or byte addressing.

For SDSC or very old cards, the flow changes after CMD8. This guide focuses on the modern SD memory card path first because it is what most MCU projects need today.

Command checklist

Command Purpose Typical argument / frame Expected response
CMD0 Reset card and request SPI mode 40 00 00 00 00 95 R1 = 0x01 means idle state entered
CMD8 Check voltage range and card generation 48 00 00 01 AA 87 R7 echo ending in 0x01AA for SDv2+
CMD55 Prefix next command as application-specific 77 00 00 00 00 01 R1 = 0x01 while still idle
ACMD41 Poll until internal initialization completes 69 40 00 00 00 01 0x01 busy, then 0x00 ready
CMD58 Read OCR and card capacity status 7A 00 00 00 00 01 R3; use CCS to distinguish SDSC from SDHC/SDXC
CMD16 Set block length for SDSC access 50 00 00 02 00 01 Use when you need 512-byte SDSC block transfers

Before CRC is explicitly enabled with CMD59, most SPI hosts send valid CRC for CMD0 and CMD8, then use a dummy CRC byte such as 0x01 on later commands.

Prerequisites and SPI bring-up rules

Most SD card SPI failures start before the first command. Get the electrical and timing basics right before blaming the command sequence.

  • Voltage: the card I/O is 3.3 V class. Use proper level shifting if the MCU is not 3.3 V compatible.
  • Clock during init: keep SCK in the 100 kHz to 400 kHz range until initialization is complete.
  • Default line states: keep CS high by default and drive MOSI high during the initial dummy clocks.
  • Pull-ups: keep CS from floating and avoid a noisy or floating MISO line during power-up.
  • Command pacing: after each command, keep clocking until a non-0xFF response appears or the timeout expires.
  • Timeouts: never loop forever on CMD0 or ACMD41. Timeouts make debugging sane.

The initialization sequence

The order matters. If the card does not reach the expected state, stop there and debug that transition before sending the next command.

Step 1: Power-up and dummy clocks

After power is stable, keep CS high and MOSI high, then send at least 74 clock pulses. In practice, most firmware sends 80 clocks by shifting ten bytes of 0xFF.

If you skip this, some cards never accept CMD0 cleanly because the internal power-up state machine is not ready yet.

Step 2: Enter SPI mode with CMD0

Pull CS low and send CMD0:

40 00 00 00 00 95

The expected response is R1 = 0x01, which means the card is now idle and has accepted SPI mode.

Step 3: Identify modern cards with CMD8

Send CMD8 with the standard 0x1AA argument:

48 00 00 01 AA 87
  • Modern SD memory card: expect an R7 response whose tail echoes 00 00 01 AA.
  • Illegal command: the card may be older SDSC or MMC, so the bring-up path changes.

For modern MCU work, this is the branch you usually want before moving to ACMD41.

Step 4: Loop on CMD55 + ACMD41 until ready

This is the core handshake. Send CMD55, then ACMD41 with HCS=1 if you support high-capacity cards. Repeat until the card returns R1 = 0x00.

  • 0x01 means the card is still busy initializing.
  • 0x00 means initialization is complete and the card left the idle state.
If this loop never exits idle, debug command framing, HCS handling, and clock rate before going any further.

Step 5: Read OCR with CMD58 and decide address mode

After the ACMD41 loop succeeds, send CMD58 to read the OCR register and inspect the CCS bit.

  • CCS = 1: SDHC or SDXC. Memory commands use block addressing and 512-byte blocks.
  • CCS = 0: SDSC. Memory commands use byte addressing; set 512-byte block length with CMD16 if needed.

One of the most common post-init bugs is using SDSC byte addresses on an SDHC or SDXC card, which makes reads and writes look wrong by a factor of 512.

Reference pseudo-code

power_on_card();
delay_ms(5);
cs_high();
send_ff_clocks(10);   // 80 clocks with MOSI high

for (retry = 0; retry < cmd0_timeout; retry++) {
  r1 = send_cmd(CMD0, 0x00000000, 0x95);
  if (r1 == 0x01) break;
}

r7 = send_cmd_long(CMD8, 0x000001AA, 0x87);
if (r7.r1 & 0x04) {
  // Older SDSC or MMC path, not the main modern flow
}

deadline = now_ms() + 1000;
do {
  send_cmd(CMD55, 0x00000000, 0x01);
  r1 = send_cmd(ACMD41, 0x40000000, 0x01);  // HCS = 1
} while (r1 == 0x01 && now_ms() < deadline);

ocr = send_cmd_long(CMD58, 0x00000000, 0x01);
if (ocr.ccs == 0) {
  send_cmd(CMD16, 512, 0x01);  // SDSC block length
  addressing = BYTE_ADDRESSING;
} else {
  addressing = BLOCK_ADDRESSING;
}

cs_high();
transfer_byte(0xFF);  // trailing clocks before next transaction

Common failure cases

No 0x01 after CMD0

  • CS was not high during the dummy clocks.
  • Initialization clock is too fast.
  • The command frame or CRC byte is wrong.
  • The card is not actually powered or level-shifted correctly.

CMD8 fails unexpectedly

  • The card may be older SDSC or MMC.
  • The host may not be clocking out enough bytes to read the full R7 response.
  • The line is sampled too early while the card still returns 0xFF.

ACMD41 never exits idle

  • CMD8 was skipped on a modern card.
  • HCS was left clear while talking to SDHC or SDXC media.
  • CMD55 and ACMD41 sequencing is wrong.
  • The SPI clock is still out of range for initialization.

Reads and writes hit the wrong block

  • SDSC: memory commands use byte addresses and usually need CMD16.
  • SDHC or SDXC: memory commands use block addresses with fixed 512-byte blocks.
  • If the offset looks wrong by 512x, check your CCS handling first.

FAQ

Why does SD card SPI mode require 74 clock cycles before CMD0?

The initial clocks give the card time to finish power-up and start sampling SPI commands. Keep CS high, keep MOSI high, and send at least 74 clocks before asserting CS for CMD0. Many firmwares send 80 clocks for margin.

What CRC bytes should I send for CMD0 and CMD8?

Send 0x95 for CMD0 with argument 0x00000000 and 0x87 for CMD8 with argument 0x000001AA. Later commands usually use a dummy CRC byte unless CMD59 enables CRC checking.

Why does ACMD41 never leave the idle state?

Common causes are missing CMD8 before ACMD41 on modern cards, HCS not set for SDHC or SDXC bring-up, SPI clock too fast during initialization, or chip-select and command framing errors.

Do CMD0 and CMD8 need valid CRC in SPI mode?

Yes. Hosts typically send valid CRC for CMD0 and CMD8 during startup. Later commands often use a dummy CRC byte while CRC checking stays disabled unless CMD59 explicitly enables it.

When do I need CMD16 after initialization?

SDSC cards use byte addressing and usually need CMD16 to select a 512-byte block length. SDHC and SDXC cards use fixed 512-byte blocks for memory access commands and do not need CMD16 for standard block reads and writes.

Why do reads look shifted by a factor of 512?

That usually means the host is using SDSC byte addressing rules on an SDHC or SDXC card, or the opposite. Check CMD58 CCS handling and make sure your later commands use the correct address format.

Closing notes

The SPI startup sequence is strict, but it is also very deterministic. If you validate each response before moving on, SD card bring-up becomes much easier to debug than it first appears. For final edge cases and card-behavior details, use the SD Association Physical Layer Simplified Specification as the primary reference.