Background: I am using an nRF52832 Development Kit with this microSD card in this breakout board. The card is powered at 3 V (I've tested running off the dev kit regulator and an external power supply). I am using 22 ohm series resistors on the SCLK, SDO, SDI, CS lines and a 10k ohm pullup resistor on SDO.

I am using FatFs to mount the SD card and write to a file. I am able to initialize the card, but my call to f_open returns error code 13 (FR_NO_FILESYSTEM).

After some digging, I was able to determine that FR_NO_FILESYSTEM is being returned from a call to find_volume, which tries to find a FAT partition on the drive. I understand that this means reading sector 0 of the card and reading bytes 510 and 511. For a valid FAT volume, those bytes should be 0x55 0xAA. However, looking at the SPI transactions, my card seems to be returning 0x00 0x00.

I've tried formatting my SD card as FAT32 using the official SD Card Formatter, the Windows format tool, OS X's Disk Utility, Ubuntu gparted, and dd, but to be sure, I used Hex Workshop to read the boot sector of the SD card on my laptop and did see 0x55 0xAA at the appropriate position:

Hex Workshop screen capture

I'm using a Saleae Logic Pro to capture the SPI sequence. I am not sure the best way to share the whole capture, but here is a table showing all the decoded values: http://pastebin.com/gQh07QfE

You can see that the initialization works alright (it responds to CMD0, CMD8, etc), and towards the end returns 0xFE (which I understand indicates a valid data token?), but then 0x00 0x00 instead of 0x55 0xAA.

My ffconf.h is here: http://pastebin.com/1XRa7c94 -- My sdmm.c is slightly modified to use the Nordic SPI API (nrf_drv_spi_transfer) and delay function (nrf_delay_us). I am using a separate GPIO pin as my CS (nrf_gpio_pin_set and nrf_gpio_pin_clear).

Does anyone have any ideas about why this read isn't working?

  • 1
    \$\begingroup\$ Umm.. I vaguely recall some trouble with Windows tools putting "sector 0" somewhere other than the actual Sector 0, probably to "protect" the boot sector ... as determined by reading it using "dd" under Linux. That was on a CF card not SD, some years ago, so may no longer apply. (But I'd crosscheck using dd as a precaution) \$\endgroup\$
    – user16324
    Mar 4, 2016 at 19:11
  • \$\begingroup\$ SD cards need pull-ups on all pins (with the exception of one which has an internal pull-up). This is not optional and is mandated by the specification. This probably won't fix your problem but you should consider it anyway. \$\endgroup\$
    – David
    Mar 4, 2016 at 20:13
  • \$\begingroup\$ Can you get any non 0 data from any other address on the sd? \$\endgroup\$
    – crasic
    Mar 4, 2016 at 21:21
  • \$\begingroup\$ @crasic, not that I can tell! All of sector 0 reads as 0x00, and so does every other sector I've tried (although the card is blank otherwise). \$\endgroup\$
    – jpwr
    Mar 4, 2016 at 23:40

1 Answer 1


Turns out the answer had to do with the way I was implementing the SPI transactions using the Nordic SDK.

My rcvr_mmc function looked like this:

void rcvr_mmc (
    BYTE *buff, /* Pointer to read buffer */
    UINT bc     /* Number of bytes to receive */
    nrf_drv_spi_transfer(&spi, NULL, 0, buff, bc);

I assumed my rcvr_mmc was working since I was correctly parsing command responses. However, sector reads weren't working at all. I didn't even see a full 512*8 clock cycles.

Once I realized that was happened, I looked more closely at the Nordic SDK SPI driver and discovered this:


Since sector reads pass bc=512, this resulted in nothing really being read. My very inefficient hack for now to get this work is:

int i;
uint8_t small_buf[1];
for (i = 0; i < bc; i++) {
    nrf_drv_spi_transfer(&spi, NULL, 0, small_buf, 1);
    buff[i] = small_buf[0];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.