diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index e8b2b40b..1f75410e 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -1272,7 +1272,6 @@ int BusManager::add(BusConfig &bc) { lastlen = 0; laststart = 0; lastBus = nullptr; - slowMode = false; DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type); if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) { @@ -1293,6 +1292,34 @@ int BusManager::add(BusConfig &bc) { } else { busses[numBusses] = new BusPwm(bc); } + + // WLEDMM ToDO + Bus *newBus = busses[numBusses]; + unsigned newStart = newBus->getStart(); + unsigned newEnd = newStart + newBus->getLength() - 1; + // WLEDMM check if added bus overlaps with any existing bus + bool foundOverlap = false; + unsigned busCount = getNumBusses(); + if (newBus != nullptr && newBus->isOk()) { + for (unsigned i=0; iisOk()) continue; + // check for overlap + unsigned theStart = theBus->getStart(); + unsigned theEnd = theStart + theBus->getLength() - 1; + // see https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap + if ((newStart <= theEnd) && (theStart <= newEnd)) { // catches all overlap scenarios - including "new is including (around) another range" + foundOverlap = true; + USER_PRINTF("bus %u[%u %u] overlaps with\t%u [%u %u]", numBusses, newStart, newEnd, i, theStart, theEnd); + } + } + } + // if some busses overlap, we disable the bus caching optimization to allow multiple outputs for the same pixel + if (foundOverlap) { overlapingBusses = true; slowMode = true; } + if (numBusses < 1) { overlapingBusses = false; slowMode = false; } + USER_PRINT(slowMode ? "busses are in SlowMode\n" : ""); return numBusses++; } @@ -1312,6 +1339,7 @@ void BusManager::removeAll() { laststart = 0; lastlen = 0; slowMode = false; + overlapingBusses = false; } void __attribute__((hot)) BusManager::show() { @@ -1431,7 +1459,7 @@ uint32_t IRAM_ATTR __attribute__((hot)) BusManager::getPixelColorRestored(uint_ bool BusManager::canAllShow() const { for (uint8_t i = 0; i < numBusses; i++) { - if (!busses[i]->canShow()) return false; + if ((busses[i]->isOk()) && !busses[i]->canShow()) return false; } return true; } diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index ea886eaf..23a3d221 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -373,7 +373,7 @@ class BusNetwork : public Bus { return _artnet_leds_per_output; } - void setColorOrder(uint8_t colorOrder); + void setColorOrder(uint8_t colorOrder); // ??? not implemented??? uint8_t getColorOrder() const override { return _colorOrder; @@ -464,7 +464,7 @@ class BusManager { lastBus = nullptr; laststart = 0; lastlen= 0; - slowMode = isRTMode; + if (isRTMode || !overlapingBusses) slowMode = isRTMode; // don't reset slowMode if we have overlaping busses } void setStatusPixel(uint32_t c); @@ -507,6 +507,7 @@ class BusManager { unsigned laststart = 0; unsigned lastlen = 0; bool slowMode = false; // WLEDMM not sure why we need this. But its necessary. + bool overlapingBusses = false; // WLEDMM needed to enforce "slowMode" when busses overlap (=custom bus start indices) inline uint8_t getNumVirtualBusses() const { int j = 0;