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 Data Transfer Problem

Part Number: RM57L843

Hello!

Basically, after power-on, I am carrying out PBIST tests on "L2 RAM", "PBIST ROM", "STC1 ROM", "STC2 ROM", "VIM RAM", "MibSPI RAM", "DCAN RAM" and finally "DMA RAM" which are all getting succeeded.

Post these tests, I am performing tests like SCI loopback, SPI loopback on all the SCI/SPI modules present on RM57 microcontroller. Finally, I am performing the DMA test which is basically as follows:

"Declare two arrays of size 100 (local variables), one loaded with data from 1 to 100 and the other being empty and initialized with zeros. Aim is to perform DMA transfer from the loaded array to the other array which is empty. Therefore, I use channel 5 (just random), set the control packet with following parameters:

Source Address = Address of array loaded with 1 to 100 elements

Destination Address = Address of Empty Array

Channel Control = 0

Frame Count = 1

Element Count = 100

Element Offset = 0 (both source and destination)

Frame Offset = 0 (both source and destination)

Port Assigned = port A read and port A write

Read Size = 8 bit 

Write Size = 8 bit (because both of the arrays declared are of character type = unsigned int8)

TType = Block Transfer 

Address Mode Read = Address Increment

Address Mode Write = Address Increment

I am calling the function "dmaSetCtrlPacket(DMA_CH5, above control parameters structure)" and then the "dmaSetChEnable(DMA_CH5, DMA_SW)". Then I am polling the bit 5 of BTCFLAG register to SET so as to indicate the transfer complete activity."

The flag in BTCFLAG register gets SET but I dont see any data in my destination array. 

I tried by also bypassing all the tests mentioned above upon power-on and just keeping the DMA test itself but still I dont see any data in the destination array. What is it that I might be missing?

By the way, I am calling the function, "dmaEnable()" right after power-on and before performing the test.

Regards,

Chetan.

  • Hi Chetan,

    You can allocate a memory region as the destination of DMA write, and configure this region as cache-write-through.

  • in sys_main.c:

    #pragma SET_DATA_SECTION(".sharedRAM")

    uint32 TXDATA[100];         /* transmit buffer in sys ram */
    uint32 RXDATA[100]= {0}; /* receive buffer in sys ram */

    #pragma SET_DATA_SECTION()

    Linker cmd:

    MEMORY
    {

       ...
      SHAREDRAM (RW) : origin=0x0807A000 length=0x0005000
    }

    SECTIONS
    {

       ...
      .sharedRAM : {} > SHAREDRAM
    }

    HALCoHen MPU setting:

    select a unused MPU region for SHAREDRAM memory region, configure it as Write-through.

  • Hi Wang!

    Thanks for the answer! But, I want to understand why do we have to do what you suggested? What is the need to define a separate memory region in the RAM when as local variables, the stack is sufficient?

    Also, what is meant by "cache-write-through"? I just know that "cache" is a memory that stores the most immediate used variables, in a very broad sense.

    Can you throw some light on "Cache memory - the type of memory it is, why is it used etc" in the context of our controller RM57?

    Finally, what is exactly happening when I configure as "cache-write-through"?

    Regards,

    Chetan. 

  • You can think of the cache as a small, high-speed buffer placed between the MCU core and main memory that stores blocks of recently referred to main memory. The purpose of a cache is to increase the average speed of memory access.

    Once we’re using a cache, each memory read will result in one of two outcomes:

    1. A cache hit – the memory for the address is already in cache.

    2. A cache miss – the memory access was not in cache, and therefore we have to go out to main memory to access it.

    There are several cache policies:

    1. Write-back: On a cache hit, only the data cache is updated and not the main memory. The cache line is marked as dirty, and writes to the main memory are postponed until the cache line is evicted, or explicitly cleaned.

    2. Write-through: On a cache hit, both the data cache and the main memory are updated.

    3. Write-allocate: On a cache miss, a cache line is allocated and loaded with the data from the main memory. This means that executing a store instruction on the processor might cause a burst read to occur to bring the data from the main memory to cache.

    4. No Write-allocate: On a cache miss, a cache line is not allocated and the data is written directly into the main memory. Here, a line is not cached until a cache miss on a read occurs, which then loads the cache using the Read Allocate policy.

    5. Read-allocate (not configurable): All cacheable locations on Cortex-R5F Hercules MCUs are read allocate. This means that the data cache lines are allocated when a cache miss occurs, bringing 32 bytes of data from the main memory into the cache memory. As a result, subsequent access to these memory locations will result in a cache hit condition, and the data is directly read from the cache memory.

    From the cache policies above, cache write-back with read allocate and write allocate provides the best performance. Write-through with no write-allocate can partially solve the cache coherency issue, but it negates the main advantage of having cache. This is why we can allocate a write-through memory region or a non-cacheable memory region for both CPU and DMA, and leave the other memory regions accessed only by CPU as write-back.  

  • Hi Wang!

    Thanks for the reply! 

    According to your answer, does it mean that it is always suggested to use such non-cacheable memory region/s for data transfers between DMA and CPU and that any buffers whatsoever declared in global RAM can cause this problem?

    Also, is this problem kind of probabilistic, in the sense that it can happen or might not. I mean, sometimes the DMA transfer (according to my first post in this thread) can take place and if it happens once, then it will happen every-time (because of cache) whereas if it doesn't happen then it might never happen?

    Is my understanding correct? I am asking this because, one of my colleagues executed the same function (as mentioned in first post) in his own custom board and the DMA transfer happened. We both use the same startup file as well and memory configurations are also same.

    Regards,

    Chetan.

  • DMA transfer does not go through MCU cache. It writes directly to main memory. If cache is enabled, any update on main memory by DMA is not visible for CPU. MCU may still see the old content because it is read from cache (if cache hits). But first CPU read can get the updated content from main memory because of cache miss. 

    There are several ways to solve the DMA coherency. Using no-cacheable memory region is the easiest way. Write-through memory region can partially solve the DMA coherency problem (CPU write, DMA read).