After breathing a massive sign of relief once the SD card starting responding to SPI commands, we thought it’d be relatively straight forward to get data into and out of the card. We’ve already worked with NAND flash memory (in our case AT45DB041D eeprom chips), and stream-reading/writing data, so it shouldn’t be too difficult….

We’re still having problems getting a reasonable response from the SD card.
Everything points to the clocking edge being either incorrect or incorrectly configured, but it’s just not making sense! We got an ok response from the SD card after initialising it. So now we send command 18 and wait for an ok before streaming the data back from the card:

void testReadData(){
      // send command 18, param x10 (start multi-block read from address 0x10)
      // and wait for an ok response
      sendCommand(CMD_READ_MULTIPLE_BLOCKS, 0x10);
      // what follows should be data?

But here’s the weird thing – after we’ve successfully initialised the card, we get some sort of noisy signal back from the card after sending the second byte from the (redundant) CRC check.

So that we can see where our init routine ends, we send a single byte 0xC0 to the SD card once we think the init routine has successfully completed. This can be seen clearly in the screenshot below:

What is unusual is the noisy signal coming back from the card. The logic probe decodes it as 0xFF but there are definitely peaks and troughs occuring in the signal in between the clock cycles.

Here, we’re sending a command to the SD card, to initiate a multi-block read so we send a command byte 18, followed by the sector to begin reading from (we chose 0x10) and a CRC value of 0x95 (the CRC is not actually used when in SPI mode, but must be included as part of the data “packet”). In the screen grab above, we seem to be getting a noisy signal back from the SD card while sending the sector address to read from.

The send command function includes a check for an ok response before returning:

unsigned char sendCommand(unsigned char command, unsigned long param) {
      r=SPISendAndReceive(0xFF); // dummy byte
      r=SPISendAndReceive(command | 0x40);
      r=SPISendAndReceive(0x95); // correct CRC for first command in SPI
      // after that CRC is ignored, so no problem with
      // always sending 0x95
      r=SPISendAndReceive(0xFF); // ignore return byte
      return waitForNot(0xFF);

But we never seem to get a non 0xFF response back from the card…..