Defer calling begin() on digital buses

NeoPixelBus requires that all parallel I2S bus members be constructed
before any of them call Begin().  Implement this by deferring the
call to the end of bus construction.

Fixes #4301.
This commit is contained in:
Will Miles 2024-11-23 12:29:46 -05:00
parent 548736f432
commit d53d7aa2e2
4 changed files with 8 additions and 12 deletions

View File

@ -1286,14 +1286,9 @@ void WS2812FX::finalizeInit() {
_isOffRefreshRequired |= bus->isOffRefreshRequired() && !bus->isPWM(); // use refresh bit for phase shift with analog _isOffRefreshRequired |= bus->isOffRefreshRequired() && !bus->isPWM(); // use refresh bit for phase shift with analog
unsigned busEnd = bus->getStart() + bus->getLength(); unsigned busEnd = bus->getStart() + bus->getLength();
if (busEnd > _length) _length = busEnd; if (busEnd > _length) _length = busEnd;
#ifdef ESP8266
// why do we need to reinitialise GPIO3??? // This must be done after all buses have been created, as some kinds (parallel I2S) interact
//if (!bus->isDigital() || bus->is2Pin()) continue; bus->begin();
//uint8_t pins[5];
//if (!bus->getPins(pins)) continue;
//BusDigital* bd = static_cast<BusDigital*>(bus);
//if (pins[0] == 3) bd->reinit();
#endif
} }
Segment::maxWidth = _length; Segment::maxWidth = _length;

View File

@ -410,7 +410,7 @@ std::vector<LEDType> BusDigital::getLEDTypes() {
}; };
} }
void BusDigital::reinit() { void BusDigital::begin() {
if (!_valid) return; if (!_valid) return;
PolyBus::begin(_busPtr, _iType, _pins); PolyBus::begin(_busPtr, _iType, _pins);
} }
@ -910,7 +910,7 @@ void BusManager::on() {
if (busses[i]->isDigital() && busses[i]->getPins(pins)) { if (busses[i]->isDigital() && busses[i]->getPins(pins)) {
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) { if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
BusDigital *bus = static_cast<BusDigital*>(busses[i]); BusDigital *bus = static_cast<BusDigital*>(busses[i]);
bus->reinit(); bus->begin();
break; break;
} }
} }

View File

@ -79,6 +79,7 @@ class Bus {
virtual ~Bus() {} //throw the bus under the bus virtual ~Bus() {} //throw the bus under the bus
virtual void begin() {};
virtual void show() = 0; virtual void show() = 0;
virtual bool canShow() const { return true; } virtual bool canShow() const { return true; }
virtual void setStatusPixel(uint32_t c) {} virtual void setStatusPixel(uint32_t c) {}
@ -213,7 +214,7 @@ class BusDigital : public Bus {
uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; } uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; }
uint16_t getUsedCurrent() const override { return _milliAmpsTotal; } uint16_t getUsedCurrent() const override { return _milliAmpsTotal; }
uint16_t getMaxCurrent() const override { return _milliAmpsMax; } uint16_t getMaxCurrent() const override { return _milliAmpsMax; }
void reinit(); void begin() override;
void cleanup(); void cleanup();
static std::vector<LEDType> getLEDTypes(); static std::vector<LEDType> getLEDTypes();

View File

@ -597,7 +597,7 @@ class PolyBus {
case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break; case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break;
case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[1], pins[0]); break; case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[1], pins[0]); break;
} }
begin(busPtr, busType, pins, clock_kHz);
return busPtr; return busPtr;
} }