ESP32 I2S bug (LSB should be on the next BCLK)?

I am trying to generate sound (16bits@44.1kHz stereo) thru ESP32's I2S with external DAC (PCM5102) but the sound is dirty, for example, the sine wave that is fully-swung (-32768~+32767) is distorted.
In my investigation to I2S signals with logic analyzer, LSB of DOUT seems left-shifted by 1 BCLK.

Here is the captured image, in case of Lch should be 0x0001 and Rch should be 0x0002:

DOUT seems 1-bit left-shifted. Is it well-known issue on ESP32?
I am using Arduino 1.8.15, ESP32 board/platform is version 1.0.6.


uint16_t wave[2] ;
static const i2s_port_t i2s_num = I2S_NUM_0 ; 
static const i2s_pin_config_t pin_config = {
    .bck_io_num   = I2S_BCLK,
    .ws_io_num    = I2S_LRCK,
    .data_out_num = I2S_DOUT,
    .data_in_num  = I2S_PIN_NO_CHANGE
static const i2s_config_t i2s_config = {
    .mode                 = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate          = 44100,
    .bits_per_sample      = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format       = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_I2S_MSB,
    .intr_alloc_flags     = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count        = 4,
    .dma_buf_len          = 1024,
    .use_apll             = false,
    .tx_desc_auto_clear   = true
void setup() {
  i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
  i2s_set_pin(i2s_num, &pin_config);
  wave[0] = 0x0001 ; // Lch 
  wave[1] = 0x0002 ; // Rch 
void loop() {
  size_t written ;
  i2s_write(I2S_NUM_0, wave, sizeof(wave), &written, portMAX_DELAY) ;

Never used I2S for any project, but a little searching turned up this article which is in-depth enough to provide you some guidance, since it seems to be doing the same type of thing as you are attempting.

Best of luck!

Yes, that's exactly how I2S works. It allows the LRCLK to be used to initiate conversions and the first bit is available one BCLK later. There are variations without the one bit delay and many I2S chips have ways to configure this delay as 0 bits or 1 bits, but the 1 bit delay is "true" I2S.

Note the PCM5102 can handle I2S or LJ formats (LJ = left-justified, ie without the delay) this is configured using the FMT pin.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.