diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index b68b8b3fc3..8d4c74d9af 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1222,7 +1222,7 @@ void WS2812FX::finalizeInit(void) { constexpr unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0])); const unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0])); - static_assert(getRequiredPins(defDataTypes[0]) <= defNumPins, + static_assert(Bus::getRequiredPins(defDataTypes[0]) <= defNumPins, "The first LED type configured requires more pins than have been defined!"); unsigned prevLen = 0; @@ -1231,7 +1231,7 @@ void WS2812FX::finalizeInit(void) { uint8_t defPin[OUTPUT_MAX_PINS]; // max 5 pins // if we have less types than requested outputs and they do not align, use last known type to set current type unsigned dataType = defDataTypes[(i < defNumTypes) ? i : defNumTypes -1]; - unsigned busPins = getRequiredPins(dataType); + unsigned busPins = Bus::getRequiredPins(dataType); // check if we have enough pins left to configure an output of this type if (pinsIndex + busPins > defNumPins) { DEBUG_PRINTLN(F("LED outputs misaligned with defined pins. Some pins will remain unused.")); diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 2d278de914..67ae3c0cc6 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -47,6 +47,34 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte #define B(c) (byte(c)) #define W(c) (byte((c) >> 24)) +BusConfig::BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len, uint8_t pcolorOrder, bool rev, uint8_t skip, byte aw, uint16_t clock_kHz, bool dblBfr, uint8_t maPerLed, uint16_t maMax) +: count(len) +, start(pstart) +, colorOrder(pcolorOrder) +, reversed(rev) +, skipAmount(skip) +, autoWhite(aw) +, frequency(clock_kHz) +, doubleBuffer(dblBfr) +, milliAmpsPerLed(maPerLed) +, milliAmpsMax(maMax) +{ + refreshReq = (bool) GET_BIT(busType, 7); + type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh) + size_t nPins = Bus::getRequiredPins(type); + for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i]; +} + +bool BusConfig::adjustBounds(uint16_t& total) { + if (!count) count = 1; + if (count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS; + if (start >= MAX_LEDS) return false; + //limit length of strip if it would exceed total permissible LEDs + if (start + count > MAX_LEDS) count = MAX_LEDS - start; + //extend total count accordingly + if (start + count > total) total = start + count; + return true; +} void ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) { if (_count >= WLED_MAX_COLOR_ORDER_MAPPINGS) { diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index d7cdfdffaf..5736448794 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -10,14 +10,6 @@ //colors.cpp uint16_t approximateKelvinFromRGB(uint32_t rgb); -// 1 pin per channel on analog, 4 "pins" (IPv4 fields) on virtual, 2 pins on clocked digital strips, 1 pin for the rest -static constexpr uint8_t getRequiredPins(uint8_t const type) { - // Constexpr so nested ternary - return IS_PWM(type) ? NUM_PWM_PINS(type) : - IS_VIRTUAL(type) ? 4 : - IS_2PIN(type) + 1; -} - #define GET_BIT(var,bit) (((var)>>(bit))&0x01) #define SET_BIT(var,bit) ((var)|=(uint16_t)(0x0001<<(bit))) #define UNSET_BIT(var,bit) ((var)&=(~(uint16_t)(0x0001<<(bit)))) @@ -29,6 +21,9 @@ static constexpr uint8_t getRequiredPins(uint8_t const type) { #define IC_INDEX_WS2812_2CH_3X(i) ((i)*2/3) #define WS2812_2CH_3X_SPANS_2_ICS(i) ((i)&0x01) // every other LED zone is on two different ICs +// Forward declaration to use Bus::getRequiredPins in BusConfig constructor +class Bus; + //temporary struct for passing bus configuration to bus struct BusConfig { uint8_t type; @@ -45,35 +40,9 @@ struct BusConfig { uint8_t milliAmpsPerLed; uint16_t milliAmpsMax; - BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U, bool dblBfr=false, uint8_t maPerLed=LED_MILLIAMPS_DEFAULT, uint16_t maMax=ABL_MILLIAMPS_DEFAULT) - : count(len) - , start(pstart) - , colorOrder(pcolorOrder) - , reversed(rev) - , skipAmount(skip) - , autoWhite(aw) - , frequency(clock_kHz) - , doubleBuffer(dblBfr) - , milliAmpsPerLed(maPerLed) - , milliAmpsMax(maMax) - { - refreshReq = (bool) GET_BIT(busType,7); - type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh) - size_t nPins = getRequiredPins(type); - for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i]; - } - - //validates start and length and extends total if needed - bool adjustBounds(uint16_t& total) { - if (!count) count = 1; - if (count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS; - if (start >= MAX_LEDS) return false; - //limit length of strip if it would exceed total permissible LEDs - if (start + count > MAX_LEDS) count = MAX_LEDS - start; - //extend total count accordingly - if (start + count > total) total = start + count; - return true; - } + BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw = RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz = 0U, bool dblBfr = false, uint8_t maPerLed = LED_MILLIAMPS_DEFAULT, uint16_t maMax = ABL_MILLIAMPS_DEFAULT); + + bool adjustBounds(uint16_t& total); }; @@ -213,6 +182,14 @@ class Bus { inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; } inline static uint8_t getGlobalAWMode() { return _gAWM; } + // 1 pin per channel on analog, 4 "pins" (IPv4 fields) on virtual, 2 pins on clocked digital strips, 1 pin for the rest + static constexpr uint8_t getRequiredPins(uint8_t const type) { + // Constexpr so nested ternary + return IS_PWM(type) ? NUM_PWM_PINS(type) : + IS_VIRTUAL(type) ? 4 : + IS_2PIN(type) + 1; + } + protected: uint8_t _type; uint8_t _bri;