I am just getting stuck as to what's happening.

Below explains the functionality of each of the hardware and how they interact with each other to give you a better idea of the situation.



ESP32 (Master)

  • Uses I2S to send stereo audio samples to the STM32 (slave)
  • It samples stereo audio at 48kHz

STM32 (Slave)

  • Receives and sends stereo audio samples from the ESP32 (Master) and to the DAC (Slave)
  • It doe DSP on the stereo audio samples

PMODI2S2: DAC (Slave)

  • Receives and sends stereo audio samples from the STM32 (Slave) and to speakers

  • This is using no DSP (Unity IIR Filter)


enter image description here


In the code of the ESP32 the I2S timing are as follow

 i2s_config_t i2s_config = {

    .mode = I2S_MODE_MASTER | I2S_MODE_TX,                                  
    .sample_rate = 48000,
    .bits_per_sample = 24,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .dma_buf_count = 6,
    .dma_buf_len = 60,
    .intr_alloc_flags = 0,        
    .use_apll = true,                                        //Default interrupt priority
    .tx_desc_auto_clear = true                                              //Auto clear tx descriptor on underflow

So this essentially tells me the ESP32 is going to create a:

$$ SCLK = 2channel * 32bit * 48kHz = 3MHz$$

$$ MCLK = 256 * 48kHz = 12.28MHz$$


$$ MCLK = 384 * 48kHz = 18.4MHz$$

$$ LRCLK = 48kHz$$

that's fine, understood I2S standard, now in my STM32 code ill setup the I2S to match the timings of the ESP32 as such:

                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_WSINV_I2S;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_DATALEN_24BIT;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_FIXCH;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_CKPOL_FALL_RISE;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_I2SSTD_I2STAND;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_CHNEL_32BIT_WIDE;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_I2SCFG_SLAVE_FULLDUPLEX;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_I2SMOD_I2S_PCM_MODE;
                       SPI3 -> I2SCFGR |= SPI_I2SCFGR_DATFMT_LAlign;

This matches up with the ESP32 timings, so everything should work. as Datalength = 24bit channel length = 32bit and the rest of the I2S standard, MSB first, left align, etc

The DAC says in the datasheet it can autodetect timings listed here. enter image description here

enter image description here

Perfect, the DAC can support 256x and 384x ratios at 48kHz and a bit timing up to 24 bit on the SCLK.

HOWEVER, when I run the code and test, the audio sounds its skipping and audio sounds faster (Its high pitched and sounds fast forwarded like mickie mouse haha).


If I change the bits in the ESP32 to 16 bits, it works no problem, sounds good. I further tinkered with it and found out it doesn't matter what data length nor channel you have it at on the STM32 if the ESP32 bit is set at 16, it sounds normal with data length of 16/24/32 and a channel length = 16/32

Why's that? This is ruining my understanding, I thought the bits determine the SCLK frequency, so how does it make sense if I change my ESP32 bit to 16 to get a SCLK = 1.5MHz and in the STM32 I can have a SCLK of = 3MHz and still works?

I know the STM32 is a slave which is kinda confusing and doesnt generate these signals then whats the point of configuration the data length and channel length at all then?


When putting back my DSP filters I noticed that changing it to 16/24 data length now causes massive static like sound, and the only thing that fixed it was putting it to 32 data length

  • \$\begingroup\$ @ChrisStratton Uhhh, I never argued against anyone on here. Sure the questions may seem the same because it has to do with audio, and I2S, I can ensure you the topic for this is much different from the prior ones. Yeah that's not a bad idea to be honest. Any other ideas before I need to get a specific hardware? Like what does Data length mean vs Channel length \$\endgroup\$
    – Leoc
    Dec 3, 2020 at 20:37
  • \$\begingroup\$ It depends on specific STM32 how it's I2S peripheral works. You did not say which specific STM32. Also look at STM32 I2S peripheral know errata list, there can be combinations that are not supported. You can have 24-bits or 16 bits worth of data in a 32-bit channel or a 24-bit channel. Completely another thing is when 24-bits is received, if that is transferred as 32-bit item into memory with DMA. \$\endgroup\$
    – Justme
    Dec 3, 2020 at 20:41
  • \$\begingroup\$ @Justme AH sorry, I didn't make it obvious. If you click the link it will direct you to the MCU I am using from STM32. Ill change it however. Ill check the list now. That makes sense to have bits worth of data < then the channel length, but why is that when ESP32 timing for data worth is 24 and I change the STM32 to match it, everything sounds like mickie mouse. Just checked the list doesnt look like anything that would affect me here \$\endgroup\$
    – Leoc
    Dec 3, 2020 at 20:43

1 Answer 1


SBC audio codec for bluetooth only supports 16 bits.

  • 1
    \$\begingroup\$ Can you expand your answer? \$\endgroup\$
    – Voltage Spike
    Jan 20, 2022 at 5:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.