diff --git a/components/hal_i2s/hal_i2s.c b/components/hal_i2s/hal_i2s.c index 67abc31..ea26949 100644 --- a/components/hal_i2s/hal_i2s.c +++ b/components/hal_i2s/hal_i2s.c @@ -9,6 +9,9 @@ #include "driver/gpio.h" #include "driver/i2s_std.h" #include "esp_log.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include #define TAG "hal_i2s" @@ -18,6 +21,10 @@ static i2s_chan_handle_t s_spk_handle = NULL; static i2s_chan_handle_t s_mic_handle = NULL; +#define HAL_I2S_CAP_FRAME_SAMPLES 320 +#define HAL_I2S_CAP_IN_BYTES (HAL_I2S_CAP_FRAME_SAMPLES * 2 * (int)sizeof(int16_t)) +static int16_t *s_rx_scratch = NULL; + void hal_audio_pa_set(bool enable) { gpio_set_level(PLIP_PA_ENABLE, enable ? 1 : 0); @@ -95,3 +102,44 @@ esp_err_t hal_i2s_init(void) } return ESP_OK; } + +esp_err_t hal_i2s_capture_begin(void) +{ + if (!s_mic_handle) { + ESP_LOGE(TAG, "capture_begin: pas de canal RX"); + return ESP_ERR_INVALID_STATE; + } + if (s_rx_scratch) return ESP_OK; /* idempotent */ + s_rx_scratch = heap_caps_malloc(HAL_I2S_CAP_IN_BYTES, MALLOC_CAP_SPIRAM); + if (!s_rx_scratch) s_rx_scratch = malloc(HAL_I2S_CAP_IN_BYTES); + if (!s_rx_scratch) return ESP_ERR_NO_MEM; + ESP_LOGI(TAG, "capture_begin: pret (full-duplex, TX actif)"); + return ESP_OK; +} + +int hal_i2s_capture_read_frame(int16_t *mono_out, int n_samples, int64_t *rms_sq_out) +{ + if (!s_rx_scratch || !s_mic_handle) return -1; + size_t bytes_read = 0; + esp_err_t ret = i2s_channel_read(s_mic_handle, s_rx_scratch, + HAL_I2S_CAP_IN_BYTES, &bytes_read, + pdMS_TO_TICKS(100)); + if (ret != ESP_OK || bytes_read == 0) return 0; /* timeout */ + int n = (int)(bytes_read / (2 * sizeof(int16_t))); + if (n > n_samples) n = n_samples; + int64_t rms_sq = 0; + for (int i = 0; i < n; i++) { + int32_t l = s_rx_scratch[i * 2]; + int32_t r = s_rx_scratch[i * 2 + 1]; + int16_t mono = (int16_t)((l + r) / 2); + mono_out[i] = mono; + rms_sq += (int64_t)mono * mono; + } + if (rms_sq_out) *rms_sq_out = (n > 0) ? rms_sq / n : 0; + return n; +} + +void hal_i2s_capture_end(void) +{ + if (s_rx_scratch) { free(s_rx_scratch); s_rx_scratch = NULL; } +} diff --git a/components/hal_i2s/include/hal_i2s.h b/components/hal_i2s/include/hal_i2s.h index 87a6554..69a6ba2 100644 --- a/components/hal_i2s/include/hal_i2s.h +++ b/components/hal_i2s/include/hal_i2s.h @@ -21,6 +21,12 @@ i2s_chan_handle_t hal_i2s_mic_handle(void); /* Enable/disable the speaker power amplifier (GPIO21, active HIGH). */ void hal_audio_pa_set(bool enable); +/* Microphone capture (RX). capture_begin allocates a scratch buffer; read_frame + * reads one 20 ms frame, downmixes L+R to mono, and reports mean energy. */ +esp_err_t hal_i2s_capture_begin(void); +int hal_i2s_capture_read_frame(int16_t *mono_out, int n_samples, int64_t *rms_sq_out); +void hal_i2s_capture_end(void); + #ifdef __cplusplus } #endif diff --git a/main/app_main.c b/main/app_main.c index 9bfac41..abfd4de 100644 --- a/main/app_main.c +++ b/main/app_main.c @@ -17,14 +17,19 @@ void app_main(void) * avec la tache tone (i2s_channel_write qui tourne en parallele). */ ESP_ERROR_CHECK(slic_init()); audio_router_init(); - audio_router_dialtone_start(); - ESP_LOGI(TAG, "tonalite de numerotation demarree (combine decroche pour ecouter)"); - /* Sonde temporaire de polarite hook (a retirer en Task 6). */ + /* Sonde RMS micro (valide chemin LIN2/RIN2) — a retirer en Task 6. */ + ESP_ERROR_CHECK(hal_i2s_capture_begin()); + int16_t cap[320]; for (int i = 0; i < 20; i++) { - ESP_LOGI(TAG, "HOOK sonde: offhook=%d (niveau brut SHK)", (int)slic_is_offhook()); + int64_t rms_sq = 0; + int got = hal_i2s_capture_read_frame(cap, 320, &rms_sq); + ESP_LOGI(TAG, "MIC sonde: offhook=%d frame=%d rms_sq=%lld", + (int)slic_is_offhook(), got, (long long)rms_sq); vTaskDelay(pdMS_TO_TICKS(500)); } - ESP_LOGI(TAG, "boot OK — Phase 3 Task 1 SLIC KS0835"); + audio_router_dialtone_start(); + ESP_LOGI(TAG, "tonalite de numerotation demarree (combine decroche pour ecouter)"); + ESP_LOGI(TAG, "boot OK — Phase 3 Task 2 capture micro hal_i2s"); while (true) { ESP_LOGI(TAG, "heartbeat"); vTaskDelay(pdMS_TO_TICKS(5000));