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.

edma3 ER

Other Parts Discussed in Thread: OMAP-L137

I've been trying to get a memory-to-memory dma example working under codec engine on the OMAP-L137 processor.

Earlier investigation led me to believe that channel 8 and param set 8 are available for use (Linux lays no claim to them).

First I forced the EDMA3 LLD example project to use channel 8/ PaRAM set 8. I ran the resulting image on my target hardware using just the DSP (no ARM9 code). That worked fine.

I tried to convert the main for the EDMA3 LLD to a test function and glued it into my Codec Engine server build. That didn't work, even though I was limiting myself to 8, 8.

I ran the EDMA3 LLD example again, stopping the code before it initiated the transfer. I copied the PaRAM set into my Codec Engine code. The values are

pParam = 0x1c04100
pParam[0] is 0x81008104
pParam[1] is 0xc251d350
pParam[2] is 0x200002
pParam[3] is 0xc251d390
pParam[4] is 0x20002
pParam[5] is 0xffff
pParam[6] is 0x0
pParam[7] is 0x1

I am trying t o manually start the as the example project did. So far no luck. In order to debug my code, I cleared the EER, bit 8. According to the manual, this will caused an ESR write to bit 8 to be directly reflected in ER and not cleared until I manually clear it. (That is the way I interpreted the manual anyway.)

    er = (UInt32 *)0x01c01000;
    esr = (UInt32 *)0x1c01010;
    eecr = (UInt32 *)0x1c01028;


and

   *eecr = 1<<edmaChan;
    temp = *er;
    *esr = 1<<edmaChan;
    temp2 = *er;
GT_1trace(gtMask, GT_1CLASS, "spi_dma_setup> ER before set = 0x%lx\n", temp);
GT_1trace(gtMask, GT_1CLASS, "spi_dma_setup> set ESR = 0x%lx\n", 1<<edmaChan);
GT_1trace(gtMask, GT_1CLASS, "spi_dma_setup> ER after set = 0x%lx\n", temp2);

where edmaChan = 8.

I get the following output:

spi_dma_setup> ER before set = 0x3000440
spi_dma_setup> set ESR = 0x100
spi_dma_setup> ER after set = 0x3000440

I expected the second ER value to have bit 8 set, but it doesn't. I have tried this using the global registers and Shadow 1 registers. Neither worked the way I expected. Can anyone see anything obvious that is wrong? (My plan was to make sure that the ESR assignment works with the EER cleared before I enabled the event.)

  • If you setting up only a single transfer, it is possible that the transfer completed and the ER and ESR bits were cleared even before you could test the ER register for that bit.

    Also you could look at the EMR register to see if there were any missed events etc.

    Are the source and destination addresses cached ?! Are you sure you are looking at the correct

    What version of Codec Engine do you have ?

    Try and locate the following example:-

    /examples/ti/sdo/fc/examples/dmaXfer. See simpleDma.c for an example of how to setup a transfer (without using LLD). Might help with the register settings etc.

  • Following your suggestion, I cut and pasted the code from simpleDma.c directly into my function. I converted the printfs to GT_ trace calls. Current code follows:

    void spi_dma_setup(UInt16 * src, UInt16 * dst, int bytes, int edmaChan)
    {
        unsigned int * pEdma;
        unsigned int * pParam;
        volatile unsigned int * ipr;

        int i = 0;
        unsigned *src_addr = (unsigned int *)src;
        unsigned *dest_addr = (unsigned int *)dst;
        unsigned int tccNum = (unsigned int)-1;

        pEdma = (unsigned int* )EDMAADDR;

        pParam = (unsigned int *)((unsigned int) pEdma + 0x4000 +
                (0x20 * edmaChan)); //param # edmaChan

        tccNum = (edmaChan << 12);

        pParam[0] = (0x00100008 | tccNum); //OPT TCC == edmachan + STATIC
        pParam[1] = (unsigned int)src_addr;
        pParam[2] = 0x00010000 + bytes; //Bcnt, Acnt
        pParam[3] = (unsigned int)dest_addr;
        pParam[4] = 0x0;
        pParam[5] = 0xFFFF;
        pParam[6] = 0x0;
        pParam[7] = 0x1;

        GT_1trace(gtMask, GT_1CLASS, "Param # %d\n", edmaChan);

        for (i = 0; i < 8; i++) {
           GT_1trace(gtMask, GT_1CLASS, "0x%x\t",pParam[i]);
        }
        GT_0trace(gtMask, GT_1CLASS, "\n");

        /* SECR = 0xFFFFFFFF */
        *((unsigned int *)((unsigned int) pEdma + 0x1040)) = 0xFFFFFFF;
        GT_1trace(gtMask, GT_1CLASS, "SER 0x%x\n", *((unsigned int *)((unsigned int) pEdma + 0x1038)));

        /* EESR  = 0x2
        *((unsigned int *)((unsigned int) pEdma + 0x1030)) = (0x01 << edmaChan);
        GT_1trace(gtMask, GT_1CLASS, "EER 0x%x\n", *((unsigned int *)((unsigned int) pEdma + 0x1020)));
        */

        /* IESR = 0x02 */
        /*
        *((unsigned int *)((unsigned int) pEdma + 0x1060)) = 0xFFFFFFF;
        GT_1trace(gtMask, GT_1CLASS, "IER 0x%x\n", *((unsigned int *)((unsigned int) pEdma + 0x1050)));
        */

        /* ICR */
        *((unsigned int *)((unsigned int) pEdma + 0x1070)) = (0x01 << edmaChan);

        /* DCHMAP */
        *((unsigned int *)((unsigned int) pEdma + 0x100 + (0x4 * edmaChan))) =
                (edmaChan << 4) ;


        ipr = (unsigned int *)((unsigned int)pEdma+ 0x1068);
        GT_1trace(gtMask, GT_1CLASS, "IPR Before 0x%x\n", *ipr);

        /* ESR = 0x02 */
        *((unsigned int *)((unsigned int) pEdma + 0x1010)) = (0x01 << edmaChan);

        GT_1trace(gtMask, GT_1CLASS, "EER 0x%x\n", *((unsigned int *)((unsigned int) pEdma + 0x1020)));

        /* Check for completion */
        while (((*ipr) & (0x1 << edmaChan))  != (0x01 << edmaChan));
        GT_1trace(gtMask, GT_1CLASS, "IPR After 0x%x\n", *ipr);
    }

    After the call to the code, I print the first 4 locations of both the source and destination buffers. Neither the source nor destination buffers are different from their initial values, suggesting that the DMA did not perform the expected copy.

    [DSP] @0x000001eb:[T:0x00000000] DSP_server - Param # 8
    [DSP] @0x000001fe:[T:0x00000000] DSP_server - 0x81108008    @0x00000213:[T:0x00000000] DSP_server - 0xc251d350    @0x00000228:[T:0x00000000] DSP_server - 0x10040    @0x0000023b:[T:0x00000000] DSP_server - 0xc251d390    @0x00000250:[T:0x00000000] DSP_server - 0x0    @0x00000261:[T:0x00000000] DSP_server - 0xffff    @0x00000273:[T:0x00000000] DSP_server - 0x0    @0x00000284:[T:0x00000000] DSP_server - 0x1    @0x00000295:[T:0x00000000] DSP_server -
    [DSP] @0x000002a5:[T:0x00000000] DSP_server - SER 0x0
    [DSP] @0x000002b7:[T:0x00000000] DSP_server - IPR Before 0x0
    [DSP] @0x000002cc:[T:0x00000000] DSP_server - EER 0x0
    [DSP] @0x000002de:[T:0x00000000] DSP_server - IPR After 0x100
    [DSP] @0x000002f3:[T:0x00000000] DSP_server - testedma> SrcBuf[0] = -21075
    [DSP] @0x0000030c:[T:0x00000000] DSP_server - testedma> SrcBuf[1] = -21075
    [DSP] @0x00000325:[T:0x00000000] DSP_server - testedma> SrcBuf[2] = -21075
    [DSP] @0x0000033e:[T:0x00000000] DSP_server - testedma> SrcBuf[3] = -21075
    [DSP] @0x00000356:[T:0x00000000] DSP_server - testedma> dstbuf[0] = 257
    [DSP] @0x0000036d:[T:0x00000000] DSP_server - testedma> dstbuf[1] = 257
    [DSP] @0x00000385:[T:0x00000000] DSP_server - testedma> dstbuf[2] = 257
    [DSP] @0x0000039c:[T:0x00000000] DSP_server - testedma> dstbuf[3] = 257

    While this has all the symptoms of a cache problem, I have not tried to enable cache yet. Perhaps I've enabled it by accident via some code that I've included. The buffers are both in external memory. What would I have to do to test the cache theory? That is, what action would I do to cause cache to be flushed prior to printing the source and destination buffers?

  • You could use ti.sdo.fc.memutils.MEMUTILS module to call some cache APIs.

    - In your cfg file add the following:-

    var MEMU = xdc.useModule("ti.sdo.fc.memutils.MEMUTILS");

    - In your c file, make the following changes:-

    #include <ti/sdo/fc/memutils/memutils.h>

    Before the transfer (and after you have updated the src, dst buffers with desired data), WB and WBINV the SRC/DST buffers respectively:-

        MEMUTILS_cacheWb((Ptr)src_addr, BUF_SIZE);
        MEMUTILS_cacheWbInv((Ptr)dest_addr, BUF_SIZE);

    Set up the params and fire off the transfer. Before checking contents of  the dst buffer, invalidate cache contents:-

      MEMUTILS_cacheInv((Ptr)dest_addr, BUF_SIZE);