-->
Page 4 of 5

Re: I2S for generating waveforms for ledpixel devices

PostPosted: Mon Aug 31, 2020 12:11 pm
by eriksl
davydnorris wrote:OK I can definitely help you with quite a bit of this.
BCK_DIV_NUM, CLKM_DIV_NUM and BITS_MOD work together to set the I2S clock frequency and the number of significant bits in the signal. You have to find the optimal value of all three that's closest to your desired frequency. These are my own notes in my header file so I remember:

The question is more, what limits does Espressif or the I2S module impose on the values. For my desired clock rate, I can choose quite a few ratios between the two, and for now, all of them seem to work. But OTOH Espressif themselves say there are limits, but doesn't clearly state what the limits are.

For example
Note that I2S_CLKM_DIV_NUM must be >5 for I2S data

I have proven this to be not true, with this divider smaller than 5 it still just works, so the I ask myself, where is the real information (by Espressif).

The BITS may be 24bit (bit depth), 31bit (max value in register) or 32bit (value size returned from mic) depending on how it works

The format specifiers only have entries for 8, 16 and 24 bit samples. So I don't know how one is supposed 31 or 32 bit? Or do you mean 2 x 16 bits (two channels)?

#define WS_I2S_CLKM_DIV 13 /* Clock Divisor 5-63 */

I'd prefer to call that the prescaler.

#define WS_I2S_BITS 15 /* Sampling depth-16. Currently needs looking into as it's 4 bits max, which gives 31 bits max?? */

I think the FIFO only allow for one, two or three bytes entries, so that would boil down to 1(?) to 24 bits per sample per channel.

i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);

This the dreaded binary blob in ROM which I replaced by a source code version I found somewhere, but it's still gobbledeegook.

//Enable FIFO in i2s module
SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);

This is where it clearly shows that you copied the Espressif mp3 player example code ;) It has the same flaw. This line does NOT enable the FIFO, instead it DISABLES it (and enables SLC mode).

But apparently you didn't have answers to my questions (comments) in the code I posted. I hope someone else does, but I very much doubt it, I am afraid.

Re: I2S for generating waveforms for ledpixel devices

PostPosted: Mon Aug 31, 2020 8:24 pm
by davydnorris
eriksl wrote:For example
Note that I2S_CLKM_DIV_NUM must be >5 for I2S data

I have proven this to be not true, with this divider smaller than 5 it still just works, so the I ask myself, where is the real information (by Espressif).

I found I had stability issues if I went below the values Espressif said so maybe it affects the higher rates

eriksl wrote:
The BITS may be 24bit (bit depth), 31bit (max value in register) or 32bit (value size returned from mic) depending on how it works


The format specifiers only have entries for 8, 16 and 24 bit samples. So I don't know how one is supposed 31 or 32 bit? Or do you mean 2 x 16 bits (two channels)?
#define WS_I2S_BITS 15 /* Sampling depth-16. Currently needs looking into as it's 4 bits max, which gives 31 bits max?? */

I think the FIFO only allow for one, two or three bytes entries, so that would boil down to 1(?) to 24 bits per sample per channel.


I2S is always returned as 64 bits in two 32 bit words, but I2S devices can be less and some do not pad the word with empty bits. This tells the ESP how to interpret the incoming stream and how to insert it into the buffer. When you choose 16/24 bits (there's no 8 because the minimum sampling depth is 16 as set by this value), that determines how many words the values can be stuffed into.

My comment in the code is because I was trying to work out what effect the WS_I2S_BITS value had on the clock rate - should I set it to 24 bits because that's my actual microphone bit depth, or 32 bits because that's what my mic returns the values as, or 31 because that's as high as you can go since it's only a 4 bit mask

What I do know is that setting it to something like 18 will also cause it to shift the bits returned depending on the values in the other registers that define MSB/LSB but I was struggling to work out what effect it had on the clock.

This is especially important as I could get closer to my desired rate by setting this to a value that was unrelated to my actual bit depth, but then the numbers coming back did weird things and I worked out they had been shifted so I lost depth.

eriksl wrote:
//Enable FIFO in i2s module
SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);

This is where it clearly shows that you copied the Espressif mp3 player example code ;) It has the same flaw. This line does NOT enable the FIFO, instead it DISABLES it (and enables SLC mode).


The comment was copied but yes you're correct

Re: I2S for generating waveforms for ledpixel devices

PostPosted: Wed Sep 02, 2020 12:50 pm
by eriksl
Ok, thanks for your information. Hopefully there are others that can add even more.

Re: I2S for generating waveforms for ledpixel devices

PostPosted: Wed Sep 02, 2020 7:30 pm
by davydnorris
I'll add more about what I know over time - this is a good thread to capture it. I think I got a lot of the I2S specific stuff worked out, but the SLC and DMA is still black magic to me.

I know that under the hood the I2S uses a FIFO - either directly like you do, or by hooking it up to the DMA subsystem, like I do. The FIFO is definitely 128 32bit words because that's the minimum DMA buffer block size you can set in the I2S - anything else blows up. And the DMA also needs a minimum of 3 blocks allocated or else it blows up. I have used more and that works.