Skip to main content

SD Storage Cards

State of the part

This part is still in concept phase.
Participators: Ferdinand, Johannes K., Julian D., Mona

Our SPI interface allows for interaction with IO devices that support SPI, for example SD cards.

During SPI interaction we disable interrupts as to reduce the risk of the SD card timing out during data transfer.

Commands

Our implementation realizes a subset of all possible SPI commands, namely the commands required for setting up SPI communication (namely CMD0 and CMD8) and commands needed to read from and write onto an SDHC SD card (CMD17 and CMD24 respectively).

CommandNameDescription
CMD0GO_IDLE_STATEReset or initialize SD card
CMD8SEND_IF_CONDRequests the supported voltage (not all cards support this)
CMD17READ_SINGLE_BLOCKReads a 512 byte block. If SDSC card is used, a custom block length can be set by a BLOCK_LEN command.
CMD24WRITE_BLOCKWrites a 512 byte block. If SDSC card is used, a custom block length can be set by a BLOCK_LEN command.

Custom block lengths have been deprecated in SDHC and above.

Interaction

Initialization:

Before we can interact with our device we need to place the SD card into SPI mode. Afterwards we run CMD0, followed by CMD8. In case of a non-expected response to each of these commands, they are repeated until the expected response has been received.

  1. Set MOSI and CS to high and toggle SD_CLK for 74 or more clock cycles. Then set CS to low.
  2. Run CMD0 with argument 0x0 and CRC 0x95. Expected response: 0x01
  3. Run CMD8 with argument 0x000001AA and CRC 0x87. Expected response: 0x01, and a subsequent echo of the argument.
  4. Check voltage and check pattern.

NOTE: 0x1AA seems to be a common value, others also possible, we need to investigate best practices.

Reads:

  1. Run CMD17 with argument DATA_ADDRESS. Expected response: 0x00. We then receive data block start byte 0xFE followed by the actual data.

Writes:

  1. Run CMD24 with argument DATA_ADDRESS. Expected response: 0x00. We then send the data block start byte 0xFE followed by the actual 512 bytes of data. We then receive data send end byte 0x05.
  2. Wait for end of BUSY state.

DATA_ADDRESS:

DATA_ADDRESS describes the index of the requested 512-byte block inside the SD card (starting from zero).

Alternative Addressing

Since the SDHC standard was introduced the default block size for the SD-Card is locked at 512 bytes and the SET_BLOCKLEN command has been deprecated. Since 512 bytes is likely too large for our design we propose an alternative block addressing:
In this scheme, we utilize the READ_MULTIPLE_BLOCK and the WRITE_MULTIPLE_BLOCK commands together with the STOP_TRANSMISSION command. These commands were designed to allow users to read/write multiple blocks in succession, but should also allow us to break off the transmission after some fraction of the block (i.e. 64/128Bytes) has been read/written. If we break of consistently we should be able to create smaller virtual blocks, sacrificing some capacity in the process. To choose between these addressing modes, consultation with the file system group is needed.

Schematics

We settled for a prepared board, because connecting the SD card to the breadboard is otherwise impossible.

Findings

  • The SD cards often do not adhere to the standard. Some cards do, others don't.
  • Getting the timings right is hard, we might use the Arduino-Interface for moving data in and out.