I2S - detect empty DMA queue
Posted: Mon Feb 22, 2021 4:14 am
Hi (newbie here),
I'm working on a project that inputs audio packets via UDP (VBAN protocol) and outputs them to an external I2S DAC. It's working fine, other than occasional crackles.
I suspect that I'm suffering DMA buffer underrun, but don't know a way to detect when the I2S/DMA has run out of fresh data and is going to re-use old buffers.
Simply, my code is an interrupt driven routine to put incoming packets into a double-buffered queue.
udpIn.onPacket(UDPtoQ)
The I2S writing code, which I have tried as both an xTask and in the main program loop, refills the I2S DMA buffers (I've tried 2 - 6 * 256 sample buffers with no real difference) using i2s_write().
I can detect when the DMA queue was full, by measuring the time it takes to execute i2s_write().
Is there a way to detect when the DMA queue is empty? I've tried reading I2S0.state.tx_idle, I2S0.int_st.out_done, I2S0.int_st.tx_rempty, I2S0.int_st.out_eof and I2S0.int_raw.tx_rempty.
None of them seem to return useful data for this purpose - possibly because the DMA is continually re-using the old buffers.
Thanks in anticipation.
I'm working on a project that inputs audio packets via UDP (VBAN protocol) and outputs them to an external I2S DAC. It's working fine, other than occasional crackles.
I suspect that I'm suffering DMA buffer underrun, but don't know a way to detect when the I2S/DMA has run out of fresh data and is going to re-use old buffers.
Simply, my code is an interrupt driven routine to put incoming packets into a double-buffered queue.
udpIn.onPacket(UDPtoQ)
The I2S writing code, which I have tried as both an xTask and in the main program loop, refills the I2S DMA buffers (I've tried 2 - 6 * 256 sample buffers with no real difference) using i2s_write().
I can detect when the DMA queue was full, by measuring the time it takes to execute i2s_write().
Is there a way to detect when the DMA queue is empty? I've tried reading I2S0.state.tx_idle, I2S0.int_st.out_done, I2S0.int_st.tx_rempty, I2S0.int_st.out_eof and I2S0.int_raw.tx_rempty.
None of them seem to return useful data for this purpose - possibly because the DMA is continually re-using the old buffers.
Thanks in anticipation.