From 887e24dac342b795275b9d3b910132d39e036afa Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Thu, 12 Feb 2026 22:01:40 +0100 Subject: [PATCH] samples are being read but board crashes --- c_mpos/src/adc_mic.c | 129 ++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 57 deletions(-) diff --git a/c_mpos/src/adc_mic.c b/c_mpos/src/adc_mic.c index 6aa4059e..e5beba92 100644 --- a/c_mpos/src/adc_mic.c +++ b/c_mpos/src/adc_mic.c @@ -6,6 +6,9 @@ #include "adc_mic.h" // Include for audio_codec_adc_cfg_t, audio_codec_new_adc_data, etc. #include "sdkconfig.h" // for CONFIG_ADC_MIC_TASK_CORE #include // For ENOMEM +#include "esp_task_wdt.h" // watchdog +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" // to add a delay #define ADC_MIC_DEBUG_PRINT(...) mp_printf(&mp_plat_print, __VA_ARGS__) @@ -13,8 +16,7 @@ static mp_obj_t adc_mic_read(void) { ADC_MIC_DEBUG_PRINT("Starting adc_mic_read...\n"); ADC_MIC_DEBUG_PRINT("CONFIG_ADC_MIC_TASK_CORE: %d\n", CONFIG_ADC_MIC_TASK_CORE); - // Configure for mono ADC on GPIO1 (ADC1_CHANNEL_0) at 16kHz - //audio_codec_adc_cfg_t cfg = DEFAULT_AUDIO_CODEC_ADC_MONO_CFG(ADC_CHANNEL_0, 16000); + // Configuration (your current manual setup with 2.5 dB atten) audio_codec_adc_cfg_t cfg = { .handle = NULL, .max_store_buf_size = 1024 * 2, @@ -23,108 +25,121 @@ static mp_obj_t adc_mic_read(void) { .adc_channel_list = ((uint8_t[]){ADC_CHANNEL_0}), .adc_channel_num = 1, .sample_rate_hz = 16000, - //.atten = ADC_ATTEN_DB_0, // ← try 0 dB first (0–1.1 V range, higher gain) - .atten = ADC_ATTEN_DB_2_5, // ← try 0 dB first (0–1.1 V range, higher gain) - // or ADC_ATTEN_DB_2_5 for ~0–1.5 V - // keep other fields as default or explicit + //.atten = ADC_ATTEN_DB_2_5, + .atten = ADC_ATTEN_DB_11, }; - ADC_MIC_DEBUG_PRINT("Config created for channel %d, sample rate %d\n", ADC_CHANNEL_0, 16000); + ADC_MIC_DEBUG_PRINT("Config created for channel %d, sample rate %d, atten %d\n", + ADC_CHANNEL_0, 16000, cfg.atten); - ADC_MIC_DEBUG_PRINT("Creating ADC data interface...\n"); + // ──────────────────────────────────────────────── + // Initialization (same as before) + // ──────────────────────────────────────────────── const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg); if (adc_if == NULL) { ADC_MIC_DEBUG_PRINT("Failed to initialize ADC data interface\n"); - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to initialize ADC data interface")); + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to init ADC interface")); } - ADC_MIC_DEBUG_PRINT("ADC data interface created successfully\n"); - // Create codec device for input esp_codec_dev_cfg_t codec_dev_cfg = { .dev_type = ESP_CODEC_DEV_TYPE_IN, .data_if = adc_if, }; - ADC_MIC_DEBUG_PRINT("Creating codec device...\n"); esp_codec_dev_handle_t dev = esp_codec_dev_new(&codec_dev_cfg); if (dev == NULL) { - ADC_MIC_DEBUG_PRINT("Failed to create codec device\n"); audio_codec_delete_data_if(adc_if); - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to create codec device")); + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to create codec dev")); } - ADC_MIC_DEBUG_PRINT("Codec device created successfully\n"); - // Set sample info: 16kHz, mono, 16-bit esp_codec_dev_sample_info_t fs = { .sample_rate = 16000, .channel = 1, .bits_per_sample = 16, }; - ADC_MIC_DEBUG_PRINT("Opening codec device with sample rate %d, channels %d, bits %d...\n", fs.sample_rate, fs.channel, fs.bits_per_sample); esp_err_t open_ret = esp_codec_dev_open(dev, &fs); if (open_ret != ESP_OK) { - ADC_MIC_DEBUG_PRINT("Failed to open codec device: error %d\n", open_ret); esp_codec_dev_delete(dev); audio_codec_delete_data_if(adc_if); - mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to open codec device: %d"), open_ret); + mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("esp_codec_dev_open failed: %d"), open_ret); } - ADC_MIC_DEBUG_PRINT("Codec device opened successfully\n"); - // Allocate buffer for 16000 samples (16-bit, so 32000 bytes) - //const size_t buf_size = 16000 * sizeof(int16_t); - const size_t buf_size = 64 * sizeof(int16_t); - ADC_MIC_DEBUG_PRINT("Allocating buffer of size %zu bytes...\n", buf_size); - int16_t *audio_buffer = (int16_t *)heap_caps_malloc(buf_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + // ──────────────────────────────────────────────── + // Small reusable buffer + tracking variables + // ──────────────────────────────────────────────── + const size_t chunk_samples = 64; + const size_t buf_size = chunk_samples * sizeof(int16_t); + //int16_t *audio_buffer = heap_caps_malloc(buf_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + int16_t *audio_buffer = heap_caps_malloc_prefer(buf_size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT); if (audio_buffer == NULL) { - ADC_MIC_DEBUG_PRINT("Failed to allocate buffer\n"); esp_codec_dev_close(dev); esp_codec_dev_delete(dev); audio_codec_delete_data_if(adc_if); mp_raise_OSError(ENOMEM); } - ADC_MIC_DEBUG_PRINT("Buffer allocated successfully\n"); - // Read the data (blocking until buffer is filled) - ADC_MIC_DEBUG_PRINT("Starting esp_codec_dev_read for %zu bytes...\n", buf_size); - int ret = esp_codec_dev_read(dev, audio_buffer, buf_size); - ADC_MIC_DEBUG_PRINT("esp_codec_dev_read completed, returned %d\n", ret); - if (ret < 0) { - ADC_MIC_DEBUG_PRINT("Failed to read audio data: %d\n", ret); - heap_caps_free(audio_buffer); - esp_codec_dev_close(dev); - esp_codec_dev_delete(dev); - audio_codec_delete_data_if(adc_if); - mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to read audio data: %d"), ret); - } + // How many chunks to read (adjust as needed) + const int N = 10; // e.g. 50 × 64 = 3200 samples (~0.2 seconds @ 16 kHz) - // Create MicroPython bytes object from the buffer - ADC_MIC_DEBUG_PRINT("Creating bytes object from buffer...\n"); - mp_obj_t buf_obj; - if (ret >= 0) { - ADC_MIC_DEBUG_PRINT("Creating full bytes object from buffer...\n"); - buf_obj = mp_obj_new_bytes((const byte *)audio_buffer, buf_size); + int16_t global_min = 32767; + int16_t global_max = -32768; - ADC_MIC_DEBUG_PRINT("First 16 samples:\n"); - size_t samples_to_print = 16; - for (size_t i = 0; i < samples_to_print; i++) { - int16_t sample = audio_buffer[i]; - ADC_MIC_DEBUG_PRINT("%4d (0x%04X) ", sample, (uint16_t)sample); - if ((i + 1) % 4 == 0) ADC_MIC_DEBUG_PRINT("\n"); + ADC_MIC_DEBUG_PRINT("Reading %d chunks of %zu samples each (total %d samples)...\n", + N, chunk_samples, N * chunk_samples); + + mp_obj_t last_buf_obj = mp_const_none; + + for (int chunk = 0; chunk < N; chunk++) { + esp_task_wdt_reset(); // "I'm alive" + int ret = esp_codec_dev_read(dev, audio_buffer, buf_size); + if (ret < 0) { + ADC_MIC_DEBUG_PRINT("Read failed at chunk %d: %d\n", chunk, ret); + break; } - ADC_MIC_DEBUG_PRINT("\n"); + vTaskDelay(pdMS_TO_TICKS(1)); // 1 ms yield + //if (ret != (int)buf_size) { + // ADC_MIC_DEBUG_PRINT("Partial read at chunk %d: got %d bytes (expected %zu)\n", + // chunk, ret, buf_size); + //} - } else { - ADC_MIC_DEBUG_PRINT("Creating empty bytes object from buffer...\n"); - buf_obj = mp_obj_new_bytes((const byte *)audio_buffer, 0); + // Update global min/max + for (size_t i = 0; i < chunk_samples; i++) { + int16_t s = audio_buffer[i]; + if (s < global_min) global_min = s; + if (s > global_max) global_max = s; + } + + // Optional: print first few chunks for debug (comment out after testing) + if (chunk < 3) { + ADC_MIC_DEBUG_PRINT("Chunk %d first 16 samples:\n", chunk); + for (size_t i = 0; i < 16; i++) { + ADC_MIC_DEBUG_PRINT("%6d ", audio_buffer[i]); + if ((i + 1) % 8 == 0) ADC_MIC_DEBUG_PRINT("\n"); + } + ADC_MIC_DEBUG_PRINT("\n"); + } + + // Keep only the last chunk to return + if (chunk == N - 1) { + last_buf_obj = mp_obj_new_bytes((const byte *)audio_buffer, buf_size); + } } + // ──────────────────────────────────────────────── + // Report results + // ──────────────────────────────────────────────── + ADC_MIC_DEBUG_PRINT("\nAfter %d chunks:\n", N); + ADC_MIC_DEBUG_PRINT("Global min: %d\n", global_min); + ADC_MIC_DEBUG_PRINT("Global max: %d\n", global_max); + ADC_MIC_DEBUG_PRINT("Range: %d\n", global_max - global_min); + // Cleanup - ADC_MIC_DEBUG_PRINT("Cleaning up...\n"); heap_caps_free(audio_buffer); esp_codec_dev_close(dev); esp_codec_dev_delete(dev); audio_codec_delete_data_if(adc_if); ADC_MIC_DEBUG_PRINT("adc_mic_read completed\n"); - return buf_obj; + + return last_buf_obj ? last_buf_obj : mp_obj_new_bytes(NULL, 0); } MP_DEFINE_CONST_FUN_OBJ_0(adc_mic_read_obj, adc_mic_read);