esp-idf: I2S channel randomly reboots incorrectly (IDFGH-9799)
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
IDF VERSION : idf-5.0.1
Operating System used. Ubuntu 22.04.2 LTS
How did you build your project? VS Code IDE
Development Kit. Custom card with SOC ESP32-C3-WROOM
What is the expected behavior? No difference in microphone values after a reboot
What is the actual behavior? When i restart my ESP (reset_button, via a command to set “esp_restart” or by switching off the power supply), the i2s channel randomly reboots incorrectly generating values with an unexplained gain.
Steps to reproduce. On my card, there are two MEMS microphones ICS 43434 connected to the ESP32C3 via I2S.
The microphones work on 24 bits according to the Philips standard.
/**
* @brief I2S driver parameters
*
*/
#define I2S_NUM_PORT 0
#define I2S_NUM_CHANNELS 2 // Stereo (2) vs Mono (1) - here Stereo
#define I2S_SAMPLE_RATE 16000 // Hz - no more than 50kHz for the onboard microphones
#define I2S_SAMPLE_SIZE 4 // bytes per sample - Philips format: 24 bits extended to 32 bits
#define I2S_BUFFER_COUNT 2 // number of buffers (>= 2)
#define I2S_BUFFER_LEN 256 // samples per buffer (size is limited to 511 samples)
// next parameter is strictly bounded to 4096
#define I2S_DMA_BUFFER_SIZE I2S_BUFFER_LEN*I2S_NUM_CHANNELS*I2S_SAMPLE_SIZE
#define I2S_RECV_BUFFER_SIZE I2S_DMA_BUFFER_SIZE * I2S_BUFFER_COUNT/I2S_SAMPLE_SIZE + 64 //should be able to take all the data in all dma buffers,
/**
* @brief I2S hardware interface
*
*/
#define I2S_SCK_GPIO GPIO_NUM_0
#define I2S_SD_GPIO GPIO_NUM_1
#define I2S_WS_GPIO GPIO_NUM_2
/**
* @brief description of the i2s microphones and the i2s GPIO
*
*/
static void
i2s_driver_config(){
i2s_chan_config_t rx_chan_cfg = {
.id = I2S_NUM_0, /*!< I2S port id */
.role = I2S_ROLE_MASTER, /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
.dma_desc_num = I2S_BUFFER_COUNT, /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
.dma_frame_num = I2S_BUFFER_LEN, /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots,*/
.auto_clear = true
};
ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));
i2s_std_config_t i2s_std_config = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(I2S_SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT,I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = I2S_SCK_GPIO,
.ws = I2S_WS_GPIO,
.dout = I2S_GPIO_UNUSED,
.din = I2S_SD_GPIO,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
/* Initialize the channel */
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &i2s_std_config));
ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
}
I have many task in my projects, including an i2s read task to save sound signal in a buffer. The listening task receives samples encoded on 32 bit from microphone, but representing 24-bit signals left-shifted, the value of the sample is then shifted to right by 8 bits.
From ICS 43434 datasheet

/* listening task */
void
listening_task(void *arg){
ESP_LOGI("Listening task", "time since boot: %lld us", esp_timer_get_time());
uint32_t sub_sampling_count = 0;
uint32_t im;
forever: {
tstpt_1_toggle();
if (i2s_channel_read(rx_chan, i2s_read_buffer, I2S_DMA_BUFFER_SIZE , &listening.i2s_bytes_read, portMAX_DELAY)==ESP_OK){
im = listening.i2s_bytes_read/I2S_SAMPLE_SIZE;
for(int i=0; i < im; i+=2){
/*** mean of the left and right microphones sound ***/
listening.sound_prl_f32 = mic_raw2mPa((mic_decode(i2s_read_buffer[i]) + mic_decode(i2s_read_buffer[i+1]))/2);
}
}
} else {
vTaskDelay(listening.task_delay);
}
} goto forever;
}
static int32_t
mic_decode(int32_t raw){
return (int)(raw >> 8);
}
static float
mic_raw2mPa(int32_t raw){
return microphone.mpa_full_scale*(float)raw/microphone.binary_full_scale;
}
float
mic_mPa2dB(float mpa){
return microphone.ref_point_db + 20.0*log10(mpa/(float)microphone.ref_point_mpa);
}
After a start-up, the i2s sometimes initializes incorrectly and it’s totally random. If the initialization of the i2s went wrong the values received will always be with a gain as long as the ESP has not restarted. Depending to the versions of my project, this bug is more or less rare without any logic.
In calm conditions I should have values between 4 and 6 mPa ( above 47 dB) but sometimes with bad i2s init, I have values between 12 and 14 mPa (above 57dB).
I tried to add delays during the initialization phase, i tried to reduce and comment out a big part of my project but this bug persists. The problem also appears on other ESP32-C3.
I don’t know if the problem is with the i2s initialization or if I misread my values. This bug stay very strange for my.
I would like to know if there are any known problems with the initialization of i2s.
Thank you for you help.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 27
I flashed your code with twos ESP32C3 (slave and master) and it’s work well. I find the right values.
However, I tried to reproduce the I2S bug. So in the menuconfig I have disabled this MPI option, it’s probably not recommended, but it seems pretty good to reproduce the bad i2s initialization:
And randomly after reboot I get the following values:
edit: The value:
0158d148is exactly four times the original value:00563412Done