diff --git a/audio_reactive.h b/audio_reactive.h index c31a14e6..1ecd9138 100644 --- a/audio_reactive.h +++ b/audio_reactive.h @@ -14,23 +14,9 @@ #ifdef ARDUINO_ARCH_ESP32 - // backwards compatibility hacks for esp-idf v3 + // backwards compatibility for esp-idf v3 has been removed #if (ESP_IDF_VERSION_MAJOR < 4) && defined(CONFIG_IDF_TARGET_ESP32) && !defined(SOC_CPU_HAS_FPU) - #if !defined(SOC_CPU_HAS_FPU) - #define SOC_CPU_HAS_FPU 1 - #endif - #if !defined(SOC_CPU_CORES_NUM) - #define SOC_CPU_CORES_NUM 2 - #endif - #if !defined(SOC_I2S_SUPPORTS_ADC) - #define SOC_I2S_SUPPORTS_ADC 1 - #endif - #if !defined(SOC_I2S_SUPPORTS_PDM_RX) - #define SOC_I2S_SUPPORTS_PDM_RX 1 - #endif - #if !defined(SOC_I2S_NUM) - #define SOC_I2S_NUM 2 - #endif + #error "audioreactive V2 requires esp-idf 4.4.x or later" #endif #include @@ -38,8 +24,8 @@ #include #endif - // AI: below section was generated by an AI - #if defined(CONFIG_IDF_TARGET_ESP32) && (ESP_IDF_VERSION_MAJOR >= 5) +// AI: below section was generated by an AI +#if defined(CONFIG_IDF_TARGET_ESP32) && (ESP_IDF_VERSION_MAJOR >= 5) /* * Bootloop workaround for classic ESP32 on esp-idf 5.x (WLED version 17.x): * AR still uses the legacy I2S driver (driver/i2s.h) which pulls in the legacy ADC driver. @@ -52,7 +38,7 @@ * so these paths are never executed; digital I2S/PDM mics don't use them. * Delete this block once the usermod is ported to the new I2S driver (driver/i2s_std.h). */ - #include + #include // Stub: would configure the (removed) I2S built-in ADC mode. Never called for digital mics. extern "C" esp_err_t adc_i2s_mode_init(int adcUnit, int channel) { @@ -73,7 +59,7 @@ extern "C" esp_err_t adc1_dma_mode_acquire(void) { extern "C" esp_err_t adc1_lock_release(void) { return ESP_OK; } - #endif +#endif // AI: end @@ -2156,19 +2142,12 @@ class AudioReactive : public Usermod { #ifdef ARDUINO_ARCH_ESP32 // Reset I2S peripheral for good measure - not needed in esp-idf v4.4.x and later. - #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0) - i2s_driver_uninstall(I2S_NUM_0); // E (696) I2S: i2s_driver_uninstall(2006): I2S port 0 has not installed - #if defined(ARDUINO_ARCH_ESP32) && !defined(__riscv) - delay(100); - periph_module_reset(PERIPH_I2S0_MODULE); // not possible on -C3 - #endif - #endif - delay(100); // Give that poor microphone some time to setup. + delay(100); // Give that poor microphone some time to setup. #if defined(SOC_I2S_SUPPORTS_PDM_RX) && !defined(__riscv) && !defined(CONFIG_IDF_TARGET_ESP32S2) if ((i2sckPin == I2S_PIN_NO_CHANGE) && (i2ssdPin >= 0) && (i2swsPin >= 0) && ((dmType == 1) || (dmType == 4))) dmType = 51; // dummy user support: SCK == -1 --means--> PDM microphone #endif - useInputFilter = 2; // default: DC blocker + useInputFilter = 2; // default: DC blocker switch (dmType) { // stub cases for not-yet-supported I2S modes on other ESP32 chips #if !defined(CONFIG_IDF_TARGET_ESP32) || !defined(SOC_I2S_SUPPORTS_ADC) || (ESP_IDF_VERSION_MAJOR > 4) diff --git a/audio_source.h b/audio_source.h index dfe1b428..5eb420ae 100644 --- a/audio_source.h +++ b/audio_source.h @@ -17,18 +17,14 @@ #if (ESP_IDF_VERSION_MAJOR < 5) #include // needed for SPH0465 timing workaround (classic ESP32) #endif - #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) - #if defined(CONFIG_IDF_TARGET_ESP32) && defined(SOC_I2S_SUPPORTS_ADC) && (ESP_IDF_VERSION_MAJOR < 5) - #include - #include - #include - #endif - // type of i2s_config_t.SampleRate was changed from "int" to "unsigned" in IDF 4.4.x - // also matches i2s_std_clk_config_t.sample_rate_hz of the IDF V5 driver - #define SRate_t uint32_t - #else - #define SRate_t int + #if defined(CONFIG_IDF_TARGET_ESP32) && defined(SOC_I2S_SUPPORTS_ADC) && (ESP_IDF_VERSION_MAJOR < 5) + #include + #include + #include #endif + // type of i2s_config_t.SampleRate was changed from "int" to "unsigned" in IDF 4.4.x + // also matches i2s_std_clk_config_t.sample_rate_hz of the IDF V5 driver + #define SRate_t uint32_t #if (ESP_IDF_VERSION_MAJOR < 4) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 7)) // backwards compatibility patch #define ADC_ATTEN_DB_12 ADC_ATTEN_DB_11 @@ -274,11 +270,7 @@ class I2SSource : public AudioSource { //.fixed_mclk = 0, .bits_per_chan = I2S_data_size, #else // ESP-IDF v3.x - .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, - .dma_buf_count = 8, - .dma_buf_len = _blockSize, - .use_apll = false + #error "esp-idf V3.x is not supported" #endif }; } @@ -299,12 +291,10 @@ class I2SSource : public AudioSource { return; } } else { - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) - #if !defined(SOC_I2S_SUPPORTS_PDM_RX) - #warning this MCU does not support PDM microphones - #endif - #endif - #if defined(SOC_I2S_SUPPORTS_PDM_RX) && !defined(__riscv) && !defined(CONFIG_IDF_TARGET_ESP32S2) + #if !defined(SOC_I2S_SUPPORTS_PDM_RX) + #warning this MCU does not support PDM microphones + #endif + #if defined(SOC_I2S_SUPPORTS_PDM_RX) && !defined(__riscv) && !defined(CONFIG_IDF_TARGET_ESP32S2) // This is an I2S PDM microphone, these microphones only use a clock and // data line, to make it simpler to debug, use the WS pin as CLK and SD pin as DATA // example from espressif: https://github.com/espressif/esp-idf/blob/release/v4.4/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -318,10 +308,9 @@ class I2SSource : public AudioSource { _config.channel_format = I2S_PDM_MIC_CHANNEL; // seems that PDM mono mode always uses left channel. _config.use_apll = true; // experimental - use aPLL clock source to improve sampling quality //_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT; // not needed - #endif + #endif } - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) if ((_i2sMaster == false) && (_config.mode & I2S_MODE_SLAVE)) { // I2S slave mode (experimental). // Seems we need to drive clocks in slave mode _config.use_apll = true; @@ -345,7 +334,6 @@ class I2SSource : public AudioSource { #if defined(WLED_USE_ETHERNET) || defined(WLED_ENABLE_HUB75MATRIX) _config.use_apll = false; // APLL is needed for Ethernet, and possibly for HUB75, too #endif - #endif if (_i2sMaster == false) { DEBUG_PRINTLN(F("AR: Warning - i2S SLAVE mode is experimental!")); @@ -363,13 +351,11 @@ class I2SSource : public AudioSource { if (!ar_allocatePin(mclkPin, true, PinOwner::UM_Audioreactive)) { ERRORSR_PRINTF("\nAR: Failed to allocate I2S pin: MCLK=%d\n", mclkPin); return; - } else _routeMclk(mclkPin); + } } _pinConfig = { - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) .mck_io_num = mclkPin, // "classic" ESP32 supports setting MCK on GPIO0/GPIO1/GPIO3 only. i2s_set_pin() will fail if wrong mck_io_num is provided. - #endif .bck_io_num = i2sckPin, .ws_io_num = i2swsPin, .data_out_num = I2S_PIN_NO_CHANGE, @@ -402,7 +388,6 @@ class I2SSource : public AudioSource { return; } - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) // ToDO: seems that this sometimes reverts PDM timing configuration err = i2s_set_clk(AR_I2S_PORT, _sampleRate, I2S_SAMPLE_RESOLUTION, I2S_CHANNEL_MONO); // set bit clocks. Also takes care of MCLK routing if needed. if (err != ESP_OK) { @@ -410,7 +395,6 @@ class I2SSource : public AudioSource { i2s_driver_uninstall(AR_I2S_PORT); // uninstall already-installed driver return; } - #endif _initialized = true; } @@ -467,27 +451,6 @@ class I2SSource : public AudioSource { } protected: - void _routeMclk(int8_t mclkPin) { - #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(__riscv) && !defined(CONFIG_IDF_TARGET_ESP32S3) - // MCLK routing by writing registers is not needed any more with IDF > 4.4.0 - #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0) - // this way of MCLK routing only works on "classic" ESP32 - /* Enable the mclk routing depending on the selected mclk pin (ESP32: only 0,1,3) - * Only I2S_NUM_0 is supported - */ - if (mclkPin == GPIO_NUM_0) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); - WRITE_PERI_REG(PIN_CTRL, 0xFFF0); - } else if (mclkPin == GPIO_NUM_1) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); - WRITE_PERI_REG(PIN_CTRL, 0xF0F0); - } else { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); - WRITE_PERI_REG(PIN_CTRL, 0xFF00); - } - #endif - #endif - } i2s_config_t _config; i2s_pin_config_t _pinConfig; @@ -880,11 +843,7 @@ class WM8978Source : public I2SSource { _wm8978I2cWrite(2, 0b110111111); // Power Management 2 - enable output and amp stages (amps may lift signal but it works better on the ADCs) _wm8978I2cWrite(3, 0b000001100); // Power Management 3 - enable L&R output mixers - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) - _wm8978I2cWrite(4, 0b001010000); // Audio Interface - standard I2S, 24-bit - #else - _wm8978I2cWrite(4, 0b001001000); // Audio Interface - left-justified I2S, 24-bit - #endif + _wm8978I2cWrite(4, 0b001010000); // Audio Interface - standard I2S, 24-bit _wm8978I2cWrite(6, 0b000000000); // Clock generation control - use external mclk _wm8978I2cWrite(7, 0b000000100); // Sets sample rate to ~24kHz (only used for internal calculations, not I2S) @@ -1028,10 +987,8 @@ class AC101Source : public I2SSource { void deinitialize() { I2SSource::deinitialize(); } }; - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) - #if !defined(SOC_I2S_SUPPORTS_ADC) && !defined(SOC_I2S_SUPPORTS_ADC_DAC) - #warning this MCU does not support analog sound input - #endif + #if !defined(SOC_I2S_SUPPORTS_ADC) && !defined(SOC_I2S_SUPPORTS_ADC_DAC) + #warning this MCU does not support analog sound input #endif #if defined(CONFIG_IDF_TARGET_ESP32) && defined(SOC_I2S_SUPPORTS_ADC) && (ESP_IDF_VERSION_MAJOR < 5) @@ -1049,11 +1006,7 @@ class I2SAdcSource : public I2SSource { .sample_rate = _sampleRate, .bits_per_sample = I2S_SAMPLE_RESOLUTION, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S), - #else - .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), - #endif .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 8, .dma_buf_len = _blockSize,