Skip to main content
chuck guzis
Associate II
September 27, 2017
Question

STM32F4 memory areas for DMA. Different?

  • September 27, 2017
  • 3 replies
  • 1255 views
Posted on September 28, 2017 at 00:51

I'm probably missing something obvious, but I'd appreciate any clarification.

Basically, I'm using a peripheral device that transmits data in 16K word blocks using DMA.   That works fine.  I'm taking the data and writing it to an SD card, using the SPL and Chan's FATFS code.

Up until yesterday, things worked fine also, but I ran into errors because of FATFS occasionally using buffers that aren't aligned to a 32-bit boundary.  So I added code to check for a misaligned buffer and move data to an aligned one before writing to SD.   My code passes his compatibility checker (app4.c) test.

Confident in the outcome, I started running my regular code with the compatibility modification.   All of the sudden, some SD writes now hang up and timeout with a DMA failure.  If I perform single-sector writes using the buffer that I use for resolving misalignment issues, things are fine, albeit slower.  But if I attempt to write (aligned data) right from the device buffer, it will go for a bit and then hang.

My thought is that perhaps some areas of memory are less suited to DMA than others, but if that's true, I don't know how to resolve the issue.

    This topic has been closed for replies.

    3 replies

    Tesla DeLorean
    Guru
    September 28, 2017
    Posted on September 28, 2017 at 02:10

    CCM RAM won't work with DMA on the F4

    I built some code in diskio.c to decompose unaligned reads/writes into single-up read/write through an aligned scratch buffer. That did require an adequate stack.

    /*-----------------------------------------------------------------------*/

    /* Write Sector(s) */

    #if _READONLY == 0

    DRESULT disk_write (

    BYTE drv, /* Physical drive nmuber (0..) */

    const BYTE *buff, /* Data to be written */

    DWORD sector, /* Sector address (LBA) */

    BYTE count /* Number of sectors to write (1..255) */

    )

    {

    SD_Error Status;

    // printf('disk_write %d %p %10d %d\n',drv,buff,sector,count);

    if (SD_Detect() != SD_PRESENT)

    return(RES_NOTRDY);

    if ((DWORD)buff & 3) // DMA Alignment failure, do single up to aligned buffer

    {

    DRESULT res = RES_OK;

    DWORD scratch[BLOCK_SIZE / 4]; // Alignment assured, you'll need a sufficiently big stack

    while(count--)

    {

    memcpy(scratch, buff, BLOCK_SIZE);

    res = disk_write(drv, (void *)scratch, sector++, 1);

    if (res != RES_OK)

    break;

    buff += BLOCK_SIZE;

    }

    return(res);

    }

    Status = SD_WriteMultiBlocksFIXED(buff, sector, BLOCK_SIZE, count); // 4GB Compliant

    if (Status == SD_OK)

    {

    SDTransferState State;

    Status = SD_WaitWriteOperation(); // Check if the Transfer is finished

    while((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)

    if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK))

    return(RES_ERROR);

    else

    return(RES_OK);

    }

    else

    return(RES_ERROR);

    }

    #endif /* _READONLY */
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    chuck guzis
    Associate II
    September 28, 2017
    Posted on September 28, 2017 at 02:40

    That's what mine essentially looks like, mutatis mutandis.   I use a buffer shared between the read and write code as scratch.   However, I don't get your comment about needing more stack space.  It would seem to be unchanged from the 'let's assume that everything is aligned' case.  After all, the buffer address, count and sector address are already resident as part of the calling sequence.  There aren't any additional onstack variables--and the scratch buffer is statically allocated; i.e.

    uint8_t  __attribute__ ((aligned(4))) ScratchBuffer[ SECTOR_SIZE];

    I guess that I'm not following you.  It doesn't explain why, if I treat all writes as single-sector unaligned writes, everything works.

    chuck guzis
    Associate II
    September 30, 2017
    Posted on September 30, 2017 at 03:16

    Nevermind--I found the typo--a missing semicolon.

    Thanks for your help.

    Chuck