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.

Subframe DMA transfer issue!

Hi All,

         I'm working on C6678 and CCS v5.1.1.

I have a buffer gRxBuffer on DDR3. I want to copy a small portion of this to a local buffer tempin.  My present code is like the following:

for(m = 511; m >= 256; m--)
{
tempin[m] = *(gRxBuffer + (p * offset1) + (i * row_width)+ m)  ;   // p and i are loop variables. offset1 and row_width have const values.
}

I want to replace this with DMA. I have set the PARAM set as

/* Setup the parameter entry parameters (READ buffer) */
myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                    CSL_EDMA3_TCCH_DIS, \
                                    CSL_EDMA3_ITCINT_DIS, \
                                    CSL_EDMA3_TCINT_EN, \
                                    0, CSL_EDMA3_TCC_NORMAL,\
                                    CSL_EDMA3_FIFOWIDTH_NONE, \
                                    CSL_EDMA3_STATIC_EN, \
                                    CSL_EDMA3_SYNC_A, \
                                    CSL_EDMA3_ADDRMODE_INCR, \
                                    CSL_EDMA3_ADDRMODE_INCR );


myParamSetup.srcAddr = (Uint32) (gRxBuffer + (p * offset1) + (i * row_width) + 256);
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(256 * sizeof (float), 1);
myParamSetup.dstAddr = (Uint32)tempin;
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,256 * sizeof (float));
myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
myParamSetup.cCnt = 1;

I am pretty sure that my PARAM values are wrong some where.. Please guide me correct my PARAM values for the transfer....


if (CSL_edma3ParamSetup(hParamBufRead,&myParamSetup) != CSL_SOK)
{
printf ("Error: EDMA Parameter Entry Setup failed\n");
}

/* Interrupt enable (Bits 0-1) for the global region interrupts */
regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr = 0x3;
regionIntr.intrh = 0x0000;
CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);

/* Trigger channel */
CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr = 0;
regionIntr.intrh = 0;

/* Poll on IPR bit 0 */
do {
CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
} while (!(regionIntr.intr & 0x1));

The triggering, polling and all is done without any exceptions... But the transfer is not happening...


Regards,

Sohal

  • Sohal,

    Is your local buffer "tempin" located in L2 SRAM?

    If so, we need to use global address for L2 SRAM in EDMA param setup.

    For example, the local L2 SRAM address 0x00801234 should be 0x10801234 for CorePac0 L2 and 0x11801234 for CorePac1 L2 as global address.

  • HI Steven JI,

        Thanks for the reply..

    But how to make it address globally?  I have initialised tempin as..

    #pragma DATA_ALIGN(tempin, 8);
    float tempin[BUFFER_SIZE];

    Presently address of tempin is 0x008101C0.


    How can I make tempin address globally?

    Regards,

    Sohal

  • Sohal,

    You can define something as follows for the translation:

    Uint32 global_address (Uint32 addr)
    {
    Uint32 corenum;
    corenum = CSL_chipReadReg(CSL_CHIP_DNUM);

    if (addr <= 0x10000000)
    {
    addr = addr + (0x10000000 + corenum*0x1000000);
    }
    return addr;
    }

    And provide it translated result to EDMA paramSet:

    myParamSetup.dstAddr = (Uint32)global_address (tempin);


  • Thanks Stevenji.

    That actually worked.

    256 elements were copied to the desired location. but the copied data is kind of garbage values. 

    For eg. The data in Source buffer is -850 and when it is copied it becomes something like -4.56758353 e^34.

    What could be wrong here now?

     

    Regards,

    Sohal

  • Sohal,

    The EDMA itself should not change the values of the data buffers. Please double check the EDMA ParamSet input and make sure you compare the current source and destination addresses.

    For the following,

    myParamSetup.srcAddr = (Uint32) (gRxBuffer + (p * offset1) + (i * row_width) + 256);

    The EDMA will just use the current values of those variables (p,offset1,i,row_width) and do the block transfer to the destination location. 

  • Steven,

               After triggering and after the copying is done when I check (gRxBuffer + (p * offset1) + (i * row_width) + 256) it shows a value say -1084 and the corresponding destination value (tempin[0]) is a garbage kind of value....

    I think something in my PARAM set parameters has went wrong....

    Regards,

    Sohal

  • Sohai,

    The PARAM set seems fine to me although the "STATIC" field is usually set to "Disabled" for DMA channels. And you can check your BIDX parameters with the example in Table 2-5 of EDMA user guide to compare if it matches your application. It may not matter in this case since you have BCNT=CCNT=1.

    Another thing to check is the cache coherency. Please check the srcBuf to see if the values are located in L2/L1D cache instead of the external memory (DDR3). The EDMA may just pick up the old data in DDR3 instead of the new one in the cache.

     

  • Steven,

    I have disabled STATIC. 

    Steven Ji said:

    Another thing to check is the cache coherency. Please check the srcBuf to see if the values are located in L2/L1D cache instead of the external memory (DDR3). The EDMA may just pick up the old data in DDR3 instead of the new one in the cache.

     

    I have checked the source buffer. The value is located in the DDR3 itself.

    Still the problem continues.....

    Regards,

    Sohal

  • Dear Steven,

                      Is there any updates?

    Regards,

    Sohal

  • Sohal,

    I tried your EDMA setup code but did not observe the data corruption as you described.

    Could you please share the whole project with me to reproduce the issue please? Thanks.