Writing ADC continuous stream to I2S

jdoei2s
Posts: 2
Joined: Thu Jan 02, 2025 9:23 pm

Writing ADC continuous stream to I2S

Postby jdoei2s » Thu Jan 02, 2025 9:25 pm

Hello,
I'm trying to read an analog microphone and put the sound through I2S, with an ESP32 WROOM-32
I'm able to make both work separately, but not together.
My code is:
```
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "driver/i2s_std.h"
#include "esp_adc/adc_continuous.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"

adc_continuous_handle_t handle = NULL;
i2s_chan_handle_t tx_chan = NULL;

#define SAMPLE_RATE 16000
#define BUFFER_SIZE 160

static TaskHandle_t mic_task = NULL;

static bool IRAM_ATTR on_microphone_data_ready(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data) {
BaseType_t mustYield = pdFALSE;
vTaskNotifyGiveFromISR(mic_task, &mustYield);
return (mustYield == pdTRUE);
}

void init_microphone() {
adc_continuous_handle_cfg_t adc_config = {
.max_store_buf_size = 1024,
.conv_frame_size = BUFFER_SIZE,
};

ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle));

adc_continuous_config_t dig_cfg = {
.sample_freq_hz = 20000,
.conv_mode = ADC_CONV_SINGLE_UNIT_1,
.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2,
.pattern_num = 1,
};

adc_digi_pattern_config_t adc_pattern = {
.atten = ADC_ATTEN_DB_11,
.channel = ADC_CHANNEL_0,
.unit = ADC_UNIT_2,
.bit_width = ADC_BITWIDTH_12,
};

dig_cfg.adc_pattern = &adc_pattern;

ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg));

adc_continuous_evt_cbs_t cbs = {
.on_conv_done = on_microphone_data_ready,
};
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL));
ESP_ERROR_CHECK(adc_continuous_start(handle));
}

void init_speaker() {
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
chan_cfg.auto_clear = true;
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = 26,
.ws = 25,
.dout = 22,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};

ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
}

void app_main(void) {
init_speaker();
init_microphone();
// ...
}
```
Which outpus:
```
E (293) adc_share_hw_ctrl: adc_apb_periph_free called, but `s_adc_digi_ctrlr_cnt == 0`

abort() was called at PC 0x400d9dab on core 0
--- 0x400d9dab: adc_apb_periph_free at /esp/esp-idf/components/esp_hw_support/adc_share_hw_ctrl.c:234
```

Am I missing something obvious here ? Like DAC not being able to work together with I2S ? Or maybe DMA config incorrect and both trying to access the same DMA resources ? I'm new to ESP32.

Thanks a lot for your help !

Full trace:
```
I (29) boot: ESP-IDF v5.5-dev-847-gcb3ac7429c 2nd stage bootloader
I (29) boot: compile time Jan 2 2025 17:03:17
I (29) boot: Multicore bootloader
I (32) boot: chip revision: v1.0
I (35) boot.esp32: SPI Speed : 40MHz
I (38) boot.esp32: SPI Mode : DIO
I (42) boot.esp32: SPI Flash Size : 2MB
I (46) boot: Enabling RNG early entropy source...
I (50) boot: Partition Table:
I (53) boot: ## Label Usage Type ST Offset Length
I (59) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (66) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (72) boot: 2 factory factory app 00 00 00010000 00177000
I (79) boot: End of partition table
I (82) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0a138h ( 41272) map
I (103) esp_image: segment 1: paddr=0001a160 vaddr=3ff80000 size=0001ch ( 28) load
I (104) esp_image: segment 2: paddr=0001a184 vaddr=3ffb0000 size=0227ch ( 8828) load
I (111) esp_image: segment 3: paddr=0001c408 vaddr=40080000 size=03c10h ( 15376) load
I (121) esp_image: segment 4: paddr=00020020 vaddr=400d0020 size=15358h ( 86872) map
I (152) esp_image: segment 5: paddr=00035380 vaddr=40083c10 size=0a56ch ( 42348) load
I (176) boot: Loaded app from partition at offset 0x10000
I (176) boot: Disabling RNG early entropy source...
I (186) cpu_start: Multicore app
I (194) cpu_start: Pro cpu start user code
I (194) cpu_start: cpu freq: 160000000 Hz
I (195) app_init: Application information:
I (195) app_init: Project name: project
I (200) app_init: App version: b12afb3-dirty
I (204) app_init: Compile time: Jan 2 2025 17:24:00
I (209) app_init: ELF file SHA256: 6901b825a...
I (213) app_init: ESP-IDF: v5.5-dev-847-gcb3ac7429c
I (219) efuse_init: Min chip rev: v0.0
I (223) efuse_init: Max chip rev: v3.99
I (227) efuse_init: Chip rev: v1.0
I (231) heap_init: Initializing. RAM available for dynamic allocation:
I (237) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (242) heap_init: At 3FFB2B08 len 0002D4F8 (181 KiB): DRAM
I (247) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (253) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (258) heap_init: At 4008E17C len 00011E84 (71 KiB): IRAM
I (264) spi_flash: detected chip: generic
I (267) spi_flash: flash io: dio
W (270) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (283) main_task: Started on CPU0
I (293) main_task: Calling app_main()
W (293) i2s_platform: i2s controller 0 has been occupied by i2s_driver
E (293) adc_share_hw_ctrl: adc_apb_periph_free called, but `s_adc_digi_ctrlr_cnt == 0`

abort() was called at PC 0x400d9dab on core 0
--- 0x400d9dab: adc_apb_periph_free at /esp/esp-idf/components/esp_hw_support/adc_share_hw_ctrl.c:234



Backtrace: 0x40081b11:0x3ffb3c50 0x400869bd:0x3ffb3c70 0x4008c8ed:0x3ffb3c90 0x400d9dab:0x3ffb3d00 0x400d4300:0x3ffb3d20 0x400d443e:0x3ffb3d50 0x400d3fae:0x3ffb3d90 0x400d40ca:0x3ffb3de0 0x400e4bf0:0x3ffb3e00 0x4008733d:0x3ffb3e30
--- 0x40081b11: panic_abort at /esp/esp-idf/components/esp_system/panic.c:454
0x400869bd: esp_system_abort at /esp/esp-idf/components/esp_system/port/esp_system_chip.c:92
0x4008c8ed: abort at /esp/esp-idf/components/newlib/src/abort.c:38
0x400d9dab: adc_apb_periph_free at /esp/esp-idf/components/esp_hw_support/adc_share_hw_ctrl.c:234
0x400d4300: adc_continuous_deinit at /esp/esp-idf/components/esp_adc/adc_continuous.c:436
0x400d443e: adc_continuous_new_handle at /esp/esp-idf/components/esp_adc/adc_continuous.c:249
0x400d3fae: init_microphone at /project/main/main.c:34
0x400d40ca: app_main at /project/main/main.c:88
0x400e4bf0: main_task at /esp/esp-idf/components/freertos/app_startup.c:208
0x4008733d: vPortTaskWrapper at /esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
```

Who is online

Users browsing this forum: No registered users and 98 guests