I am trying to read a block of data from a standard capacity micro SD card, but the received data does not make any sense. Here is what I'm doing:
- Initializing the card
- Reading data
- Setting CS low
- Sending CMD16 to set block length
- Sending CMD17 with start address
- Waiting for start byte (0xfe)
- Receiving bytes and printing them to the serial terminal
- Receiving CRC
- Setting CS high
- Sending 8 extra clocks (?)
The data I'm trying to read is the FAT16 boot sector, as shown below:
And the data I'm getting out is this:
At this point, I can't even begin to think of what is going wrong. I don't think it's a transmission error, because the data out is always the same. I can also read the boot sector signature 0x55 0xAA every time, even if I set the start address to 510 and read two bytes, they come back perfectly. The problem is that I can't read other bytes.
I also tried swapping cards and that didn't help either.
What am I missing?
EDIT: the function in question is below.
bit sd_read_block(unsigned long size, unsigned long start_addr)
{
unsigned long i;
unsigned char r;
SD_CS = 0;
r = sd_card_cmd(16, size, 0);
sprintf(usb_uart_tx_buffer, "CMD16 R Token: %02x.\r\n", r);
usb_uart_tx(usb_uart_tx_buffer);
r = sd_card_cmd(17, start_addr, 0);
sprintf(usb_uart_tx_buffer, "CMD17 R Token: %02x.\r\n", r);
usb_uart_tx(usb_uart_tx_buffer);
// wait for start token
r = 0;
while (spi_rx_byte() != 0xfe) {
if (r++ > 25) {
SD_CS = 1;
return r;
}
}
for (i = 0; i < size; i++) {
if (i % 20 == 0) {
UART1_TX(0x0d);
UART1_TX(0x0a);
}
sprintf(usb_uart_tx_buffer, "%02x ", spi_rx_byte());
usb_uart_tx(usb_uart_tx_buffer);
}
// CRC
spi_rx_byte();
spi_rx_byte();
// extra clocks
r = spi_rx_byte();
SD_CS = 1;
return 0;
}