diff --git a/src/core/configPins.cpp b/src/core/configPins.cpp index af0139652..1f0e507be 100644 --- a/src/core/configPins.cpp +++ b/src/core/configPins.cpp @@ -113,6 +113,19 @@ void BruceConfigPins::fromJson(JsonObject obj) { log_e("Fail"); } + if (!root["micClk"].isNull()) { + micClk = root["micClk"].as(); + } else { + count++; + log_e("Fail"); + } + if (!root["micData"].isNull()) { + micData = root["micData"].as(); + } else { + count++; + log_e("Fail"); + } + if (!root["CC1101_Pins"].isNull()) { SPIPins def = CC1101_bus; CC1101_bus.fromJson(root["CC1101_Pins"].as()); @@ -213,6 +226,8 @@ void BruceConfigPins::toJson(JsonObject obj) const { root["rfidModule"] = rfidModule; root["gpsBaudrate"] = gpsBaudrate; root["iButton"] = iButton; + root["micClk"] = micClk; + root["micData"] = micData; JsonObject _CC1101 = root["CC1101_Pins"].to(); CC1101_bus.toJson(_CC1101); @@ -505,6 +520,16 @@ void BruceConfigPins::setiButtonPin(int value) { saveFile(); } else log_e("iButton: Gpio pin not set, incompatible with this device\n"); } +void BruceConfigPins::setMicClkPin(int value) { + micClk = value; + saveFile(); +} + +void BruceConfigPins::setMicDataPin(int value) { + micData = value; + saveFile(); +} + void BruceConfigPins::setGpsBaudrate(int value) { gpsBaudrate = value; validateGpsBaudrateValue(); diff --git a/src/core/configPins.h b/src/core/configPins.h index ed4c31678..932bd178c 100644 --- a/src/core/configPins.h +++ b/src/core/configPins.h @@ -200,6 +200,10 @@ class BruceConfigPins { // RFID int rfidModule = M5_RFID2_MODULE; + // Microphone + int micClk = PIN_CLK; + int micData = PIN_DATA; + // GPS int gpsBaudrate = 9600; @@ -258,6 +262,10 @@ class BruceConfigPins { // iButton void setiButtonPin(int value); + // Microphone + void setMicClkPin(int value); + void setMicDataPin(int value); + // RFID void setRfidModule(RFIDModules value); void validateRfidModuleValue(); diff --git a/src/core/menu_items/ConfigMenu.cpp b/src/core/menu_items/ConfigMenu.cpp index 2b606096f..9cd4b940f 100644 --- a/src/core/menu_items/ConfigMenu.cpp +++ b/src/core/menu_items/ConfigMenu.cpp @@ -271,6 +271,7 @@ void ConfigMenu::devMenu() { {"I2C Pins", [this]() { setI2CPinsMenu(bruceConfigPins.i2c_bus); } }, {"UART Pins", [this]() { setUARTPinsMenu(bruceConfigPins.uart_bus); } }, {"GPS Pins", [this]() { setUARTPinsMenu(bruceConfigPins.gps_bus); } }, + {"Mic Pins", [this]() { setMicPinsMenu(); } }, {"Serial USB", [this]() { switchToUSBSerial(); } }, {"Serial UART", [this]() { switchToUARTSerial(); } }, {"Disable DevMode", [this]() { bruceConfig.setDevMode(false); } }, diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 93dbf343b..be5709ecb 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -1585,6 +1585,50 @@ void setI2CPinsMenu(BruceConfigPins::I2CPins &value) { } } +/********************************************************************* +** Function: setMicPinsMenu +** Menu to change Microphone I2S pins (CLK + DATA) +**********************************************************************/ +void setMicPinsMenu() { + uint8_t opt = 0; + bool changed = false; + int clk = bruceConfigPins.micClk; + int data = bruceConfigPins.micData; + +RELOAD_MIC: + options = { + {String("CLK = " + String(clk)).c_str(), [&]() { opt = 1; }}, + {String("DATA = " + String(data)).c_str(), [&]() { opt = 2; }}, + {"Save Config", [&]() { opt = 7; }, changed}, + {"Main Menu", [&]() { opt = 0; }}, + }; + + loopOptions(options); + if (opt == 0) return; + else if (opt == 7) { + if (changed) { + bruceConfigPins.setMicClkPin(clk); + bruceConfigPins.setMicDataPin(data); + } + } else { + options = {}; + int sel = -1; + int index = 0; + if (opt == 1) index = clk + 1; + else if (opt == 2) index = data + 1; + for (int8_t i = -1; i <= GPIO_NUM_MAX; i++) { + String tmp = String(i); + options.push_back({tmp.c_str(), [i, &sel]() { sel = i; }}); + } + loopOptions(options, index); + options.clear(); + if (opt == 1) clk = sel; + else if (opt == 2) data = sel; + changed = true; + goto RELOAD_MIC; + } +} + /********************************************************************* ** Function: setTheme ** Menu to change Theme diff --git a/src/core/settings.h b/src/core/settings.h index f49bac2fd..acc859b90 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -101,6 +101,8 @@ void setUARTPinsMenu(BruceConfigPins::UARTPins &value); void setI2CPinsMenu(BruceConfigPins::I2CPins &value); +void setMicPinsMenu(); + void setTheme(); void setMacAddressMenu(); diff --git a/src/modules/others/mic.cpp b/src/modules/others/mic.cpp index a71b5b7c5..d006910c4 100644 --- a/src/modules/others/mic.cpp +++ b/src/modules/others/mic.cpp @@ -134,6 +134,11 @@ bool deinitMicroPhone() { bool InitI2SMicroPhone() { // Enable codec, if exists _setup_codec_mic(true); + + // Use runtime-configurable pins from brucePins.conf + int mic_clk = bruceConfigPins.micClk; + int mic_data = bruceConfigPins.micData; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); chan_cfg.dma_desc_num = 8; chan_cfg.dma_frame_num = SPECTRUM_HEIGHT; @@ -147,10 +152,10 @@ bool InitI2SMicroPhone() { .slot_cfg = slot_cfg, .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, - .bclk = (gpio_num_t)PIN_CLK, + .bclk = (gpio_num_t)mic_clk, .ws = (gpio_num_t)PIN_WS, .dout = I2S_GPIO_UNUSED, - .din = (gpio_num_t)PIN_DATA, + .din = (gpio_num_t)mic_data, .invert_flags = {.mclk_inv = false, .bclk_inv = false, .ws_inv = false}, }, }; @@ -158,7 +163,7 @@ bool InitI2SMicroPhone() { #else if (mic_bclk_pin != I2S_PIN_NO_CHANGE) { - gpio_num_t mic_ws_pin = (gpio_num_t)PIN_CLK; + gpio_num_t mic_ws_pin = (gpio_num_t)mic_clk; i2s_std_config_t i2s_config; memset(&i2s_config, 0, sizeof(i2s_std_config_t)); #if defined(CONFIG_IDF_TARGET_ESP32P4) @@ -185,7 +190,7 @@ bool InitI2SMicroPhone() { i2s_config.gpio_cfg.ws = (gpio_num_t)mic_ws_pin; i2s_config.gpio_cfg.dout = (gpio_num_t)I2S_PIN_NO_CHANGE; i2s_config.gpio_cfg.mclk = (gpio_num_t)I2S_PIN_NO_CHANGE; - i2s_config.gpio_cfg.din = (gpio_num_t)PIN_DATA; + i2s_config.gpio_cfg.din = (gpio_num_t)mic_data; err = i2s_channel_init_std_mode(i2s_chan, &i2s_config); } else { @@ -197,8 +202,8 @@ bool InitI2SMicroPhone() { .clk_cfg = clk_cfg, .slot_cfg = slot_cfg, .gpio_cfg = { - .clk = (gpio_num_t)PIN_CLK, - .din = (gpio_num_t)PIN_DATA, + .clk = (gpio_num_t)mic_clk, + .din = (gpio_num_t)mic_data, .invert_flags = {.clk_inv = false}, }, }; @@ -1006,10 +1011,10 @@ bool mic_capture_samples( .slot_cfg = slot_cfg, .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, - .bclk = (gpio_num_t)PIN_CLK, + .bclk = (gpio_num_t)bruceConfigPins.micClk, .ws = (gpio_num_t)PIN_WS, .dout = I2S_GPIO_UNUSED, - .din = (gpio_num_t)PIN_DATA, + .din = (gpio_num_t)bruceConfigPins.micData, .invert_flags = {.mclk_inv = false, .bclk_inv = false, .ws_inv = false}, }, }; @@ -1017,7 +1022,7 @@ bool mic_capture_samples( #else if (mic_bclk_pin != I2S_PIN_NO_CHANGE) { // Standard I2S mode - gpio_num_t mic_ws_pin = (gpio_num_t)PIN_CLK; + gpio_num_t mic_ws_pin = (gpio_num_t)bruceConfigPins.micClk; i2s_std_config_t i2s_config; memset(&i2s_config, 0, sizeof(i2s_std_config_t)); #if defined(CONFIG_IDF_TARGET_ESP32P4) @@ -1044,7 +1049,7 @@ bool mic_capture_samples( i2s_config.gpio_cfg.ws = (gpio_num_t)mic_ws_pin; i2s_config.gpio_cfg.dout = (gpio_num_t)I2S_PIN_NO_CHANGE; i2s_config.gpio_cfg.mclk = (gpio_num_t)I2S_PIN_NO_CHANGE; - i2s_config.gpio_cfg.din = (gpio_num_t)PIN_DATA; + i2s_config.gpio_cfg.din = (gpio_num_t)bruceConfigPins.micData; err = i2s_channel_init_std_mode(temp_i2s_chan, &i2s_config); } else { // PDM mode @@ -1057,8 +1062,8 @@ bool mic_capture_samples( .clk_cfg = clk_cfg, .slot_cfg = slot_cfg, .gpio_cfg = { - .clk = (gpio_num_t)PIN_CLK, - .din = (gpio_num_t)PIN_DATA, + .clk = (gpio_num_t)bruceConfigPins.micClk, + .din = (gpio_num_t)bruceConfigPins.micData, .invert_flags = {.clk_inv = false}, }, };