AnsweredAssumed Answered

Using GPDMA to send audio buffer to I2S

Question asked by leecoakley on Mar 25, 2018
Latest reply on Mar 28, 2018 by leecoakley

I have an audio mixer that generates samples into a ring buffer. I want the DMA to send chunks of this ring buffer to the I2S TX FIFO and receive an interrupt when the chunk has been sent.

 

I can't seem to get it to work though.  If I configure the DMA as flow controller the transfer never starts and I hear nothing.  If I use the peripheral as the flow controller then the audio plays at first but the DMA just keeps incrementing its read address forever until it bus faults.

 

Ideally I'd like to have a circular linked-list of transfers but let's start simple.  How do I send a buffer to the I2S block correctly?

 

I can't find any examples that have this memory-to-peripheral I2S setup. Only peripheral-to-peripheral from RX to TX. Are there any examples out there?

 

Here's what I have right now:

// Configure the DMA transfer

const Status status = Chip_GPDMA_Transfer(

    dma,

    0,

    (uint32) audioBuffer,

    GPDMA_CONN_I2S_Tx_Channel_0,

    GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL,

    1024

);

 

if (status != ERROR) {

    printf( "DMA transfer setup failed!\n" );

    return;

}

 

// Start requesting data
i2s->DMA[I2S_DMA_REQUEST_CHANNEL_1] |= I2S_DMA1_TX_ENABLE;

This is the relevant part only. Before this happens, the I2S and GPDMA blocks are fully set up. I know those parts are okay because I have no problems driving the I2S peripheral through software. The only problem is how to get the DMA to behave sensibly.

Outcomes