Page 1 of 1

I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Mon May 29, 2017 2:31 am
by jcwren
I'm trying to understand how to determine the values for dma_buf_count and dma_buf_len when receiving (or transmitting...) I2S data.

I've read through the i2s_example_main.c, and understand how to calculate the values if I'm synthesizing a waveform, but I don't understand how to determine the values for data from something like an I2S microphone.

The sample rate is 32,000 Hz, using a 32-bit word, with both left and right channels. What sort of values would be reasonable in this case? Is there a formula for this?

Thanks in advance.

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Mon May 29, 2017 5:03 am
by ESP_Sprite
It depends on the application. Larger buffers mean less CPU time, because the CPU can set up a DMA transaction and then go do something else for a long time. On the flip side, it also means more latency (because you have to know the entire buffer before you're able to DMA it (or use dirty hacks)) and you have the extra memory use of the larger buffers. If you want a random value that usually works, set it to 1K or so, you can always modify it later on.

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Mon May 29, 2017 8:27 am
by BuddyCasino
Yes, its not a precise science. The memory consumption of the DMA buffer is calculated as follows:

Code: Select all

(bits_per_sample / 8) * num_chan * dma_buf_count * dma_buf_len
Example:
16 bit stereo, dma_buf_count 32, dma_buf_len 64
= 32 * 256
= 8192 bytes

A bit tricky because dma_buf_len is not bytes, but samples!

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Wed Aug 02, 2017 2:27 am
by p-rimes
Sorry to bump this old thread, but I notice within esp-idf, in the file components/esp32/test/test_ahb_arb.c:130 the following code snippet. As far as I can tell, this is the only occurrence within esp-idf of non-uint8_t data being sent with DMA, and here it appears that length and size are both set to the byte count. This does seem odd (maybe the esp-idf test code is invalid? the comment indicates the quality may be poor).

Code: Select all

130 /*
131 This is a very, very, very hacked up LCD routine which ends up basically doing a memcpy from sbuf to rbuf.
132 */
133 static void sendRecvBufDma(uint16_t *sbuf, uint16_t *rbuf, int len)
134 {
135     //Fill DMA descriptor
136     dmaDesc[0].length = len * 2;
137     dmaDesc[0].size = len * 2;
...
I'm just trying to confirm what is said in this thread, which would indicate that

Code: Select all

dmaDesc[0].length
is set incorrectly in the sample code above?

At any rate, where is this stuff mentioned and/or what document is definitive, anyway?

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Wed Aug 02, 2017 2:59 am
by kolban
Howdy,
I've been studying the DMA under the auspices of this sample:

https://github.com/igrr/esp32-cam-demo

There is also an excellent thread here ...

https://github.com/igrr/esp32-cam-demo/issues/29

which if one bites the bullet and reads through it, there is some gold.

In addition, Ive got a "sorta working" sample here:

https://github.com/nkolban/esp32-snippe ... ls/I2S.cpp

with some "DMA" working.

That said ... the docs for I2S/DMA are pretty rough ... however, if anyone wants to collaborate ... I'd be up to working with y'all to try and decode it together. I feel that there is likely value in pulling knowledge and posing questions to us that we can then dig into.

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Wed Aug 02, 2017 4:48 am
by p-rimes
Thanks, that does help.

This specific comment from the Github issue you mentioned seems to be the most up-to-date info on the matter:
size: size of the buffer pointed to by buf member

length: number of valid data bytes stored into the buffer. For example, if you create a DMA descriptor with 1024 bytes size, and start receiving data using I2S with RX_EOF_NUM set to 128 (samples), then I2S will store only 128 (sampels) * 4 (bytes per sample) = 512 bytes into the DMA buffer, and set the length field to 512.
@igrr - https://github.com/igrr/esp32-cam-demo/ ... -308629259

That at least answers the question for what I should use (.length == .size), and does imply that they are both measured in bytes. I can't think of a situation right now where size and length would be different (maybe static allocating a large buffer for the maximum value considered at compile-time, but choosing a smaller DMA transfer .length at run-time?), but I will know what do if that comes up!

Re: I2S: dma_buf_count and dma_buf_len values for receive?

Posted: Wed Aug 02, 2017 5:23 am
by p-rimes
Also, incidentally, @kolban does your "sorta working" example work for you? My use is different (and working... but v. slow) but the configuration is similar (yours is camera+RX+I2S0, mine is LCD+TX+I2S1), but personally I'm not able to run at this speed:

Code: Select all

I2S0.clkm_conf.clkm_div_num = 2;
(I really wish I could run a bit faster, but unfortunately I get unreliable output anywhere below 8).

I believe at a value of 2, my output only gets a couple clock cycles then dies, so I'm curious if you've had it working for any amount of time at that speed, and what sort of max clock frequency you were getting?