SD v2 initialization

Here the data between the LPC17xx and the SD card are shown for one of my SD cards.
The card is a Kinstron 2 GB Micro-SD card.

Each step contains a screen dump of my logic analyzer. The top lines show the data from the SD card, the bottom lines the data to to SD card (i.e. the commands being sent from the LPC17xx).

I will not explain all the details of the SD card protocol, the overview given is just there to give you a quick start in debugging a non-working SD-card interface.
if you like to have more insight in the exact meaning of the data, please search google for "SD physical layer spec". This will result in pointers to document from SanDisk and Toshiba describing the SD card protocol in a bit more detail.

Init - before sending any commands

Before sending any commands, we must make sure the SD card is ready.
The SD_Init() function therefor starts with sending 11 x 8 clock pulses to the SD card with SSEL high.
After this the card will be ready to accept data

CMD 0: GO_IDLE_STATE

The first command is a CMD0 (GO_IDLE_STATE). This command will trigger the SD card to use the SPI interface.
The following code in SD_Init() is responsible for this:

if (SD_SendCommand (GO_IDLE_STATE, 0, NULL, 0) != R1_IN_IDLE_STATE) // CMD0
{
     goto  init_end;
}

 

Each command contains starts with a start bit (0) and a transmission bit (1) after which the 6 command bits follow. So a CMD0 is seen on the SPI interface as 40h. After this there are 4 bytes with parameter data and a CRC checksum.
The only commands that must have a valid CRC are GO_IDLE_STATE and SEND_IF_COND. For all other commands the CRC is optional: the SD card can be programmed to skip CRC checking allowing simple microcontrollers to skip the CRC generation). The software used does not generate or check the CRC values.

After sending the command, SD_SendCommand() waits for the R1 response. This is the first byte that follows which has bit 7set low. Bits 6~0 contain possible error codes with bit 0 indicating that the SD card is in idle tate.

If the SD card reports anything else than IN_IDLE_STATE, initialization is stopped - the card is not ready to accept other commands and is defective (or at least not compatible).

CMD 8: SEND_IF_COND

r1 = SD_SendCommand (SEND_IF_COND, 0x1AA, buf, 4);  // CMD8
if (r1 & 0x80) goto init_end;

The SEND_IF_COND command is needed to tell the SD card which voltages it must accept.
The 4 byte parameter contains bits for each voltage being supported.

After sending the command and receiving the R1 response (same as above), there are 4 bytes of data showing which voltages (as requested) the SD card supports.

ACMD 41: SEND_OP_COND

Commands that start with 'A' mean that the command is an application specific command. The command being send is preceded by a CMD 55: APP_CMD.

When the command is accepted, the SD card will leave the IDLE_STATE. The code in SD_Init() repeats sending the ACMD41 until the SD card reports it has left the IDLE_STATE. A time out in this loop guards the system from reaching a blocking state.

do {
    r1 = SD_SendACommand (SD_SEND_OP_COND, 0x40000000, NULL, 0);  // ACMD41
    if      (r1 == 0x00) break;
    else if (r1 > 0x01)  goto init_end;            
} while (Timer1);

 

With my card, the second time the ACMD41 is sent, the card is ready and has left the IDLE_STATE

CMD 58: READ_OCR

The READ_OCR reads the OCR register in order to determine if this is a high capacity (SDHC) card or a standard v2 SD card. This card reports as a standard capacity card (bit 6 of the first response parameter is 0).

CMD 16: SET_BLOCKLEN

For SDHC the block length is always fixed to 512 bytes but for other types (MMC, SD v1 and SD v2 standard capacity) we need to tell the card what block length to use. Block length is set to 512 bytes to allow the software to be used with all types of SD/MMC cards.

Note that this command is not sent with the card is a SDHC card, for those cards the block length is always 512 bytes.

After this, SSEL is set high and the SD clock is increased such that further communication with the card uses the high clock frequency.

SD_ReadConfiguration()

After SD_Init() the software continues with the SD_ReadConfiguration() function. The bus speed is now at high speed (up to 25 MHz max.).

I am not going to show all logic analyzer views for all commands, I'll stick to showing the commands and responses in hex values. Please note that the content of the responses may vary depending on your SD card.

CMD 58: READ_OCR

To make SD_ReadConfiguration independent of any other functions, the OCR is read again.

FFh FFh FFh FFh FFh FFh FFh FFh FFh 00h 80h FFh 80h 00h
FFh FFh 7Ah 00h 00h 00h 00h 01h FFh FFh FFh FFh FFh FFh

CMD 10: SEND_CID

The CID (Card Identification) register is 16 bytes long and contains information lke manufacturer ID, Product name/revision/serial etc.
After sending the command and getting the R1 response, a block of 16 data bytes is returned by the card. First, the card sends a FEh byte to indicate the start of the data block, then 16 bytes of data follow with a 2 byte CRC.

FFh FFh FFh FFh FFh FFh FFh FFh FFh 00h FFh FEh 02h 54h 4Dh 53h 41h 30h 32h 47h 03h 9Ch B4h 66h C8h 00h 95h C1h F1h 44h
FFh FFh 4Ah 00h 00h 00h 00h 01h FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh

CMD 9: SEND_CSD

The CSD (Card Specific Data) register is 16 bytes long and contains data about the card's parameters.
The data block is received in a similar way as with the SEND_CID command.

FFh FFh FFh FFh FFh FFh FFh FFh FFh 00h FFh FEh 00h 4Fh 00h 32h 5Bh 5Ah A3h ACh FFh FFh FFh 8Fh 0Ah 80h 00h 45h 8Bh A3h
FFh FFh 49h 00h 00h 00h 00h 01h FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh FFh

CMD 13: SEND_STATUS

The status command is only send for SD v2 cards, apparently there is some special data block that follows the status with extra information needed.

FFh FFh FFh FFh FFh FFh FFh FFh FFh 00h FFh FFh FFh FFh FFh FFh FFh FFh FFh 00h 00h FFh FFh ...
FFh FFh 77h 00h 00h 00h 00h 01h FFh FFh FFh FFh 4Dh 00h 00h 00h 00h 01h FFh FFh FFh FFh FFh ...