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.
I2S: dma_buf_count and dma_buf_len values for receive?
-
- Posts: 9835
- Joined: Thu Nov 26, 2015 4:08 am
Re: I2S: dma_buf_count and dma_buf_len values for receive?
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.
-
- Posts: 263
- Joined: Sun Jun 19, 2016 12:00 am
Re: I2S: dma_buf_count and dma_buf_len values for receive?
Yes, its not a precise science. The memory consumption of the DMA buffer is calculated as follows:
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!
Code: Select all
(bits_per_sample / 8) * num_chan * dma_buf_count * dma_buf_len
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?
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).
I'm just trying to confirm what is said in this thread, which would indicate that is set incorrectly in the sample code above?
At any rate, where is this stuff mentioned and/or what document is definitive, anyway?
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;
...
Code: Select all
dmaDesc[0].length
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?
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.
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.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: I2S: dma_buf_count and dma_buf_len values for receive?
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:
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!
This specific comment from the Github issue you mentioned seems to be the most up-to-date info on the matter:
@igrr - https://github.com/igrr/esp32-cam-demo/ ... -308629259size: 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.
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?
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: (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?
Code: Select all
I2S0.clkm_conf.clkm_div_num = 2;
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?
Who is online
Users browsing this forum: Bing [Bot] and 108 guests