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.

enet_uip_m3 example and the uDma access on Concerto

Other Parts Discussed in Thread: CONTROLSUITE

The project I'm currently working uses the enet_uip_m3 as the base for the ethernet comms and everything is working fine.

The problem is: this example uses the F28M25x_generic_M3_RAM.cmd and F28M25x_generic_M3_FLASH.cmd linker files and neither of those uses the shared Sx memory, and my project will be using it. But if I try to add those areas, the ethernet stops working.

I'm assuming that, although not shown on the linker file, uDMA configured on enet_uip_m3 is using that area to process it's stuff and thou, conflicting with the rest of my code.

So my questions are:

is my assumption correct? how to I check which areas the uDMA is using?

thanks.

  • I can't explain exactly WHY it's working now but I made it working.

    I started tracking the addressing of stuff through the codes starting on the udma.h where we have the tDMAControlTable struct with a:

            // The ending source address of the data transfer.
    volatile void *pvSrcEndAddr; 

    ok , 'source address' that looks good, let's see where it's used, so I went to udma.c and found that it gets this address from pvSrcAddr that comes from this call:

    void uDMAChannelTransferSet(unsigned long ulChannelStructIndex,
    unsigned long ulMode, void *pvSrcAddr, void *pvDstAddr,
    unsigned long ulTransferSize)

    so then, I went to track on the enet_uip_m3 code where this is being called and we have two lines that does the call:

    	// Set up the DMA to transfer the Ethernet header when a packet is received
    uDMAChannelTransferSet(UDMA_CHANNEL_ETH0RX, UDMA_MODE_AUTO, (void *) (ETH_BASE + MAC_O_DATA), &pucBuf[2], lTempLen >> 2);

    and

    	// Configure the TX DMA channel to transfer the packet buffer.
    uDMAChannelTransferSet(UDMA_CHANNEL_ETH0TX, UDMA_MODE_AUTO, pucBuf, (void *) (ETH_BASE + MAC_O_DATA), lBufLen >> 2);

    which gives us two values to look at (in bold letters). ETH_BASE is defined on hw_memmap.h and it's a 0x40048000, all the way up on the peripheral registers mapping, so this definitely not the problem. Let's find pucBuf; it's being passed from this call:

    static long EthernetPacketPutDMA(unsigned long ulBase, unsigned char *pucBuf, long lBufLen);

    ok, let's see who is calling it; there's quite a few of calls but all of them pass the same uip_buf parameter; a few more searches and we find it being defined as a normal pointer to a u8_t and it's set to point to:

    	// Adjust the pointer to be aligned on an odd half word address so that DMA can be used.
    uip_buf = (u8_t *) (((unsigned long) ucUIPBuffer + 3) & 0xfffffffe);

    which is just that buffer declared there: u8_t ucUIPBuffer[UIP_BUFSIZE + 2];

    So, it shouldn't have problem at all ... so let's try to see again what would be the difference between the linker files with and without the Sx memory. Well, besides the obvious inclusion of the S0 areas... on the generic, the variable data is stored across the RAM

        .vtable :   >  C0 | C1 | C2 | C3
    .data : > C2 | C3
    .bss : >> C2 | C3
    .sysmem : > C0 | C1 | C2 | C3
    .stack : > C0 | C1 | C2 | C3

    while the example linker with the shared memory was all using C0 ... so I replace that line to include all the RAM and the thing started working almost as magic (but it's hard work science engineering and a bit of guessing).

    If anyone could the WHY of it all, I guess would be a good addition to the forum, but in any case, I'm marking my response as correct.

    Thanks for reading!

  • Pace,

    Thanks a lot for your detailed debug and thanks for sharing it all.

    C0 and C1 memories on Master subsytem are not uDMA accessible. So the example linker command file for shared RAM(s) usage has to be corrected so that it does't place any data sections in C0/C1 RAM(s). Generic linker command files seems to be corrected in the latest countrolsuite release - we will update the shared RAM usage linker command files too.

    Also, please check the errata on uDMA - so that you are aware of it. Not that you are running into that same issue.

    Best Regards

    Santosh

  • Santosh,

     I've a similar task to do with uDMA and ethernet controller, maybe you can help me.

    With the concerto unit, I have to write the shared memory continually and access to it at the same time.

    My question is:is it possible? I checked the errata of the Concerto MCUs and I've doubt about it:

    "If μDMA accesses Shared RAM (Cx and Sx) or MSG RAM when any other master
    (Cortex™-M3/C28x/DMA) accesses the same memory, data and parity may get
    corrupted in the memory."

    In my solution the c28 core saves its data to S0 shared RAM.

    I'd like to access to it with the uDMA controller from the M3 side and send it via ethernet...

     

    So any suggestion would be appreciate about this problem..

    Thanks,

    Balazs

  • Balazs,

    That errata is valid for REV0 of Si, we are fixing it in the next REV.

    Depending on how you write your SW, you might not see the issue in your case, you can use IPC to realize a mutex operation on Sx RAM.

    > 1. C28 writes data to S0 RAM

    > 2. Sends IPC to Master and waits for IPC to clear.

    > 3. Master waits for it and receives the IPC and enables uDMA to transmit the data out

    >4. When master is done, it either sends an IPC back or clear the IPC it got in step 2.

    if you want to avoid waits in step2 and step3 you can two buffers in S0 RAM and alternatively switch between each of them. Depending on how fast C28 can give the new data for M3 to be transmitted you can do one of the above. Atleast this can be a good starting point.

    Pleaes let us know if you have any more questions. Our uDMA expert is monitoring this thread and he will chime in as needed.

     

    Best Regards

    Santosh

     

     

  • Santosh,

    Thanks for the idea.

    If I willl have critical timings in my solution -so uDMA will necessary- something like this is going to be implemented.

    regards,

    Balazs

  • Hi Santosh,

    We are experiencing the same problem with enet_uip and DMA refusing to interrupt on the Concerto. I looked into the linker files provided in the ControlSuite latest version and couldn't find anything for the ARM with shared memory. Could you send me an example ARM linker file that solves this problem.

    Thanks,

    Mason

  • Mason,

    the problem could be different, can you open a new forum post explaining the scenario? and which device you are looking at F28M35x or F28M36x?

     

    Best Regards

    Santosh