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 Self Link is not working with the following Implementation

I'm using the OMAPL-137 and I have code working for the McASP, w/ EDMA and the AIC3106. In trying to fully understand the mechanisms I have two versions of the EDMA setup. One will work the other one will not. I one method my source for TX is a single array for both the left and the right channel and the version of the code that works simply has two src arrays, one for the left and one for the right channel.

This is at the start of my task:

for ( sample = 0 ; sample < 48 ; sample++ )

{
datatx[sample]=datatx[sample]<<16 | 0;
xmt_ping_L[sample]=datatx[sample];
xmt_pong_L[sample]=datatx[sample];
xmt_ping_R[sample]=datatx[sample];
xmt_pong_R[sample]=datatx[sample];
}

and here are the two functions:

the one that does not work

int Edma3_Setup_McASP_XMT(void *src, void *dst, unsigned int bytes, unsigned int samples)
{
CSL_Edma3ccParamSetRegs param;

param.OPT = (EDMA_XMT_PING_TCC << 12) | (1 << 20); // transfer complete interrupt enabled, A Synch Mode
param.SRC = (Uint32)src;
param.A_B_CNT = (2 << 16) | bytes; // actual format: BCNT|ACNT ACnt is 2 bytes or 16 bit word
param.DST = (Uint32)dst;
param.SRC_DST_BIDX = (0 << 16) | 0; // actual format: DSTBIDX|SCRBIDX
param.LINK_BCNTRLD = (2 << 16) | (EDMA_XMTPING * 0x20); // actual format: BCNTRLD|LINK
param.SRC_DST_CIDX = (0 << 16) | (bytes & 0x0000FFFF); // actual format: DSTCIDX|SRCCIDX
param.CCNT = samples; // our array has 48 samples for single 48 KHz period
Edma3_Write_PaRAM(EDMA_MCASPTXCH, &param);

// 2. setup ping PaRAM set (to be reloaded later)
Edma3_Write_PaRAM(EDMA_XMTPING, &param);

return 0;
}

and the one that works

void setup_edma_ping_xmt(void *src_ping_L, void *src_ping_R,
void *dst,
Uint32 bytes, Uint32 samples)
{
CSL_Edma3ccParamSetRegs param;

Uint32 ping_offset = (Uint32)src_ping_R - (Uint32)src_ping_L;
Int32 ping_c_idx = -ping_offset + bytes;

// 1. setup channel PaRAM slot
param.OPT = (EDMA_XMT_PING_TCC << 12) | (1 << 20); // transfer complete interrupt enabled
param.SRC = (Uint32)src_ping_L;
param.A_B_CNT = (2 << 16) | bytes; // actual format: BCNT|ACNT
param.DST = (Uint32)dst;
param.SRC_DST_BIDX = (0 << 16) | ping_offset; // actual format: DSTBIDX|SCRBIDX
param.LINK_BCNTRLD = (2 << 16) | (EDMA_XMTPING * 0x20); // actual format: BCNTRLD|LINK
param.SRC_DST_CIDX = (0 << 16) | (ping_c_idx & 0x0000FFFF); // actual format: DSTCIDX|SRCCIDX
param.CCNT = samples;
Edma3_Write_PaRAM(EDMA_MCASPTXCH, &param);

// 2. setup ping PaRAM set (to be reloaded later)
Edma3_Write_PaRAM(EDMA_XMTPING, &param);
}

I bolded the lines that should be different.

  • Hoffiz,

    My suggestion on the other thread of writing to a RAM buffer would be a useful way to debug this or many data-oriented DMA issues.

    Looking at your bolded lines, we can figure out where the first two samples are being read from. In the working (second) case, the first 16-bit output sample comes from src_ping_L and the second 16-bit sample comes from src_ping_L+ping_offset=src_ping_R.

    In the failing (first) case, the first 16-bit output sample comes from src and the second 16-bit sample comes from src+0 since SRCBIDX=0, which is the same as src and is not a right-channel sample.

    Could this difference explain your data differences?

    If not, please try the RAM buffer destination method and show the results for us to look at with you.

    Regards,
    RandyP
  • in the case that is not working the following should be OK

    In the failing (first) case, the first 16-bit output sample comes from src and the second 16-bit sample comes from src+0 since SRCBIDX=0, which is the same as src and is not a right-channel sample. 

    This the src is an array and the dst is the McASP address. What I'm trying to do with this Edma Setup is generate the same sample to the left and the right channel. Hence I keep SRCBIDX=0, so that for each AXEVT, which corresponds to left, right,..... I send the same src element. Then C is set to the number of samples to exhaust the 48 samples array.

    I tried saving to RAM by borrowing the rcv_pong_L array and modified the Edma_Setup to

    void Edma3_Setup_McASP_XMT(void *src, void *dst, unsigned int bytes, unsigned int samples)
    {
    CSL_Edma3ccParamSetRegs param;

    param.OPT = (EDMA_XMT_PING_TCC << 12) | (1 << 20); // transfer complete interrupt enabled, A Synch Mode
    param.SRC = (unsigned int)src;
    param.A_B_CNT = (2 << 16) | bytes; // actual format: BCNT|ACNT ACnt is 2 bytes or 16 bit word
    param.DST = (unsigned int)dst;
    param.SRC_DST_BIDX = (0 << 16) | 0; // actual format: DSTBIDX|SCRBIDX
    param.LINK_BCNTRLD = (1 << 16) | (EDMA_RCVPING * 0x20); // actual format: BCNTRLD|LINK
    param.SRC_DST_CIDX = (bytes << 16) | (bytes); // actual format: DSTCIDX|SRCCIDX
    param.CCNT = samples; // our array has 48 samples for single 48 KHz period
    Edma3_Write_PaRAM(EDMA_MCASPTXCH, &param);

    // 2. setup ping PaRAM set (to be reloaded later)
    Edma3_Write_PaRAM(EDMA_XMTPING, &param);
    }

    because I'm still using the McASP event to drive the EDMA I have left 
    param.SRC_DST_BIDX = (0 << 16) | 0;  
    but changed
    param.SRC_DST_CIDX = (bytes << 16) | (bytes); // actual format: DSTCIDX|SRCCIDX

    in my task I call

    Edma3_Setup_McASP_XMT(xmt_ping_L, rcv_pong_L, BYTES, SAMPLES);

    xmt_ping_L is initialize to:

    for ( sample = 0 ; sample < 48 ; sample++ )
    {
    xmt_ping_L[sample]=datatx[sample]<<16 | datatx[sample]<<16;

    and to be safe this is how I print the result

    for ( sample = 0 ; sample < 48 ; sample++ )
    {
    System_printf("%d %d %d %d %d\n",
    (short)(xmt_ping_L[sample]>>16),
    (short)(rcv_ping_L[sample]>>16),
    (short)(rcv_ping_R[sample]>>16),
    (int)(rcv_pong_L[sample]>>0),
    (short)(rcv_pong_R[sample]>>16));
    }

    the result of rcv_pong_L is zeros.

     

  • Hoffiz,

    Are you working on an EVM or a custom board you have built? Can you connect CCS to it, is my reason for the question. Using printf for debugging this leaves questions open, where I was hoping to see the Memory Browser view of the memory instead of the shifted interpretation of it.

    Can that be done here, using CCS? This will allow you to show the physical contents of the memory buffers and not the CPU view, which could be affected by caching.

    To get the memory destination to work for showing what is happening, you will need to use APIs to write to ESR to manually trigger the events. You can do this regardless of the state of the McASP, in fact it will be best if the McASP is not in the way.

    To see what the EDMA3 is doing, the DSTBIDX must be 'bytes', not 0.

    Regards,
    RandyP
  • I'm working with the Spectrum Digital EVM board and yes, I'm using CCS. I'm kind of new to CCS. Is there any documentation you can share in how to look at the actual memory. I have done a manually trigger EDMA setup, that is actually how I started looking into this. If you can help me look at the physical memory I can follow up with the manually trigger edma.