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.

problem using EDMA with using dsplink

Hi,

I have a problem using EDMA transfer under dsplink environment. I use
EDMA by the following sequence:
1. Set appropriate DRAE register to use EDMA3 channel 0 shadow region
1 to transfer data;
2. Configure channel 21 to transfer 6 int data from AD_BUF to AD_BUF3
in a single operation;
3. Start EDMA and check the data at AD_BUF3.

The following code runs correctly as expected under CCS, but failed in
linux+dsp/bios with dsplink environment.
I can get IPR normally, but AD_BUF3 is left unchanged.

Here's a snippet of the code I am using:

int16_t AD_BUF[12];
int16_t AD_BUF3[] = {1,2,3,4,5,6};
#define BCNT 1
void DMA_init()
{
       struct EDMA3CC_PaRAM    *pEDMA3CC_PaRAM;
       unsigned int state;

       state = 1  << 21;
       EDMA3_0_EECR    =  state;
       EDMA3_0_IECR    =  state;
       EDMA3_0_ICR     =  state;
       EDMA3_0_SECR    =  state;
       EDMA3_0_EMCR    =  state;
       EDMA3_0_ECR     =  state;

       pEDMA3CC_PaRAM =(struct EDMA3CC_PaRAM *) 0x01c042a0;//  chan 21 param

       pEDMA3CC_PaRAM -> OPT = (1 << 20) | (21 << 12) | (1 << 8) | (0 << 2);
       pEDMA3CC_PaRAM -> SRC = (volatile int16_t*)AD_BUF3;
       pEDMA3CC_PaRAM -> A_B_CNT = (BCNT << 16) | 12;
       pEDMA3CC_PaRAM -> DST = (volatile int16_t*)AD_BUF;
       pEDMA3CC_PaRAM -> SRC_DST_BIDX = (12 << 16);
       pEDMA3CC_PaRAM -> LINK_BCNTRLD = (BCNT << 16)|0xFFFF;
       pEDMA3CC_PaRAM -> SRC_DST_CIDX = 0;
       pEDMA3CC_PaRAM -> CCNT = 1;

       EDMA3_0_IESR    |= (1 << 21);
       EDMA3_0_EESR    |= (1 << 21);
       EDMA3_0_ICR     |= (1 << 21);
}

void test_edma()
{
       DRAE0 = 0;
//using the shadow region 1
       DRAE1 = 0xFFFFFFFF;
       AD_BUF[0] = 0;
//config the edma param
       DMA_init();
       DMAQNUM2 |=(1<<20);
       EDMA3_0_CCERRCLR |=(1<<21);
       EDMA3_0_ESR |=(1<<21);
//check the edma ipr
       while((EDMA3_0_IPR & (1 << 21)) == 0);
       EDMA3_0_ICR |= (1 << 21);
}

Here is the related register definition:

//region register
#define EDMA3_0_ECR             *(uint32_t *)0x01C02208
#define EDMA3_0_ESR             *(uint32_t *)0x01C02210
#define EDMA3_0_EECR            *(uint32_t *)0x01C02228
#define EDMA3_0_EESR            *(uint32_t *)0x01C02230
#define EDMA3_0_IECR            *(uint32_t *)0x01C02258
#define EDMA3_0_IESR            *(uint32_t *)0x01C02260
#define EDMA3_0_IPR             *(uint32_t *)0x01C02268
#define EDMA3_0_ICR             *(uint32_t *)0x01C02270
#define EDMA3_0_SECR            *(uint32_t *)0x01C02240

//global register
#define DMAQNUM2                *(uint32_t *)0x01c00248
#define EDMA3_0_CCERRCLR        *(uint32_t *)0x01c0031c
#define EDMA3_0_EMCR            *(uint32_t *)0x01C00308
#define DRAE0                   *(uint32_t *)0x01C00340
#define DRAE1                   *(uint32_t *)0x01C00348

  • Since it works on CCS but not in the Linux environment, the issue is likely due to Linux using the channel(s) that the DSP is also trying to use.

    If that is the case, you will need to "reserve" some EDMA channels for the DSP's use.  There is another thread in the Forum which mentions this (2nd post from Sekhar Nori): http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/51363/190268.aspx

    Regards,

    - Rob