# SD card read sector problem

I am using FatFS. After solving card initialization problem I am trying to read sector 0, but the card returns junk data.

This is my read operation: I see that the card replied with 0x00 which means that it is read to deliver data.

Of course my zeroth sector dumped with a USB card reader looks correctly:

This is my debug log (CMD numbers are in hex):

    388:mmc_disk_initialize: SPI initialized
366:send_cmd_INTERNAL: call 401 Cmd 00 response 01
403:mmc_disk_initialize: CMD0 okay
366:send_cmd_INTERNAL: call 405 Cmd 08 response 01
406:mmc_disk_initialize: CMD8 okay - this is an SDv2 card
409:mmc_disk_initialize: CMD8 response 000001AA
413:mmc_disk_initialize: Waiting for leaving idle state
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 01
366:send_cmd_INTERNAL: call 309 Cmd 37 response 01
366:send_cmd_INTERNAL: call 415 Cmd 29 response 00
419:mmc_disk_initialize: Checking CCS bit in OCR
366:send_cmd_INTERNAL: call 420 Cmd 3A response 00
423:mmc_disk_initialize: CMD58 response 80FF8000
452:mmc_disk_initialize: Init okay
40:disk_initialize: status = 0
58:disk_read_INTERNAL: Call from 27
366:send_cmd_INTERNAL: call 494 Cmd 11 response 00
60:disk_read_INTERNAL: buf=20001588 sector=0 count=1
27:test_task1: Read result 0
28:test_task1: dump len 512
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FE000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0000000000000000001B3DAFBF000080
0101008311F4FD3E000000C2EF3A0000
00000000000000000000000000000000
00000000000000000000000000000000

• My debug data is 100% consistent with logic analyzer traffic.
• Initialization is the same as in FatFS reference driver, only SPI layer is changed, so I would expect the initialization to fail if something was wrong with SPI itself
• SPI clock is around 150kHz
• Card returns the same junk every time, another card returns another junk reliably
• I am sending 2 dummy bytes with CS high between commands

What should I check/change to make read command work reliably?

• As @TurboJ indicates below, the 0x00 response to your read command only indicates the acceptance of the command. After that, you need to keep reading/skipping 0xff's until you see the data start token 0xFE; the requested block's data folllows that token. However, you still seem to be dumping the wrong block in the first place. – JimmyB May 9 '17 at 7:36

## 3 Answers

What you read om the µC is the MBR (Master Boot Record) with the partition table. This data you cannot read on a OS like windows without admin privileges! The USB card reader data clearly shows the first sector of the "drive" (partiton)- which is not sector 0 (zero).

Some hex editors can show your the MBR if started as an admin - but you must use the correct physical device, which has no drive letter.

• I've dumped it with dd if=/dev/sdb of=my_file bs=512 count=1 so I think I did dump sector 0. I've checked how FatFS detects the correct filesystem and it looks at the magic at byte 510 (BS_55AA in ff.c). Even without the FatFS in sight, when I read sector 0 I think I should get the same data on my MCU that I get from a USB card reader. – filo May 9 '17 at 5:47
• Are you 100% sure? A FAT12 file system cannot be larger than 32 MByte, but your SD is a 2.0 which should be in the GB range. – Turbo J May 9 '17 at 5:57
• I've dumped with the exact command as in above comment. The card is 32GB. I made now a dummy filesystem with mkfs.vfat on a file (without partition table) and even though is has the string FAT32 it still has 0x55AA magic at offset 510 (decimal). I think it is still not the problem of the filesystem, but of the underlying block access of the SD card. – filo May 9 '17 at 6:05
• Have you checked - with fdisk for example - that you are using the correct device name? – Turbo J May 9 '17 at 6:15
• Note that you seem to be missing a few bytes on the µC, as the sector 0 starts with the 0x00 byte after the 0xFE token. – Turbo J May 9 '17 at 6:16

Let's look at the dumps:

• your SD-card hex dump shows correct command execution. Data start with data token (FE), and, as TurboJ said, it seems to be partition table, however there're some artifacts in there (1B3DAFBF0000). MBR's first volume information:

80 01 01 00 83 11 F4 FD 3E 00 00 00 C2 EF 3A 00

Active partition, type 83 (Native Linux partition), volume first LBA is 0000003E and size 003AEFC2 (1,977,582,592 ~ 2 GB partition).

• your first hex dump really shows FAT12 file system's boot sector, which is another piece of the file system. Its OEM ID shows MSWIN4.1 (formatted on Windows 95/98/ME); media descriptor is 0xF8 (hard disk); sectors per cluster is 0x40 (64); number of sectors 0x5545 (11,176,448 bytes in volume). It is not a diskette, not a hard disk. Most probably was formatted with some application which makes images for older devices supporting FAT12 and spoofs OEM ID so that device is readable on Windows/Linux/mobiles.

Conclusion: it's hard to make conclusion. Read whole SD-card on your Windows/Linux host (for example using Image Writer) and look into it using hex/binary viewer. Card's structure may be created by some special tool, thus its contents may be unpredictable. But what I can certainly say that boot sector you provided in first dump, under normal circumstances, should not correspond to the volume of device having MBR in second dump.

The problem was that I was starting to treat data coming directly after 0x00 from the card as sector payload. I fixed that by waiting first for 0x00 after sending the command, then waiting for 0xFE (which is the start of data byte). Now I can read the file system and list files.