2010-08-17 08:07 PM
ELM-FATFs / SDIO / DMA 'gotcha'
2011-05-17 05:02 AM
Brian,
How did you fix this? I'm not sure I understood. Is the problem in SD_ReadBlock()? Please can you post more information and / or your fix? thanks.2011-05-17 05:02 AM
Where the problem is depends on what code you're using, of course. I'm using FWLib version 2.0.3, which is not the latest. I haven't looked at FWLib V3 in detail yet but I believe the SDIO stuff it is pretty similar. Most of the ELM/SDIO interface code I've seen is lifted more-or-less verbatim from the FWLib SDIO example code.
To use ELM, you must implement a disk_read() function, which has a ''BYTE *'' parameter for the destination buffer. This is the parameter which can be misaligned. If you blindly pass that parameter on to SD_ReadBlock(), and you're using DMA, then that pointer is probably being cast to a ''u32 *'' pointer. In my implementation, that pointer got passed to ''DMA_Configuration()''; but that function expects an aligned address (in my code). My work-around was to inspect the pointer, and only if it is mis-aligned, then use a local, aligned buffer for ''SD_ReadBlock()'' instead. After the read completes, I copy the data from that local buffer to the caller's desired location before returning (taking a performance hit). A bit more jiggery-pokery is required to make the SD_ReadMultiBlocks() do the right thing; and similar work must be done on the Write functions. I'm in the process of testing my changes. The ELM code calls ''disk_read()'' to read FAT entries as well as user file data directly from the SD card. For short, small ''f_read()'' calls, the corresponding ''disk_read()'' calls are almost always directed to the ELM's internal buffer, so no problem occurs. In this case, ELM extracts the partial-sector data that you asked for from its internal buffer, before returning from the ''f_read()'' call. However, if (say) you are doing an ''f_read()'' call of a very large block of data, then that translates to reading of many sectors. When ALL of the sector-data in a ''disk_read()'' call is destined to be passed to the user (i.e. at least 512 bytes, and not FAT data), then ELM may bypass its internal buffer, and ask ''disk_read()'' to put the data directly into your buffer, as specified in your ''f_read()'' call. Hope that helps.2011-05-17 05:02 AM
Thanks Brian - I understand better.
I'm using ELM-FAT with 4 bit wide SDIO and DMA but only writing and always writing in 512 byte units. I have noticed when writing 4608 bytes of data twice a second that sometimes the write seems to take noticeably (tens or hundreds of ms) longer. I assume it's internal operations inside the card. Have you noticed such behaviour? I would estimate I get an average write speed of about 128kB / s into a 1GB Transcend micro SD. I don't have data for any other cards.2011-05-17 05:02 AM
Dear Brian,
I am currently fighting with ELM-FAT and SDIO of STM32. It would be great if you could send me your ELM-FAT/ SDIO related code because I am having issues merging ELM and SDIO. Thanks Sascha