Using the BusPirate with a SD card


As part of my GPS Logger project I needed to make sure that I could initialise and talk to a SD card over a SPI bus. The BusPirate is an excellent tool for testing  the physical and datalink layers. All parameters can be checked and adjusted on the fly without having to write any code. When the time comes to write code for the GPS logger, it will work first time as all the kinks and quirks were quickly worked out with the BusPirate.

This post covers SPI bus setup, card initialisation, reading and writing individual sectors.

BusPirate and a SD card, together at last

Getting it connected

Before anything can work, the SD card needs to be connected to the BusPirate. A specific connector could be used, however its easier and cheaper to hack it. A SD card fits neatly in a standard 0.1″ header and with a bit of paper to provide some extra pressure it works like a charm.

Impromptu SD Card socket

I have removed the second row of pins from the header to make it easier to fit in the breadboard. The BusPirate is connected directly to the card and Vpu needs to be connected to 3.3v for the pull up resistors.

SD Card pinout

The numbers indicate the SD card pin number. Pins 8 & 9 are used as additional data lines for faster transers and are not used in SPI mode.

BusPirate Setup

The BusPirate is set up to use SPI mode, with open drain and pullups on. This particular SPI bus needs an idle low clock, with data being output on the idle to active transition and data getting sampled at the end of the bit cycle.

Bus Pirate v3
Firmware v3.0
DEVID:0x0447 REVID:0x3043 (B5)
http://dangerousprototypes.com
HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. JTAG
7. RAW2WIRE
8. RAW3WIRE
9. PC KEYBOARD
10. LCD
(1) >5
Mode selected
Set speed:
 1. 30KHz
 2. 125KHz
 3. 250KHz
 4. 1MHz
(1) >1
Clock polarity:
 1. Idle low *default
 2. Idle high
(1) >1
Output clock edge:
 1. Idle to active
 2. Active to idle *default
(2) >1
Input sample phase:
 1. Middle *default
 2. End
(1) >1
Select output type:
 1. Open drain (H=Hi-Z, L=GND)
 2. Normal (H=3.3V, L=GND)
(1) >1
READY
SPI>p
 1. Pull-ups off
 2. Pull-ups on
(1) >2
Pull-up resistors ON
SPI>W
POWER SUPPLIES ON
SPI>

Card Initialisation

SD Cards start out in SD mode and needs to be put into SPI mode. This is accomplished through sending the card a reset command (CMD0) with CS held low. The card also needs 80 clock cycles for initialisation before being sent any commands.

SPI>]r:10[0x40 0x00 0x00 0x00 0x00 0x95 r:8]
CS DISABLED
READ 0x0A BYTES:
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
WRITE: 0x40
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x95
READ 0x08 BYTES:
0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS DISABLED
SPI>

All SD commands are 6 bytes long, beginning with the command number ORd with 0×40, a 32-bit argument (big endian) and then a checksum.  In this case the argument (parameters) for the reset command are 0 and the checksum needs to be valid. Once in SPI mode the checksum is disabled and arbitrary data can be sent in its place. 8 bytes are read back after the command is sent to get the response byte. Returned data of 0xFF indicates that the bus is idle or the card is processing and will give a response shortly.

 The card is now is in SPI mode and in the IDLE state, shown by the 0×01 response and needs to be moved into the operating state through CMD1 (SEND_OPERATING_STATE). This command is repeated until the card comes out of the IDLE state.

SPI>[0x41 0x00 0x00 0x00 0x00 0xFF r:8]
CS ENABLED
WRITE: 0x41
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS DISABLED
SPI>[0x41 0x00 0x00 0x00 0x00 0xFF r:8]
CS ENABLED
WRITE: 0x41
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS DISABLED
SPI>

Before transferring any data, the block transfer size needs to be set through SET_BLOCKLEN (CMD16). We will read and write a block of 512 bytes at a time, the standard sector size.

SPI>[0x50 0x00 0x00 0x02 0x00 0xFF r:8]
CS ENABLED
WRITE: 0x50
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS DISABLED
SPI>

Reading a sector

 A sector is read with the READ_SINGLE_BLOCK (CMD17) command, supplied with the address of the sector as the argument. The SD card that I am using in this example is already partitioned and formatted, so dumping the first sector (offset 0) will guarantee that data is present and allow for verification.

SPI>[0x51 0x00 0x00 0x00 0x00 0xFF r:520]
CS ENABLED
WRITE: 0x51
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0xFF 0x00 0xFF 0xFF 0xFE 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x01 0x14 0x00 0x04 0x03 0x60 0xDA 0x33 0x00 0x00 0x00
0x4D 0xED 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x55 0xAA 0xC2 0xC3
CS DISABLED
SPI>

The response of the card is different to the previous commands. Firstly a response of 0×00 was received, indicating a successful command. After a bus idle time 0xFE was received, this is the Start block token and 512 bytes of sector data follow it. Finally the data ends with 0xC2 0xC3, a CRC-16 based checksum of the send data.

Verifying the data we see 0×55 0xAA as the last two bytes of the sector, which isthe signature for Master Boot Records. The information at offset 0x1BE gives the entry for the first and only partition. 0×00 0×01 0×14 0×00 0×04 0×03 0×60 0xDA 0×33 0×00 0×00 0×00 0x4D 0xED 0×00 0×00. Which is a non bootable, DOS 3.0+ 16-bit FAT file system, starting at sector 0×33 (51) and continuing for 0xED4D (60749) sectors, or 31103488 bytes.

Writing a sector

So we can read, but can we write? Writing uses a similar structure to reading but before we write data we need a location to write it to. Going back to our partition table, the filesystem doesn’t start until sector 51 which leaves sectors 0 – 50 free and which should be empty. Lets check.

SPI>[0x51 0x00 0x00 0x02 0x00 0xFF r:520]
CS ENABLED
WRITE: 0x51
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0xFF 0x00 0xFF 0xFF 0xFE 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
CS DISABLED
SPI>

Yup sector 1 (offset 0×200) if empty and filled with zeros. Writing is performed in two steps, first a write command  of WRITE_SINGLE_BLOCK (CMD24) is sent specifying the location that we want to write to.

SPI>[0x58 0x00 0x00 0x02 0x00 0xFF r:8
CS ENABLED
WRITE: 0x58
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
SPI>

The card is happy with us writing to offset 0×200 (sector 1). Next a Start Block token is sent, then the data, then a checksum. We don’t need to worry about the checksum values as checksumming has been disabled.

SPI>0xFE 0xFF:128 0xFF:128 0xFF:128 0xFF:128 0x00 0x00 r:100
WRITE: 0xFE
WRITE: 0xFF , 0x80 TIMES
WRITE: 0xFF , 0x80 TIMES
WRITE: 0xFF , 0x80 TIMES
WRITE: 0xFF , 0x80 TIMES
WRITE: 0x00
WRITE: 0x00
READ 0x64 BYTES:
0xE5 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF
SPI>

The card indicated that the write was a success (0xE5) then it went into busy mode, effectively tying the data out pin low. The card cannot be sent another command until the bus is idle again (0xFF). Here we filled the sector with 0xFF, now lets check that it worked.

SPI>[0x51 0x00 0x00 0x02 0x00 0xFF r:520]
CS ENABLED
WRITE: 0x51
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ 0x08 BYTES:
0xFF 0xFF 0x00 0xFF 0xFF 0xFE 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x7F 0xA1
CS DISABLED
SPI>

Looks like the data made it onto the card.

Notes and further information

According to the SD card specification, we are not observing the correct way to initialise a card and some cards (1.4mm thick) will fail to initialise, however the presented method should also be good for using MMC cards. The standard states that memory corruption could occur due to differing fields in some registers. We could also gather more information from the card, including its storage size before using it.

If you intend to utilise SD cards, the following references may be handy:

,

  1. #1 by JonathanD on April 18, 2010 - 5:46 pm

    I had this SD card reader laying around that I never managed to get working. Then I tried your setup with the BusPirate and it worked like a charm !!

    Thanks a lot for this nice tutorial. Keep up the good work!

  2. #2 by enorthemous on August 31, 2010 - 2:48 am

    This is great, I was looking all over for someone who was making use of their old FDC connector. I know that you mainly used the FDC connector to SD in a project, but just wondering, did you happen to try reading an sd from the FDC on a pc motherboard? If this was possible I assume that one could use it as a boot device, perhaps for EFI, like a bootleg EFI-X without having to pay 200$ or use boot 132… or maybe just a way to read SD.

    anyhow, great work! everyone connects CF to IDE and such but far fewer people are doing anything with their FDC connectors

(will not be published)