Skip to content

Commit acc2d3a

Browse files
committed
clean up I2C pin handling in audioreactive (ES7243+ES8388)
* remove double Wire.begin() - Wire cannot be re-initialized; its already started by pinManager.joinWire() * Only use global I2C pins; make sure that audireactive I2C settings are aligned with global I2C pins * minor cleanup * remove I2C pins from AudioSource::initialize() Note to self: sdaPin, sclPin are just dummy values now, good for UI consistency, but unused otherwise. Could be removed.
1 parent b3d9621 commit acc2d3a

File tree

2 files changed

+49
-87
lines changed

2 files changed

+49
-87
lines changed

usermods/audioreactive/audio_reactive.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,13 @@ class AudioReactive : public Usermod {
16871687
//useInputFilter = 0; // in case you need to disable low-cut software filtering
16881688
audioSource = new ES7243(SAMPLE_RATE, BLOCK_SIZE);
16891689
delay(100);
1690-
if (audioSource) audioSource->initialize(sdaPin, sclPin, i2swsPin, i2ssdPin, i2sckPin, mclkPin);
1690+
// WLEDMM align global pins
1691+
if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined)
1692+
if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin;
1693+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
1694+
if (i2c_scl >= 0) sclPin = -1;
1695+
1696+
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
16911697
break;
16921698
case 3:
16931699
DEBUGSR_PRINT(F("AR: SPH0645 Microphone - ")); DEBUGSR_PRINTLN(F(I2S_MIC_CHANNEL_TEXT));
@@ -1719,11 +1725,21 @@ class AudioReactive : public Usermod {
17191725
break;
17201726
#endif
17211727
case 6:
1722-
DEBUGSR_PRINTLN(F("AR: ES8388 Source"));
1728+
#ifdef use_es8388_mic
1729+
DEBUGSR_PRINTLN(F("AR: ES8388 Source (Mic)"));
1730+
#else
1731+
DEBUGSR_PRINTLN(F("AR: ES8388 Source (Line-In)"));
1732+
#endif
17231733
audioSource = new ES8388Source(SAMPLE_RATE, BLOCK_SIZE, 1.0f);
17241734
//useInputFilter = 0; // to disable low-cut software filtering and restore previous behaviour
17251735
delay(100);
1726-
if (audioSource) audioSource->initialize(sdaPin, sclPin, i2swsPin, i2ssdPin, i2sckPin, mclkPin);
1736+
// WLEDMM align global pins
1737+
if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined)
1738+
if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin;
1739+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
1740+
if (i2c_scl >= 0) sclPin = -1;
1741+
1742+
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
17271743
break;
17281744

17291745
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
@@ -2366,6 +2382,11 @@ class AudioReactive : public Usermod {
23662382

23672383
JsonObject dmic = top.createNestedObject(FPSTR(_digitalmic));
23682384
dmic[F("type")] = dmType;
2385+
// WLEDMM: align with globals I2C pins
2386+
if ((dmType == 2) || (dmType == 6)) { // only for ES7243 and ES8388
2387+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
2388+
if (i2c_scl >= 0) sclPin = -1; // -1 = use global
2389+
}
23692390
JsonArray pinArray = dmic.createNestedArray("pin");
23702391
pinArray.add(i2ssdPin);
23712392
pinArray.add(i2swsPin);

usermods/audioreactive/audio_source.h

Lines changed: 25 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class AudioSource {
126126
This function needs to take care of anything that needs to be done
127127
before samples can be obtained from the microphone.
128128
*/
129-
virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0;
129+
virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0;
130130

131131
/* Deinitialize
132132
Release all resources and deactivate any functionality that is used
@@ -205,7 +205,7 @@ class I2SSource : public AudioSource {
205205
};
206206
}
207207

208-
virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) {
208+
virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE) {
209209
DEBUGSR_PRINTLN("I2SSource:: initialize().");
210210
if (i2swsPin != I2S_PIN_NO_CHANGE && i2ssdPin != I2S_PIN_NO_CHANGE) {
211211
if (!pinManager.allocatePin(i2swsPin, true, PinOwner::UM_Audioreactive) ||
@@ -425,19 +425,14 @@ class ES7243 : public I2SSource {
425425
private:
426426
// I2C initialization functions for ES7243
427427
void _es7243I2cBegin() {
428-
bool i2c_initialized = Wire.begin(pin_ES7243_SDA, pin_ES7243_SCL, 100000U);
429-
if (i2c_initialized == false) {
430-
ERRORSR_PRINTLN(F("AR: ES7243 failed to initialize I2C bus driver."));
431-
}
428+
Wire.setClock(100000);
432429
}
433430

434431
void _es7243I2cWrite(uint8_t reg, uint8_t val) {
435-
#ifndef ES7243_ADDR
436-
Wire.beginTransmission(0x13);
437-
#define ES7243_ADDR 0x13 // default address
438-
#else
432+
#ifndef ES7243_ADDR
433+
#define ES7243_ADDR 0x13 // default address
434+
#endif
439435
Wire.beginTransmission(ES7243_ADDR);
440-
#endif
441436
Wire.write((uint8_t)reg);
442437
Wire.write((uint8_t)val);
443438
uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK
@@ -462,54 +457,30 @@ class ES7243 : public I2SSource {
462457
_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
463458
};
464459

465-
void initialize(int8_t sdaPin, int8_t sclPin, int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
460+
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
466461
DEBUGSR_PRINTLN("ES7243:: initialize();");
467-
// check that pins are valid
468-
if ((sdaPin < 0) || (sclPin < 0)) {
469-
ERRORSR_PRINTF("\nAR: invalid ES7243 I2C pins: SDA=%d, SCL=%d\n", sdaPin, sclPin);
470-
return;
471-
}
472462

473-
if ((i2c_sda < 0) || (i2c_scl < 0)) { // check that global I2C pins are not "undefined"
463+
// if ((i2sckPin < 0) || (mclkPin < 0)) { // WLEDMM not sure if this check is needed here, too
464+
// ERRORSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
465+
// return;
466+
// }
467+
if ((i2c_sda < 0) || (i2c_scl < 0)) { // check that global I2C pins are not "undefined"
474468
ERRORSR_PRINTF("\nAR: invalid ES7243 global I2C pins: SDA=%d, SCL=%d\n", i2c_sda, i2c_scl);
475469
return;
476470
}
477-
if (!pinManager.joinWire()) { // WLEDMM specific: start I2C with globally defined pins
471+
if (!pinManager.joinWire(i2c_sda, i2c_scl)) { // WLEDMM specific: start I2C with globally defined pins
478472
ERRORSR_PRINTF("\nAR: failed to join I2C bus with SDA=%d, SCL=%d\n", i2c_sda, i2c_scl);
479473
return;
480474
}
481475

482-
if ((i2sckPin < 0) || (mclkPin < 0)) {
483-
ERRORSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
484-
return;
485-
}
486-
487-
// Reserve SDA and SCL pins of the I2C interface
488-
PinManagerPinType es7243Pins[2] = { { sdaPin, true }, { sclPin, true } };
489-
if (!pinManager.allocateMultiplePins(es7243Pins, 2, PinOwner::HW_I2C)) {
490-
pinManager.deallocateMultiplePins(es7243Pins, 2, PinOwner::HW_I2C);
491-
ERRORSR_PRINTF("\nAR: Failed to allocate ES7243 I2C pins: SDA=%d, SCL=%d\n", sdaPin, sclPin);
492-
return;
493-
}
494-
495-
pin_ES7243_SDA = sdaPin;
496-
pin_ES7243_SCL = sclPin;
497-
498476
// First route mclk, then configure ADC over I2C, then configure I2S
499477
_es7243InitAdc();
500478
I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
501479
}
502480

503481
void deinitialize() {
504-
// Release SDA and SCL pins of the I2C interface
505-
PinManagerPinType es7243Pins[2] = { { pin_ES7243_SDA, true }, { pin_ES7243_SCL, true } };
506-
pinManager.deallocateMultiplePins(es7243Pins, 2, PinOwner::HW_I2C);
507482
I2SSource::deinitialize();
508483
}
509-
510-
private:
511-
int8_t pin_ES7243_SDA;
512-
int8_t pin_ES7243_SCL;
513484
};
514485

515486
/* ES8388 Sound Modude
@@ -520,19 +491,14 @@ class ES8388Source : public I2SSource {
520491
private:
521492
// I2C initialization functions for ES8388
522493
void _es8388I2cBegin() {
523-
bool i2c_initialized = Wire.begin(pin_ES8388_SDA, pin_ES8388_SCL, 100000U);
524-
if (i2c_initialized == false) {
525-
ERRORSR_PRINTLN(F("AR: ES8388 failed to initialize I2C bus driver."));
526-
}
494+
Wire.setClock(100000);
527495
}
528496

529497
void _es8388I2cWrite(uint8_t reg, uint8_t val) {
530-
#ifndef ES8388_ADDR
531-
Wire.beginTransmission(0x10);
532-
#define ES8388_ADDR 0x10 // default address
533-
#else
498+
#ifndef ES8388_ADDR
499+
#define ES8388_ADDR 0x10 // default address
500+
#endif
534501
Wire.beginTransmission(ES8388_ADDR);
535-
#endif
536502
Wire.write((uint8_t)reg);
537503
Wire.write((uint8_t)val);
538504
uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK
@@ -619,59 +585,34 @@ class ES8388Source : public I2SSource {
619585
_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT;
620586
};
621587

622-
void initialize(int8_t sdaPin, int8_t sclPin, int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
588+
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
623589
DEBUGSR_PRINTLN("ES8388Source:: initialize();");
624590

591+
// if ((i2sckPin < 0) || (mclkPin < 0)) { // WLEDMM not sure if this check is needed here, too
592+
// ERRORSR_PRINTF("\nAR: invalid I2S ES8388 pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
593+
// return;
594+
// }
625595
// BUG: "use global I2C pins" are valid as -1, and -1 is seen as invalid here.
626596
// Workaround: Set I2C pins here, which will also set them globally.
627597
// Bug also exists in ES7243.
628-
629-
// check that pins are valid
630-
if ((sdaPin < 0) || (sclPin < 0)) {
631-
ERRORSR_PRINTF("\nAR: invalid ES8388 I2C pins: SDA=%d, SCL=%d\n", sdaPin, sclPin);
632-
return;
633-
}
634-
635598
if ((i2c_sda < 0) || (i2c_scl < 0)) { // check that global I2C pins are not "undefined"
636599
ERRORSR_PRINTF("\nAR: invalid ES8388 global I2C pins: SDA=%d, SCL=%d\n", i2c_sda, i2c_scl);
637600
return;
638601
}
639-
if (!pinManager.joinWire()) { // WLEDMM specific: start I2C with globally defined pins
602+
if (!pinManager.joinWire(i2c_sda, i2c_scl)) { // WLEDMM specific: start I2C with globally defined pins
640603
ERRORSR_PRINTF("\nAR: failed to join I2C bus with SDA=%d, SCL=%d\n", i2c_sda, i2c_scl);
641604
return;
642605
}
643606

644-
if ((i2sckPin < 0) || (mclkPin < 0)) {
645-
ERRORSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
646-
return;
647-
}
648-
649-
// Reserve SDA and SCL pins of the I2C interface
650-
PinManagerPinType es8388Pins[2] = { { sdaPin, true }, { sclPin, true } };
651-
if (!pinManager.allocateMultiplePins(es8388Pins, 2, PinOwner::HW_I2C)) {
652-
pinManager.deallocateMultiplePins(es8388Pins, 2, PinOwner::HW_I2C);
653-
ERRORSR_PRINTF("\nAR: Failed to allocate ES8388 I2C pins: SDA=%d, SCL=%d\n", sdaPin, sclPin);
654-
return;
655-
}
656-
657-
pin_ES8388_SDA = sdaPin;
658-
pin_ES8388_SCL = sclPin;
659-
660607
// First route mclk, then configure ADC over I2C, then configure I2S
661608
_es8388InitAdc();
662609
I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
663610
}
664611

665612
void deinitialize() {
666-
// Release SDA and SCL pins of the I2C interface
667-
PinManagerPinType es8388Pins[2] = { { pin_ES8388_SDA, true }, { pin_ES8388_SCL, true } };
668-
pinManager.deallocateMultiplePins(es8388Pins, 2, PinOwner::HW_I2C);
669613
I2SSource::deinitialize();
670614
}
671615

672-
private:
673-
int8_t pin_ES8388_SDA;
674-
int8_t pin_ES8388_SCL;
675616
};
676617

677618
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
@@ -714,7 +655,7 @@ class I2SAdcSource : public I2SSource {
714655
/* identify Audiosource type - I2S-ADC*/
715656
AudioSourceType getType(void) {return(Type_I2SAdc);}
716657

717-
void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) {
658+
void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) {
718659
DEBUGSR_PRINTLN("I2SAdcSource:: initialize().");
719660
_myADCchannel = 0x0F;
720661
if(!pinManager.allocatePin(audioPin, false, PinOwner::UM_Audioreactive)) {
@@ -886,7 +827,7 @@ class SPH0654 : public I2SSource {
886827
I2SSource(sampleRate, blockSize, sampleScale, i2sMaster)
887828
{}
888829

889-
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) {
830+
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE) {
890831
DEBUGSR_PRINTLN("SPH0654:: initialize();");
891832
I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin);
892833
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)

0 commit comments

Comments
 (0)