My IDF version is v3.3-beta2, but it requires hacking on the IDF a bit to expose the necessary functions (I have also tried this by manipulating the registers directly); I'll detail that below.
My issue is, no matter what I do, I see the ADC data with doubled up or skipped channels. I have code that extracts the channel from the ADC data that appears from an I2S read like this:
Code: Select all
static void show_some_data(uint16_t * data)
{
const unsigned rows = 8;
for (unsigned row = 0; row < rows; row++)
{
ESP_LOGI(
TAG,
"CH: %d %d %d %d %d %d %d %d",
(data[8*row + 0] & 0xF000) >> 12,
(data[8*row + 1] & 0xF000) >> 12,
(data[8*row + 2] & 0xF000) >> 12,
(data[8*row + 3] & 0xF000) >> 12,
(data[8*row + 4] & 0xF000) >> 12,
(data[8*row + 5] & 0xF000) >> 12,
(data[8*row + 6] & 0xF000) >> 12,
(data[8*row + 7] & 0xF000) >> 12
);
}
}
Code: Select all
I (324) I2S: PLL_D2: Req RATE: 24000, real rate: 1515.000, BITS: 16, CLKM: 55, BCK: 60, MCLK: 55.556, SCLK: 48480.000000, diva: 64, divb: 35
I (334) i2s-test: CH: 6 6 6 6 6 6 0 0
I (334) i2s-test: CH: 0 0 0 0 0 0 0 0
I (344) i2s-test: CH: 0 0 0 0 0 0 0 0
I (344) i2s-test: CH: 0 0 0 0 0 0 0 0
I (354) i2s-test: CH: 0 0 0 0 0 0 0 0
I (354) i2s-test: CH: 0 0 0 0 0 0 0 0
I (364) i2s-test: CH: 0 0 0 0 0 0 0 0
I (364) i2s-test: CH: 0 0 0 0 0 0 0 0
I (364) i2s-test: CH: 5 5 6 6 5 5 6 6
I (374) i2s-test: CH: 5 5 6 6 5 5 6 6
I (374) i2s-test: CH: 5 5 6 6 5 5 6 6
I (384) i2s-test: CH: 5 5 6 6 5 5 6 6
I (384) i2s-test: CH: 5 5 6 6 5 5 6 6
I (394) i2s-test: CH: 5 5 6 6 5 5 6 6
I (394) i2s-test: CH: 5 5 6 6 5 5 6 6
I (394) i2s-test: CH: 5 5 6 6 5 5 6 6
I (404) i2s-test: CH: 6 6 5 5 6 6 5 5
Code: Select all
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN,
.sample_rate = SAMPLE_RATE, // 24kHz
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.communication_format = I2S_COMM_FORMAT_I2S,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 2,
.dma_buf_len = NUM_SAMPLES, // 64
.use_apll = 0,
.fixed_mclk = 0
};
i2s_driver_install(i2s_num, &i2s_config, 4, i2s_queue);
i2s_set_clk(i2s_num, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO);
i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_6);
adc_set_i2s_data_pattern(ADC_UNIT_1, 0, ADC_CHANNEL_6, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11);
adc_set_i2s_data_pattern(ADC_UNIT_1, 1, ADC_CHANNEL_5, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11);
adc_set_i2s_data_len(ADC_UNIT_1, 2);
The full project, including build config, is on Gitlab. It can be built just by checking it out and doing "idf.py build".
I am totally unable to figure out what's wrong. I have checked through both my code and the IDF libs to make sure the registers are being set correctly. I have read the technical reference manual front to back. I've tried it with and without the queue, with and without the DMA clearing. I've used an oscilloscope to verify that the WS signal is indeed running at 24kHz (although that shouldn't affect the channel order).
It would be a huge help to me even just to have someone else try out my example project and tell me whether they see the same thing on their hardware. But if you can see a mistake that I've made here, or have any ideas for more debugging, please let me know.