Using GPDMA to send audio buffer to I2S

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using GPDMA to send audio buffer to I2S

1,378 Views
leecoakley
Contributor III

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.

Labels (2)
Tags (3)
0 Kudos
5 Replies

949 Views
leecoakley
Contributor III

Alright, I managed to solve this myself. Phew. It can be done and circular linked lists work great.

The hardware works, the I2S driver is perfectly fine, but the GPDMA driver is pretty bad. There is some bug that prevents it from working out of the box although I'm not sure what it is exactly.  Most likely bad CREG.DMAMUX or peripheral src/dst lookup values.  I may diff the registers later to see the exact setup problem.  There is also a bug in the GPDMA driver where it will crash if you try to set up a linked list for a peripheral transfer. Bad design fellas.

My not-very-satisfying solution was to write my own DMA driver from scratch following the documentation closely. It worked on the first attempt, go me.

There's a severe shortage of examples online so I'll share the code for everyone else's benefit. See attached. MIT license; use it for any purpose you like no attribution required. I include the DMA driver and also an example of setting it up to drive the I2S block with a looping buffer.  Some minor editing will be needed to make it compile because I use global includes and stuff like that but it is well commented.

Now I can finally make my glorious fart app... :smileywink:

0 Kudos

949 Views
leecoakley
Contributor III

By the way, something quite useful to know about the GPDMA is that it's an ARM PL080 DMA controller. You can find a bit more detail about how it works in the ARM documentation, about the flow control modes, how big the internal FIFOs are etc.  It's still a bit obtuse but it's helpful when seen alongside the existing docs.

0 Kudos

949 Views
leecoakley
Contributor III

I notice there is an unanswered question from four years ago on this subject...

Is this actually possible, or is there some design flaw or driver bug that prevents this from working?  I at least need to know if it can be done so I'm not wasting my time.

0 Kudos

949 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Please check and download LPCOpen v3.02 Keil, IAR, MCB 4357(REV 3.02) from here.

Customer could refer [periph-uart] demo about GPDMA [memory-to-peripheral] transfer, which located at below default path:

..\lpcopen_3_02_keil_iar_mcb4357\LPC43xx_18xx\examples_43xx_18xx\periph_uart

Wish it helps.


Have a great day,
Mike

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

949 Views
leecoakley
Contributor III

I already solved the problem two days ago, my comment was pending moderation for some time. But thanks anyway.

0 Kudos