Page 1 of 1

Confusion between I2S slot width and bit width

Posted: Wed Jan 31, 2024 7:40 pm
by ImproperCatGirl
Basically as the title says. I'm using a PCM1808 I2S ADC in master mode with the ESP32 as the slave. The datasheet suggests that the ADC's slot width is 32bit ("The frequency of BCK is constant at 64 BCK/frame."), and its bit width is 24bit. I've checked it with my logic analyzer and the result agrees with the datasheet.

logic analyser result: https://imgur.com/a/p8ruCaL

However, when I set the i2s slot config to I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_24BIT, I2S_SLOT_MODE_STEREO) , I get nothing but garbled data. But when I set the data bit width to 32bit, it works without any issue, and the I2S read result is consistent with my logic analyzer's result.

So, why? Espressif's official documentation seems to indicate that data bit width is the width of the actual data, and can be less than the slot bit width. One would assume that, in my case, according to the image at https://docs.espressif.com/projects/esp ... ndard-mode , data_bit_width = 24, and slot_bit_width = 32.

My I2S configuration:
  1. i2s_std_config_t rx_std_cfg = {
  2.         .clk_cfg  ={
  3.             .sample_rate_hz = 48000,
  4.             .clk_src = I2S_CLK_SRC_DEFAULT,
  5.             .mclk_multiple = I2S_MCLK_MULTIPLE_384,
  6.         },
  7.         .slot_cfg =I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
  8.         .gpio_cfg = {
  9.             .mclk = I2S_GPIO_UNUSED,    // some codecs may require mclk signal, this example doesn't need it
  10.             .bclk = EXAMPLE_STD_BCLK_IO1,
  11.             .ws   = EXAMPLE_STD_WS_IO1,
  12.             .dout = I2S_GPIO_UNUSED,
  13.             .din  = EXAMPLE_STD_DIN_IO1,
  14.             .invert_flags = {
  15.                 .mclk_inv = false,
  16.                 .bclk_inv = false,
  17.                 .ws_inv   = false,
  18.             },
  19.         },
  20.     };

Re: Confusion between I2S slot width and bit width

Posted: Thu Feb 01, 2024 2:43 am
by ESP_Sprite
What does the data you write to the I2S peripheral look like? Specifically, there's this warning: "For 24-bit width, the buffer is supposed to use uint32_t (i.e., align with 4 bytes), and only the high 24 bits are valid while the low 8 bits are dropped."

Re: Confusion between I2S slot width and bit width

Posted: Thu Feb 01, 2024 2:57 am
by ImproperCatGirl
<r>1.I'm reading data from the ADC. The data looks exactly like what the logic analyzer shows (either 0xffff??00 or 0x0000??00) (?? is some random noise from the ADC when there is no input).<br/>
2. I am aware of this warning, and this is the code I'm using to actually read the data(the data type is int32_t since this ADC outputs signed data in 2's complement form):
<CODE><s>

Code: Select all

</s>static void i2s_example_read_task(void *args)
{
    int32_t *r_buf = (int32_t *)calloc(1, EXAMPLE_BUFF_SIZE);
    assert(r_buf); // Check if r_buf allocation success
    size_t r_bytes = 0;

    /* Enable the RX channel */
    ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));

    /* ATTENTION: The print and delay in the read task only for monitoring the data by human,
     * Normally there shouldn't be any delays to ensure a short polling time,
     * Otherwise the dma buffer will overflow and lead to the data lost */
    while (1) {
        /* Read i2s data */
        uint out_data = 0;
    
        if (i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000) == ESP_OK) {
        //printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes);
        for(uint i = 0; i < r_bytes/4; i++)
        {
            r_buf[i] >>= 8;
            printf("%ld\n", r_buf[i]);
            
        }
        // printf("%x %x %x %x %x %x %x %x\n\n",
        //        r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
        } else {
            printf("Read Task: i2s read failed\n");
        }
        
        printf("\n-------------------------------------------------------\n\n");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    free(r_buf);
    vTaskDelete(NULL);
}<e>
</e></CODE></r>