2017-09-15 02:53 PM
I have been struggling for a week now trying to get FatFS working over the SDIO under FreeRTOS. I was making some progress debugging through the HAL but I have come to a difficult part to debug.
While debugging through f_open(), stepping into find_volume() and I get to the check_fs(). It pulls up the MBR correctly and the partition table sends it to sector 8192. The following steps pull the sector pointed to by the MBR in each of the four partition tables. When check_fs() reads sector 8192 everything is correct EXCEPT the first word, which is set to 0x00000000. find_volume() uses this first word to determine if the sector is a valid FAT partition, and zero is not valid, so I get an invalid file system error.
I put breakpoints on the SDIO and DMA interrupts so that it breaks before any of the interrupt code is executed and the first word of sector 8192 is still 0x00000000. It looks like the DMA_Read is not pulling the first word of the sector. When I put the SDIO card into my PC and use a disk sector editor the first bytes of the sector are non-zero and valid values.
I tried running with the DMA FIFOs off and got all zeros for the entire MBR sector.
Any suggestions? (Go back to 1.7?)
2017-09-15 03:59 PM
I would recommend debugging from the DISKIO.C layer, instrumenting the code rather than break-pointing.
2017-09-16 11:57 AM
Here is what I have so far using Clive One's suggestion.
I have used a logic analyzer to look at the SD bus during the read cycles. The first 10 values on the SD bus are
EB 58 90 4D 53 44 4F 53 35 2E 30 | . . . MSDOS5.0
Which is a correctly formatted FAT32 Partition header. This is what find-volume is looking for to indicate that the partition is valid.
I used memcpy at various places to copy the values from the fs->win buffer, plus the word before (fs->winsect) and I get the following data. The data shown are the results after the function listed. (Some function names are abbreviated to fit the display.) Execution order is roughly bottom to top.
fs->win - 4 = 0x200211D8
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
Pre_SD_TX_DMA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Post_SD_TX_DMA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Pre_SD_RX_DMA FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
Post_SD_RX_DMA FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
Pre_SD_IRQ FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
Post_SD_IRQ FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
BSP_SD_ReadDMA FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
SD_Read FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
disk_read FF FF FF FF 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
move_window 00 20 00 00 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
check_fs 00 20 00 00 00 00 00 00 53 44 4F 53 35 2E 30 00 02 40 5E 04 02 00 00 00
After BSP_SD_ReadBlocks_DMA the interrupts before the data are collected and before the SD_Read function returns. The Pre_ and Post_ for each of the IRQs is taken before and after the HAL functions are called in the IRQ.
We can see that at the beginning of any of the interrupts, the bytes in locations 04-07 are already zero, when they should be EB 58 90 4D everything beyond that are correct.
Rearranging the IRQ priority among the SD_IRQ and the DMA_IRQs produces the same result.