Hi Gianluca,
thanks for your reply,
I tried several sampling rates from 3 kHz to 100 kHz but it didn't work for any of them.
I am using the esp-idf version 4.1.
Here is the code that I used. I reused quite a lot of Your code.
Code: Select all
#define TAG "I2S"
#define SAMPLE_RATE 5000
#define I2S_UNIT (0)
#define DMA_BUF_COUNT 4
#define DMA_BUF_LEN 1024
#define ADC_UNIT 1
#define ADC_CHANNEL 0
#define NUM_SAMPLES 1024
xQueueHandle adc_i2s_event_queue;
uint8_t adc_i2s_event_queue_size = 1;
// ...
i2s_event_t adc_i2s_evt;
static void adc_i2s_init(void)
{
esp_err_t ret = ESP_OK;
i2s_config_t adc_i2s_config =
{
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN,
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.intr_alloc_flags = 0,
.dma_buf_count = DMA_BUF_COUNT,
.dma_buf_len = DMA_BUF_LEN,
.use_apll = 1,//false,
.tx_desc_auto_clear = true
};
static const i2s_pin_config_t pin_config = {
.bck_io_num = 32, // Sample f(Hz) (= sample f * 2) on this pin (optional).
.ws_io_num = 33, // Left/Right (= sample f) on this pin (optional).
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_PIN_NO_CHANGE
};
//install and start i2s driver
ret = i2s_driver_install(I2S_UNIT, &adc_i2s_config, adc_i2s_event_queue_size , &adc_i2s_event_queue);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "i2s_driver_install operation error = %i", ret);
}
// Output sample clock & left/right signals to measure with oscilloscope (optional).
i2s_set_pin(I2S_UNIT, &pin_config);
//init ADC pad
ret = i2s_set_adc_mode(ADC_UNIT, ADC_CHANNEL);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "i2s_set_adc_mode_custom operation error = %i", ret);
}
vTaskDelay(2000);
}
static void adc_i2s_enable(void)
{
esp_err_t ret = ESP_OK;
ESP_ERROR_CHECK(i2s_zero_dma_buffer(I2S_UNIT));
ret = i2s_adc_enable(I2S_UNIT);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "i2s_adc_enable_custom operation error = %i", ret);
}
}
static void adc_i2s_disable(void)
{
i2s_adc_disable(I2S_UNIT);
}
static void adc_i2s_restore_sampling(void)
{
adc_i2s_disable();
vTaskDelay(100);
adc_power_on();
adc_i2s_init();
adc_i2s_enable();
}
#define I2S_MAX_CHANNELS 1
// Convert DMA 16bit (Chan 4b + ADC 12b) => 12bit, and print them in the same order each time.
void i2s_print_adc_data(uint8_t* s_buff, uint32_t len)
{
uint16_t dac_value[] = // Max 8 ADC1 input channels/pins.
{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
int chan = 0;
printf( "\tChan[n] : ADC raw\t");
for (int i = 0; i < len; i += (I2S_MAX_CHANNELS * 2)) {
for (int j = 0; j < (I2S_MAX_CHANNELS * 2); j += 2) {
chan = s_buff[i + j + 1] >> 4; // Cannel nbr is in bit 7:4.
dac_value[chan] = (((s_buff[i + j + 1] & 0x0F) << 8) | s_buff[i + j + 0 ]);
}
for (int j = 0; j < 8; j ++) {
if(dac_value[j] != 0xFFFF)
printf( "\t[%d] : %04x", j, dac_value[j]);
}
}
printf("\n\n");
}
static void adc_task(void *pvParameter)
{
esp_err_t ret = ESP_OK;
i2s_event_t adc_i2s_evt;
size_t bytes_read;
uint8_t* adc_data_buf = (uint8_t*) calloc(NUM_SAMPLES, sizeof(char));
adc_i2s_init();
vTaskDelay(5000 / portTICK_PERIOD_MS);
adc_i2s_enable();
while ( 1 )
{
if(xQueueReceive(adc_i2s_event_queue, (void * )&adc_i2s_evt, (portTickType)portMAX_DELAY))
{
if(adc_i2s_evt.type == I2S_EVENT_RX_DONE)
{
//vTaskDelay(3000 / portTICK_PERIOD_MS);
ret = i2s_read(I2S_UNIT, (char*)adc_data_buf, NUM_SAMPLES, &bytes_read, portMAX_DELAY);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "i2s_read operation error = %i", ret);
}
if(((adc_data_buf[0]) == 0) && ((adc_data_buf[1]) == 0) && ((adc_data_buf[2]) == 0))
{
printf("adc_data_buf[0] = %d adc_data_buf[1] = %d adc_data_buf[2] = %d\n",adc_data_buf[0],adc_data_buf[1],adc_data_buf[2]);
// If the adc reads zero values, it means it hasn't been started correctly. Restart it again to fix this problem.
adc_i2s_restore_sampling();
}
else
{
printf("adc_data_buf[0] = %d adc_data_buf[1] = %d adc_data_buf[2] = %d\n",adc_data_buf[0],adc_data_buf[1],adc_data_buf[2]);
ESP_LOGW(TAG, "RESTARTING");
vTaskDelay(1000);
// Restart is done to reproduce this problem
esp_restart();
}
}
}
}
adc_i2s_disable(); // Unreachable
}
esp_err_t app_main()
{
esp_log_level_set("I2S", ESP_LOG_INFO);
xTaskCreate( adc_task, "example_i2s_adc_dac", 4096, NULL, 5, NULL);
while(1)
{
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
return ESP_OK;
}