ESP32 I2S Read Timeout Problem
Posted: Sat Apr 20, 2024 10:08 pm
I'm using an ESP32-D0WD-V3 with esp-idf v5.1.2. I'm trying to communicate with a codec that is i2s master that is sending 64 bclks per wclk. The data is 16bits stereo and the sample rate is 16000hz. With the following configuration I am able to transmit data correctly but the read always times out. If I set data_bit_width=I2S_DATA_BIT_WIDTH_32BIT the reads are successful but this leads to incorrect tx data. I attached a logic analyzer trace showing the i2s transaction. What gives?
Code: Select all
i2s_chan_config_t chan_cfg = {
.id=I2S_NUM_AUTO, /*!< I2S port id */
.role = I2S_ROLE_SLAVE,//I2S_ROLE_MASTER, /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
/* DMA configurations */
.dma_desc_num = 2, /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
.dma_frame_num = 160, /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots,
* it should be the multiple of '3' when the data bit width is 24.
*/
.auto_clear = true, /*!< Set to auto clear DMA TX buffer, i2s will always send zero automatically if no data to send */
};
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan));
i2s_std_config_t std_cfg = {
.clk_cfg = {
.sample_rate_hz = 16000, /*!< I2S sample rate */
.clk_src = I2S_CLK_SRC_DEFAULT, /*!< Choose clock source */
.mclk_multiple = I2S_MCLK_MULTIPLE_384, //**Ignored in slave mode
},
// .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.slot_cfg = {
.data_bit_width = I2S_DATA_BIT_WIDTH_16BIT,
.slot_bit_width = I2S_SLOT_BIT_WIDTH_32BIT,
.slot_mode = I2S_SLOT_MODE_STEREO,
.slot_mask = I2S_STD_SLOT_BOTH,
.ws_width = I2S_DATA_BIT_WIDTH_32BIT,
.ws_pol = true,
.bit_shift = true,
.msb_right = true
},
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = params.bclk,
.ws = params.ws,
.dout = params.dout,
.din = params.din,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
/* Initialize the channels */
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg));