This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM57L843: DMA not working properly after Cache is enabled

Part Number: RM57L843
Other Parts Discussed in Thread: HALCOGEN

Hello E2E team,

I have being reading a lot of forums related to the issue I am having when enabling the cache in an application that uses DMA.

I am using the GCC compiler/linker, FreeRTOS and Halcogen v04.07.00.

I am using a dedicated MPU memory region R8 for the CPU <> DMA access. This region is setup as follows:

This region overlaps with region 3, which covers the whole RAM memory, but the region 3 is not available for editing in Halcogen, so I am not able to change the Type and Permission of the region 3:

so I figure out I could try and edit the Halcogen config file ( *.dil ) changing the following parameters:

DRIVER.SYSTEM.VAR.CORE_MPU_REGION_3_TYPE.VALUE=NORMAL_OINC_SHARED
DRIVER.SYSTEM.VAR.CORE_MPU_REGION_3_TYPE_VALUE.VALUE=0x000C
DRIVER.SYSTEM.VAR.CORE_MPU_REGION_3_PERMISSION.VALUE=PRIV_RW_USER_RW_EXEC
DRIVER.SYSTEM.VAR.CORE_MPU_REGION_3_PERMISSION_VALUE.VALUE=0x0300

This way, when I load the Halcogen project, now I can see that the region is shareable (and non-cacheable):

But still, if I enable the Cache in Halcogen settings, the SPI DMA just sends data as zeros, meanwhile if a disable the Cache in Halcogen, I can see that the DMA performs correctly.

These are the snippets of the linker file that I use to place the "sharedRAM" section on top of the "RAM" section.

/* Entry Point */
ENTRY(_c_int00)

/* Highest address of the stack */
_estack = 0x8040000; /* end of 256K RAM */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x400; /* required amount of heap */

/* Shared RAM fully accessible and non-cacheable */
SHAREDRAM_SIZE = 0x1000;

/* Specify the memory areas */
MEMORY
{
    VECTORS(rx) : ORIGIN = 0x00000000, LENGTH = 0x00000020
    KERNEL (rx) : ORIGIN = 0x00000020, LENGTH = 0x00008000
    FLASH (rx) : ORIGIN = 0x00008020, LENGTH = (0x001F7FE0 + 0x00200000)
    CPU_STACK (rw) : ORIGIN = 0x08000000, LENGTH = 0x0000f000 /* Stack is configured in sys_core.asm */
    KRAM (xrw) : ORIGIN = 0x0800f000, LENGTH = 0x00000800
    RAM (xrw) : ORIGIN = (0x0800f000 + 0x00000800), LENGTH = (0x00071000 - 0x00000800 - SHAREDRAM_SIZE)
    MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
    SHAREDRAM(rw) : ORIGIN = 0x0807F000, LENGTH = SHAREDRAM_SIZE
}

/* DMA shared data located in RAM */
.sharedRAM :
{
    . = ALIGN(4);
    __sharedRAM_start__ = .; /* create a global symbol at sharedRAM start */
    *(.sharedRAM)
    . = ALIGN(4);
} > SHAREDRAM

 

I am missing any other step in order to correctly use the DMA with the Cache Enabled?

Thanks for your support,

Best Regards,

Jor Sas

 

  • Hello Jor,

    1. DMA will write the data directly to the SRAM, or read the data directly from SRAM. Enabling and disabling will not impact the DMA operation. If you enable the cache (the default is writeback), the CPU may not read/write the data from/to the SRAM immediately. In a write-through cache, every write to the cache causes a write to SRAM. In a write-back cache, writes are not immediately mirrored to the SRAM. The data at the DMA source address (SPI send) or DMA destination address (SPI receive) may not be updated.

    2. You can use DAP to read the SRAM (DMA resource address) to check if the data is updated

    In debug window, click Debuggable devices --> click "show all cores"

    Click "TI XDS... Debug Probe/Dap", then select "Connect the target"

    Open the window browser, check the value in your location

  • Dear QJ Wang,

    Thank you for attending my request.

    I agree with you in that enabling cache will not impact the DMA operation, but it is impacting data read from SRAM and data write to SRAM when I enable the cache.

    The following pictures show how the data in the SRAM is correct in both cases with cache enabled and cache disabled:

     

    Cache Disabled:

    • _cacheEnable_() is commented in the code (HL_sys_startup.c)
    • Data in SRAM (m_pOutputBuffer) to be transferred to the SPI TX register is correctly transferred in the SPI transmission (SPI - MOSI signal)

    Cache Enabled:

    • _cacheEnable_() is NOT commented in the code (HL_sys_startup.c)
    • Data in SRAM (m_pOutputBuffer) to be transferred to the SPI TX register is shown correctly in the SRAM location but is NOT correctly transferred in the SPI transmission (SPI - MOSI signal), most probably due to cache intervention (the only difference in the code).


     

    In both cases, MPU regions 3 and 8 are configured to be:

    NORMAL_OINC_SHARED (non-cachable and shared)

    PRIV_RW_USER_RW_EXEC

    as it is recommended in other posts to avoid any cache intervention:

    2100.HalCoGen_FreeRTOS_GCC_Regions_R3_R8_NonCachable_and_Shared.zip

    Do you think there is any more configuration step that I am probably missing?

    Thanks again for your support,

    Kind Regards,

    Jor Sas

  • Found the issue:

    The Halcogen config tool allows to setup a specific memory regions to some FreeRTOS tasks (the user is forced to have a minimum of one of these tasks). What it’s not obvious is what the code underneath these setttings does, which is to remove any MPU config previously setup in Halcogen by the user if ANY of those FreeRTOS tasks does not configure ANY specific region, which is a very ugly thing to do.

    Thanks for no help.

    Jor Sas