Skip to content

Commit f8ca0f9

Browse files
committed
Keep bus length when failed
In the event that a Bus fails to initialize, or the memory validation fails, keep the configuration around so the settings contents don't change out from under the user.
1 parent 97f68b3 commit f8ca0f9

File tree

5 files changed

+70
-17
lines changed

5 files changed

+70
-17
lines changed

wled00/FX_fcn.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,14 +1181,14 @@ void WS2812FX::finalizeInit() {
11811181
// create buses/outputs
11821182
unsigned mem = 0;
11831183
for (auto bus : busConfigs) {
1184-
unsigned busMemUsage = bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount : 0);
1185-
// if memory exceeds limit, add it anyway but reduce LED count to default if it is larger (a bit dangerous, but prevents no buses being created at all)
1186-
if (mem + busMemUsage > MAX_LED_MEMORY) {
1187-
bus.count = min((int)bus.count, DEFAULT_LED_COUNT);
1188-
DEBUG_PRINTF_P(PSTR("Bus %d memory usage exceeds limit, setting count to %d\n"), (int)bus.type, bus.count);
1184+
bool use_placeholder = false;
1185+
unsigned busMemUsage = bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount : 0);
1186+
if (mem + busMemUsage > MAX_LED_MEMORY) {
1187+
DEBUG_PRINTF_P(PSTR("Bus %d with %d LEDS memory usage exceeds limit\n"), (int)bus.type, bus.count);
1188+
use_placeholder = true;
11891189
}
1190-
if (BusManager::add(bus) != -1) {
1191-
mem += bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount : 0);
1190+
if (BusManager::add(bus, use_placeholder) != -1) {
1191+
mem += BusManager::busses.back()->getBusSize();
11921192
if (Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type)) digitalCount++;
11931193
} else break;
11941194
}
@@ -1807,7 +1807,7 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
18071807

18081808
for (size_t i = s; i < BusManager::getNumBusses(); i++) {
18091809
const Bus *bus = BusManager::getBus(i);
1810-
if (!bus || !bus->isOk()) break;
1810+
if (!bus) break;
18111811

18121812
segStarts[s] = bus->getStart();
18131813
segStops[s] = segStarts[s] + bus->getLength();

wled00/bus_manager.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,26 @@ void BusNetwork::cleanup() {
755755
}
756756

757757

758+
BusPlaceholder::BusPlaceholder(const BusConfig &bc)
759+
: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, bc.refreshReq)
760+
, _colorOrder(bc.colorOrder)
761+
, _skipAmount(bc.skipAmount)
762+
, _frequency(bc.frequency)
763+
, _milliAmpsPerLed(bc.milliAmpsPerLed)
764+
, _milliAmpsMax(bc.milliAmpsMax)
765+
, _text(bc.text)
766+
{
767+
memcpy(_pins, bc.pins, sizeof(_pins));
768+
}
769+
770+
size_t BusPlaceholder::getPins(uint8_t* pinArray) const {
771+
size_t nPins = Bus::getNumberOfPins(_type);
772+
if (pinArray) {
773+
for (size_t i = 0; i < nPins; i++) pinArray[i] = _pins[i];
774+
}
775+
return nPins;
776+
}
777+
758778
//utility to get the approx. memory usage of a given BusConfig
759779
size_t BusConfig::memUsage(unsigned nr) const {
760780
if (Bus::isVirtual(type)) {
@@ -797,7 +817,7 @@ size_t BusManager::memUsage() {
797817
return size + maxI2S;
798818
}
799819

800-
int BusManager::add(const BusConfig &bc) {
820+
int BusManager::add(const BusConfig &bc, bool placeholder) {
801821
DEBUGBUS_PRINTF_P(PSTR("Bus: Adding bus (p:%d v:%d)\n"), getNumBusses(), getNumVirtualBusses());
802822
unsigned digital = 0;
803823
unsigned analog = 0;
@@ -807,8 +827,10 @@ int BusManager::add(const BusConfig &bc) {
807827
if (bus->isDigital() && !bus->is2Pin()) digital++;
808828
if (bus->is2Pin()) twoPin++;
809829
}
810-
if (digital > WLED_MAX_DIGITAL_CHANNELS || analog > WLED_MAX_ANALOG_CHANNELS) return -1;
811-
if (Bus::isVirtual(bc.type)) {
830+
if (digital > WLED_MAX_DIGITAL_CHANNELS || analog > WLED_MAX_ANALOG_CHANNELS) placeholder = true;
831+
if (placeholder) {
832+
busses.push_back(make_unique<BusPlaceholder>(bc));
833+
} else if (Bus::isVirtual(bc.type)) {
812834
busses.push_back(make_unique<BusNetwork>(bc));
813835
} else if (Bus::isDigital(bc.type)) {
814836
busses.push_back(make_unique<BusDigital>(bc, Bus::is2Pin(bc.type) ? twoPin : digital));
@@ -907,7 +929,7 @@ void BusManager::on() {
907929
if (PinManager::getPinOwner(LED_BUILTIN) == PinOwner::BusDigital) {
908930
for (auto &bus : busses) {
909931
uint8_t pins[2] = {255,255};
910-
if (bus->isDigital() && bus->getPins(pins)) {
932+
if (bus->isDigital() && bus->getPins(pins) && bus->isOk()) {
911933
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
912934
BusDigital &b = static_cast<BusDigital&>(*bus);
913935
b.begin();
@@ -1002,7 +1024,7 @@ void BusManager::initializeABL() {
10021024
_useABL = true; // at least one bus has ABL set
10031025
uint32_t ESPshare = MA_FOR_ESP / numABLbuses; // share of ESP current per ABL bus
10041026
for (auto &bus : busses) {
1005-
if (bus->isDigital()) {
1027+
if (bus->isDigital() && bus->isOk()) {
10061028
BusDigital &busd = static_cast<BusDigital&>(*bus);
10071029
uint32_t busLength = busd.getLength();
10081030
uint32_t busDemand = busLength * busd.getLEDCurrent();

wled00/bus_manager.h

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class Bus {
125125
virtual void setColorOrder(uint8_t co) {}
126126
virtual uint32_t getPixelColor(unsigned pix) const { return 0; }
127127
virtual size_t getPins(uint8_t* pinArray = nullptr) const { return 0; }
128-
virtual uint16_t getLength() const { return isOk() ? _len : 0; }
128+
virtual uint16_t getLength() const { return _len; }
129129
virtual uint8_t getColorOrder() const { return COL_ORDER_RGB; }
130130
virtual unsigned skippedLeds() const { return 0; }
131131
virtual uint16_t getFrequency() const { return 0U; }
@@ -363,6 +363,37 @@ class BusNetwork : public Bus {
363363
#endif
364364
};
365365

366+
// Placeholder for buses that we can't construct due to resource limitations
367+
// This preserves the configuration so it can be read back to the settings pages
368+
class BusPlaceholder : public Bus {
369+
public:
370+
BusPlaceholder(const BusConfig &bc);
371+
372+
// Actual calls are stubbed out
373+
void setPixelColor(unsigned pix, uint32_t c) override {};
374+
void show() override {};
375+
376+
// Accessors
377+
uint8_t getColorOrder() const override { return _colorOrder; }
378+
size_t getPins(uint8_t* pinArray) const override;
379+
unsigned skippedLeds() const override { return _skipAmount; }
380+
uint16_t getFrequency() const override { return _frequency; }
381+
uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; }
382+
uint16_t getMaxCurrent() const override { return _milliAmpsMax; }
383+
const String getCustomText() const override { return _text; }
384+
385+
size_t getBusSize() const override { return sizeof(BusPlaceholder); }
386+
387+
private:
388+
uint8_t _colorOrder;
389+
uint8_t _skipAmount;
390+
uint8_t _pins[5];
391+
uint16_t _frequency;
392+
uint8_t _milliAmpsPerLed;
393+
uint16_t _milliAmpsMax;
394+
String _text;
395+
};
396+
366397

367398
//temporary struct for passing bus configuration to bus
368399
struct BusConfig {
@@ -464,7 +495,7 @@ namespace BusManager {
464495

465496
//do not call this method from system context (network callback)
466497
void removeAll();
467-
int add(const BusConfig &bc);
498+
int add(const BusConfig &bc, bool placeholder);
468499

469500
void on();
470501
void off();

wled00/cfg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ void serializeConfig(JsonObject root) {
973973
for (size_t s = 0; s < BusManager::getNumBusses(); s++) {
974974
DEBUG_PRINTF_P(PSTR("Cfg: Saving bus #%u\n"), s);
975975
const Bus *bus = BusManager::getBus(s);
976-
if (!bus || !bus->isOk()) break;
976+
if (!bus) break; // Memory corruption, iterator invalid
977977
DEBUG_PRINTF_P(PSTR(" (%d-%d, type:%d, CO:%d, rev:%d, skip:%d, AW:%d kHz:%d, mA:%d/%d)\n"),
978978
(int)bus->getStart(), (int)(bus->getStart()+bus->getLength()),
979979
(int)(bus->getType() & 0x7F),

wled00/xml.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
314314
unsigned sumMa = 0;
315315
for (size_t s = 0; s < BusManager::getNumBusses(); s++) {
316316
const Bus *bus = BusManager::getBus(s);
317-
if (!bus || !bus->isOk()) break; // should not happen but for safety
317+
if (!bus) break; // should not happen but for safety
318318
int offset = s < 10 ? '0' : 'A' - 10;
319319
char lp[4] = "L0"; lp[2] = offset+s; lp[3] = 0; //ascii 0-9 //strip data pin
320320
char lc[4] = "LC"; lc[2] = offset+s; lc[3] = 0; //strip length

0 commit comments

Comments
 (0)