Page 1 of 1

ESP32 输出的 I2S 数据移位

Posted: Wed Aug 10, 2022 10:19 am
by alee163
ESP32 PICO D4
ESP-IDF 4.3-rc

我在 ESP32 中使用 i2s 向 codec 芯片推送数据的时候,用逻辑分析仪抓 esp32 输出的数据,再对比标准 i2s 协议,发现存在一些差异。

在 ESP32 中配置 i2s ,16 bit 双声道,对齐方式为标准 i2s,重复输出字节 1-9 。

Code: Select all

i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX),
    .sample_rate = 8000,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
    .dma_buf_count = 2,
    .dma_buf_len = 1024,
    .use_apll = true,
    .tx_desc_auto_clear = true,
    .fixed_mclk = 0
};

i2s_pin_config_t pin_config = {
    .bck_io_num = 4,
    .ws_io_num = 26,
    .data_out_num = 33,
    .data_in_num = -1                                                       //Not used
};
i2s_driver_install(i2s, &i2s_config, 0, NULL);
i2s_set_pin(i2s, &pin_config);



uint8_t simples [1024] ;
for(int i=0; i<sizeof(simples); i++) {
    simples[i] = (i%9) + 1 ;
}

size_t cnt = 0 ;
i2s_write(I2S_NUM_0, simples, sizeof(simples), &cnt, 1000 / portTICK_PERIOD_MS);
    

用逻辑分析抓到的波形如下:
Clip_20220810_175611.png
Clip_20220810_175611.png (35.46 KiB) Viewed 2023 times
疑问1:
SDATA 上的数据相比 BCLK 和 LRSLK ,整体偏移了1位 (图中箭头所指)

标准 i2s 协议时序如下:
Clip_20220810_180659.png
Clip_20220810_180659.png (30.42 KiB) Viewed 2023 times
应该是每个 sample 都从第二位开始输出 SDATA ,所以 16bit的 sample, 实际上需要 17个 BCLK ,并且 L/R sample 都需要位移1bit。

疑问2:
缓冲区里的字节为 1-9 重复: 1,2,3,4,5,6,7,8,9,1,2,3 ...
I2S 配置为 I2S_BITS_PER_SAMPLE_16BIT , i2s使用 大端字节顺序,所以输出的字节顺序应该是: 2,1,4,3,6,5,8,7,1,9,3,2 ....

但 ESP32 SDATA 上输出的字节顺序是: 4,3,2,1, 8,7,6,5, 3, 2, 1, 9 ....
这是把缓冲区里的数据当成 32bit 数据来处理了。


以上两个问题,是我的 i2s 配置不对,还是我对 i2s 的理解有误?