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.
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.
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.
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 0x40, 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 0x01 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 0x00 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 0x55 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. 0x00 0x01 0x14 0x00 0x04 0x03 0x60 0xDA 0x33 0x00 0x00 0x00 0x4D 0xED 0x00 0x00. Which is a non bootable, DOS 3.0+ 16-bit FAT file system, starting at sector 0x33 (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 0x200) 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 0x200 (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:
- SD Card Assoc. -Â Simplified Version of Physical Layer Specification
- Wikipedia – Master Boot Records
- Microsoft – FAT32 File System Specification
#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 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