cancel
Showing results for 
Search instead for 
Did you mean: 

ELM-FATFs / SDIO / DMA ''gotcha''

daviddavid94
Associate II
Posted on August 18, 2010 at 05:07

ELM-FATFs / SDIO / DMA 'gotcha'

4 REPLIES 4
John F.
Senior
Posted on May 17, 2011 at 14:02

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.

daviddavid94
Associate II
Posted on May 17, 2011 at 14:02

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.

John F.
Senior
Posted on May 17, 2011 at 14:02

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.

sascha239955_st
Associate
Posted on May 17, 2011 at 14:02

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