Skip to main content
daviddavid94
Associate II
August 18, 2010
Question

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

  • August 18, 2010
  • 4 replies
  • 1040 views
Posted on August 18, 2010 at 05:07

ELM-FATFs / SDIO / DMA 'gotcha'

    This topic has been closed for replies.

    4 replies

    daviddavid94
    Associate II
    May 17, 2011
    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.
    Associate III
    May 17, 2011
    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.

    sascha239955_st
    Visitor II
    May 17, 2011
    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

    John F.
    Associate III
    May 17, 2011
    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.