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.

TMDX5515EZDSP, I2S and DMA

Hello.

I tried to start I2S DMA MODE TEST from c55xx_csl\ccs_v4.0_examples (csl lib. ver 2.50). This is output of the test:

CSL I2S DMA MODE TEST!

 

I2S Module Instance opened successfully

I2S Module Configured successfully

I2S Reset Successful

I2S Close Successful

I2S Read & Write Buffers doesn't Match!!!

 

CSL I2S DMA MODE TEST FAILED!!

After working this program i2sDmaWriteLeftBuff = 0x12345678, i2sDmaWriteRightBuff = 0x12345678, i2sDmaReadLeftBuff = 0x90ADB448, i2sDmaReadRightBuff = 0xE0244856.

I also made my own simple program, using board support library and datasheets. This program transfers data from memory to I2S and from I2S to memory using DMA.

Sometimes this program transfers data from i2s_t_buf[] to i2s_r_buf[] properly, but usually I see broken data in i2s_r_buf[].

For example i2s_t_buf[] contains 0, 5, 10, 15..., i2s_r_buf[] contains 0, 92, 951, 0... What's wrong with I2S and DMA?

This is my simple program:

---------------------------------------------------------

#define BUF_SIZE   256

#pragma DATA_ALIGN (i2s_t_buf, 4);
unsigned short i2s_t_buf[BUF_SIZE];

#pragma DATA_ALIGN (i2s_r_buf, 4);
unsigned short i2s_r_buf[BUF_SIZE];
void main(void)
{
     USBSTK5515_init();    /* Initialize BSL */

    for(i=0; i<BUF_SIZE; i++) i2s_t_buf[i] = i*5;
    for(i=0; i<BUF_SIZE; i++) i2s_r_buf[i] = 0;

     i2sinit();
    while(1) {}
}

void i2sinit()
{
    volatile int i;

    peripheral_reset(0x20, (1<<5)); // reset MMC/SD0, MMC/SD1, I2S0, and I2S1

#define I2S0CG   (1<<8)

    SYS_PCGCR1 &= (~I2S0CG); // Peripheral clock is active

    // these bits take effect within 6 SYSCLK cycles and do not require an idle instruction.
    for(i=0; i<10; i++) {}

    _disable_interrupts();

        *I2S0ADDR(I2SINTMASK) = 0; // disable all interrupts;

        if(*I2S0ADDR(I2SINTFL)) {} // read interrupt flag register

        // DMA
        dma_0_01_init();

    _enable_interrupts();

    *I2S0ADDR(I2SSRATE) = (0x3<<3); // FS divided by 64, CLK divided by 2

    // enable, stereo
    // loopback
    // packing mode enabled, 16 bit
    // master, i2s format
    *I2S0ADDR(I2SSCTRL) = 0x8892;
}

void dma_0_01_init()
{
    unsigned long addr;
   
    while(((*PRCR_ADDR)&(1<<4)) != 0) {} // Ensure the DMA controller is out of reset

#define DMA0CG (1<<3)

    SYS_PCGCR1 &= (~DMA0CG); // Enable the DMA controller input clock

    *DMAIFR = 0x3; // manually clear the DMA0CH0IF and DMA0CH1IF of DMAIFR

    *DMACTRL0(DMACH0TCR2) = 0;

    *DMA0CESR1 = 0x0201; // CH1 receive I2S event, CH0 transmit I2S event

    // memory to i2s
    addr = (unsigned long)(&i2s_t_buf[0]);
    *DMACTRL0(DMACH0SSAL) = (unsigned short)((addr<<1)&0xFFFE);
//    *DMACTRL0(DMACH0SSAU) = (unsigned short)((addr>>15)&0xFFFC);
    *DMACTRL0(DMACH0SSAU) = 1;
    *DMACTRL0(DMACH0DSAL) = 0x280C;
    *DMACTRL0(DMACH0DSAU) = 0x0000;

    // i2s to memory
    addr = (unsigned long)(&i2s_r_buf[0]);
    *DMACTRL0(DMACH1SSAL) = 0x282C;
    *DMACTRL0(DMACH1SSAU) = 0x0000;
    *DMACTRL0(DMACH1DSAL) = (unsigned short)((addr<<1)&0xFFFE);
//    *DMACTRL0(DMACH1DSAU) = (unsigned short)((addr>>15)&0xFFFC);
    *DMACTRL0(DMACH1DSAU) = 1;

    *DMACTRL0(DMACH0TCR1) = BUF_SIZE*2;
    *DMACTRL0(DMACH1TCR1) = BUF_SIZE*2;

    // EN, AUTORLD
    // DSTAMODE = constant address;
    // SRAMODE = autoincrement, BURSTMODE = 1 double word (4 bytes)
    // SYNCMODE, PING_PONG_EN
    *DMACTRL0(DMACH0TCR2) = 0x9205;

    // EN, INT enabled, AUTORLD    
    // DSTAMODE = autoincrement;
    // SRAMODE = constant address, BURSTMODE = 1 double word (4 bytes)
    // SYNCMODE, PING_PONG_EN
    *DMACTRL0(DMACH1TCR2) = 0xB085;
}

---------------------------------------------------------