You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
samples are being read but board crashes
This commit is contained in:
+72
-57
@@ -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 <errno.h> // 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user