diff --git a/src/AudioBoard.h b/src/AudioBoard.h index 414c382..d65e3ef 100644 --- a/src/AudioBoard.h +++ b/src/AudioBoard.h @@ -12,24 +12,29 @@ namespace audio_driver { */ class AudioBoard { public: - AudioBoard(AudioDriver *driver, DriverPins* pins=&NoPins) { - this->pins = pins; - this->driver = driver; + + AudioBoard(AudioDriver *driver, DriverPins* pins) { + this->p_pins = pins; + this->p_driver = driver; } - AudioBoard(AudioDriver &driver, DriverPins& pins=NoPins) { - this->pins = &pins; - this->driver = &driver; + AudioBoard(AudioDriver &driver, DriverPins& pins) { + this->p_pins = &pins; + this->p_driver = &driver; } bool begin(){ AD_LOGD("AudioBoard::begin"); - pins->setSPIActiveForSD(codec_cfg.sd_active); - if (!pins->begin()){ + if (p_pins==nullptr){ + AD_LOGE("pins are null"); + return false; + } + p_pins->setSPIActiveForSD(codec_cfg.sd_active); + if (!p_pins->begin()){ AD_LOGE("AudioBoard::pins::begin failed"); return false; } - if (!driver->begin(codec_cfg, *pins)){ + if (!p_driver->begin(codec_cfg, *p_pins)){ AD_LOGE("AudioBoard::driver::begin failed"); return false; } @@ -47,45 +52,53 @@ class AudioBoard { /// Updates the CodecConfig values -> reconfigures the codec only bool setConfig(CodecConfig cfg) { this->codec_cfg = cfg; - return driver->setConfig(cfg); + return p_driver->setConfig(cfg); } bool end(void) { - pins->end(); + p_pins->end(); is_active = false; - return driver->end(); + return p_driver->end(); } - bool setMute(bool enable) { return driver->setMute(enable); } + bool setMute(bool enable) { return p_driver->setMute(enable); } bool setMute(bool enable, int line) { if (line == power_amp_line) setPAPower(!enable); - return driver->setMute(enable, line); + return p_driver->setMute(enable, line); } bool setVolume(int volume) { AD_LOGD("setVolume: %d", volume); // when we get the volume we make sure that we report the same value // w/o rounding issues this->volume = volume; - return (is_active) ? driver->setVolume(volume) : false; + return (is_active) ? p_driver->setVolume(volume) : false; } int getVolume() { #if DRIVER_REPORT_DRIVER_VOLUME return driver->getVolume(); } #else - return volume >= 0 ? volume : driver->getVolume(); } + return volume >= 0 ? volume : p_driver->getVolume(); } #endif - DriverPins& getPins() { return *pins; } - bool setPAPower(bool enable) { return driver->setPAPower(enable); } + DriverPins& getPins() { return *p_pins; } + DriverPins& pins() { return *p_pins; } + + bool setPAPower(bool enable) { return is_active ? p_driver->setPAPower(enable) : false; } + /// set volume for adc: this is only supported on some defined codecs - bool setInputVolume(int volume) {return driver->setInputVolume(volume);} + bool setInputVolume(int volume) {return p_driver->setInputVolume(volume);} AudioDriver* getDriver(){ - return driver; + return p_driver; + } + AudioDriver& driver(){ + return *p_driver; } + operator bool() { return is_active && p_driver != nullptr && p_pins != nullptr;} + protected: - DriverPins* pins; + AudioDriver* p_driver = nullptr; + DriverPins* p_pins = nullptr; CodecConfig codec_cfg; - AudioDriver* driver = nullptr; int power_amp_line = ES8388_PA_LINE; int volume = -1; bool is_active = false; diff --git a/src/Driver.h b/src/Driver.h index a8bb044..869d3d7 100644 --- a/src/Driver.h +++ b/src/Driver.h @@ -190,9 +190,10 @@ class CodecConfig : public codec_config_t { */ class AudioDriver { public: + /// Starts the processing virtual bool begin(CodecConfig codecCfg, DriverPins &pins) { - AD_LOGD("AudioDriver::begin"); + AD_LOGI("AudioDriver::begin"); p_pins = &pins; pins.setSPIActiveForSD(codecCfg.sd_active); if (!setConfig(codecCfg)){ @@ -206,27 +207,22 @@ class AudioDriver { } /// changes the configuration virtual bool setConfig(CodecConfig codecCfg) { + AD_LOGI("AudioDriver::setConfig"); codec_cfg = codecCfg; if (!init(codec_cfg)) { - AD_LOGE("AudioDriver::begin::init failed"); + AD_LOGE("AudioDriver init failed"); return false; - } else { - AD_LOGD("AudioDriver::begin::init succeeded"); - } + } codec_mode_t codec_mode = codec_cfg.get_mode(); if (!controlState(codec_mode)) { - AD_LOGE("AudioDriver::begin::controlState failed"); + AD_LOGE("AudioDriver controlState failed"); return false; - } else { - AD_LOGD("AudioDriver::begin::controlState succeeded"); - } + } bool result = configInterface(codec_mode, codec_cfg.i2s); if (!result) { - AD_LOGE("AudioDriver::begin::configInterface failed"); + AD_LOGE("AudioDriver configInterface failed"); return false; - } else { - AD_LOGD("AudioDriver::begin::configInterface succeeded"); - } + } return result; } /// Ends the processing: shut down dac and adc @@ -250,12 +246,17 @@ class AudioDriver { /// Determines if setInputVolume() is supported virtual bool isInputVolumeSupported() { return false; } /// Provides the pin information - DriverPins &pins() { return *p_pins; } + virtual DriverPins &pins() { return *p_pins; } /// Sets the PA Power pin to active or inactive bool setPAPower(bool enable) { + if (p_pins == nullptr) { + AD_LOGI("pins are null"); + return false; + } GpioPin pin = pins().getPinID(PinFunction::PA); if (pin == -1) { + AD_LOGI("PinFunction::PA not defined"); return false; } AD_LOGI("setPAPower pin %d -> %d", pin, enable); @@ -263,15 +264,14 @@ class AudioDriver { return true; } - /// Gets the number of I2S Interfaces - virtual int getI2SCount() { return 1; } + operator bool() {return p_pins != nullptr;} protected: CodecConfig codec_cfg; DriverPins *p_pins = nullptr; /// Determine the TwoWire object from the I2C config or use Wire - TwoWire *getI2C() { + virtual TwoWire *getI2C() { if (p_pins == nullptr) return &Wire; auto i2c = pins().getI2CPins(PinFunction::CODEC); if (!i2c) { @@ -281,7 +281,7 @@ class AudioDriver { return result != nullptr ? result : &Wire; } - int getI2CAddress() { + virtual int getI2CAddress() { if (p_pins == nullptr) return -1; auto i2c = pins().getI2CPins(PinFunction::CODEC); if (i2c) { @@ -316,8 +316,8 @@ class AudioDriver { class NoDriverClass : public AudioDriver { public: virtual bool begin(CodecConfig codecCfg, DriverPins &pins) { - codec_cfg = codecCfg; - p_pins = &pins; + //codec_cfg = codecCfg; + //p_pins = &pins; return true; } virtual bool end(void) { return true; } @@ -390,6 +390,7 @@ class AudioDriverAD1938Class : public AudioDriver { return true; } virtual bool setConfig(CodecConfig codecCfg) { + assert(p_pins != nullptr); bool result = begin(codecCfg, *p_pins); return result; } @@ -428,7 +429,6 @@ class AudioDriverAD1938Class : public AudioDriver { protected: AD1938 ad1938; - DriverPins *p_pins = nullptr; int volume = 100; int volumes[8] = {100}; }; @@ -563,6 +563,7 @@ class AudioDriverCS42448Class : public AudioDriver { cs42448.setMute(false); } } else { + assert(p_pins != nullptr); result = begin(codecCfg, *p_pins); } return result; @@ -594,7 +595,6 @@ class AudioDriverCS42448Class : public AudioDriver { protected: CS42448 cs42448; - DriverPins *p_pins = nullptr; int volume = 100; CodecConfig cfg; }; @@ -1414,18 +1414,28 @@ class AudioDriverPCM3168Class : public AudioDriver { class AudioDriverLyratMiniClass : public AudioDriver { public: bool begin(CodecConfig codecCfg, DriverPins &pins) { - int rc = 0; - if (codecCfg.output_device != DAC_OUTPUT_NONE) - rc += !dac.begin(codecCfg, pins); - if (codecCfg.input_device != ADC_INPUT_NONE) - rc += !adc.begin(codecCfg, pins); - return rc == 0; + AD_LOGI("AudioDriverLyratMiniClass::begin"); + p_pins = &pins; + codec_cfg = codecCfg; + bool ok = true; + if (codecCfg.output_device != DAC_OUTPUT_NONE){ + AD_LOGI("starting DAC"); + ok = dac.begin(codecCfg, pins); + } + if (codecCfg.input_device != ADC_INPUT_NONE){ + AD_LOGI("starting ADC"); + ok = ok && adc.begin(codecCfg, pins); + } + if (!ok) { + AD_LOGI("AudioDriverLyratMiniClass::begin failed"); + } + return ok; } bool end(void) { int rc = 0; rc += dac.end(); rc += adc.end(); - return rc == 0; + return rc == 2; } bool setMute(bool enable) { return dac.setMute(enable); } bool setVolume(int volume) { return dac.setVolume(volume); } @@ -1433,8 +1443,6 @@ class AudioDriverLyratMiniClass : public AudioDriver { bool setInputVolume(int volume) { return adc.setVolume(volume); } int getInputVolume() { return adc.getVolume(); } bool isInputVolumeSupported() { return true; } - // Separate ADC and DAC I2S - int getI2SCount() override { return 2; } protected: AudioDriverES8311Class dac; diff --git a/src/DriverPins.h b/src/DriverPins.h index ddc9e1e..6030400 100644 --- a/src/DriverPins.h +++ b/src/DriverPins.h @@ -136,7 +136,10 @@ struct PinsSPI { } return true; } - void end() { p_spi->end(); } + void end() { + AD_LOGD("PinsSPI::end"); + p_spi->end(); + } }; /** @@ -175,6 +178,7 @@ struct PinsI2C { operator bool() { return pinsAvailable(); } bool begin() { + AD_LOGD("PinsI2C::begin: %d", port); if (set_active) { AD_LOGD("PinsI2C::begin for %d", function); // if no pins are defined, just call begin @@ -239,6 +243,10 @@ struct PinsFunction { */ class DriverPins { public: + DriverPins (const DriverPins&) = delete; + DriverPins& operator= (const DriverPins&) = delete; + DriverPins() = default; + bool addI2S(PinsI2S pin) { if (getI2SPins(pin.function)) return false; i2s.push_back(pin); @@ -356,14 +364,11 @@ class DriverPins { AD_LOGD("DriverPins::begin"); // setup function pins - AD_LOGD("DriverPins::begin::setupPinMode"); setupPinMode(); // setup spi - AD_LOGD("DriverPins::begin::SPI"); bool result = true; for (auto &tmp : spi) { - AD_LOGD("DriverPins::begin::SPI::begin"); if (tmp.function == PinFunction::SD) { if (sd_active) result &= tmp.begin(); @@ -373,9 +378,7 @@ class DriverPins { } // setup i2c - AD_LOGD("DriverPins::begin::I2C"); for (auto &tmp : i2c) { - AD_LOGD("DriverPins::begin::I2C port:%d", tmp.port); result &= tmp.begin(); } return result; @@ -384,7 +387,6 @@ class DriverPins { void end() { // setup spi for (auto &tmp : spi) { - AD_LOGD("DriverPins::begin::SPI::end"); tmp.end(); } // setup i2c @@ -427,6 +429,7 @@ class DriverPins { } void setupPinMode() { + AD_LOGD("DriverPins::setupPinMode"); // setup pins for (auto &tmp : pins) { if (tmp.pin != -1) { @@ -550,10 +553,9 @@ class PinsLyrat42Class : public DriverPins { */ class PinsLyratMiniClass : public DriverPins { public: + PinsLyratMiniClass() { // sd pins: CLK, MISO, MOSI, CS - //addSPI(PinFunction::SD, 14, 2, 15, 13, SPI); - //addSPI(PinFunction::SD, 18, 19, 23, 5, SPI); addSPI(ESP32PinsSD); // add i2c codec pins: scl, sda, port, frequency addI2C(PinFunction::CODEC, 23, 18); @@ -561,7 +563,7 @@ class PinsLyratMiniClass : public DriverPins { addI2S(PinFunction::CODEC, 0, 5, 25, 26, 35, 0); addI2S(PinFunction::CODEC_ADC, 0, 32, 33, -1, 36, 1); - addPin(PinFunction::HEADPHONE_DETECT, 19, PinLogic::InputActiveLow); + addPin(PinFunction::HEADPHONE_DETECT, 19, PinLogic::InputActiveHigh); addPin(PinFunction::PA, 21, PinLogic::Output); addPin(PinFunction::LED, 22, PinLogic::Output, 1); addPin(PinFunction::LED, 27, PinLogic::Output, 2);