diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 56267c117..b0ea62e87 100755 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -606,29 +606,34 @@ void BusNetwork::cleanup() { //utility to get the approx. memory usage of a given BusConfig uint32_t BusManager::memUsage(BusConfig &bc) { - uint8_t type = bc.type; + if (bc.type == TYPE_ONOFF || IS_PWM(bc.type)) return 5; + uint16_t len = bc.count + bc.skipAmount; - if (type > 15 && type < 32) { // digital types - if (type == TYPE_UCS8903 || type == TYPE_UCS8904) len *= 2; // 16-bit LEDs + uint16_t channels = 3; + uint16_t multiplier = 1; + if (IS_DIGITAL(bc.type)) { // digital types + if (IS_16BIT(bc.type)) len *= 2; // 16-bit LEDs #ifdef ESP8266 + if (bc.type > 28) channels = 4; //RGBW if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem - if (type > 28) return len*20; //RGBW - return len*15; + multiplier = 5; } - if (type > 28) return len*4; //RGBW - return len*3; - #else //ESP32 RMT uses double buffer? - if (type > 28) return len*8; //RGBW - return len*6; + #else //ESP32 RMT uses double buffer, I2S uses 5x buffer + if (type > 28) channels = 4; //RGBW + multiplier = 2; #endif } - if (type > 31 && type < 48) return 5; - return len*3; //RGB + if (IS_VIRTUAL(bc.type)) { + switch (bc.type) { + case TYPE_NET_DDP_RGBW: channels = 4; break; + } + } + return len * channels * multiplier; //RGB } int BusManager::add(BusConfig &bc) { if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1; - if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) { + if (IS_VIRTUAL(bc.type)) { busses[numBusses] = new BusNetwork(bc); } else if (IS_DIGITAL(bc.type)) { busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap); diff --git a/wled00/const.h b/wled00/const.h index 0aa8a526d..4ef81b907 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -225,7 +225,7 @@ #define TYPE_NONE 0 //light is not configured #define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light -//Digital types (data pin only) (16-31) +//Digital types (data pin only) (16-39) #define TYPE_WS2812_1CH 18 //white-only chips (1 channel per IC) (unused) #define TYPE_WS2812_1CH_X3 19 //white-only chips (3 channels per IC) #define TYPE_WS2812_2CH_X3 20 //CCT chips (1st IC controls WW + CW of 1st zone and CW of 2nd zone, 2nd IC controls WW of 2nd zone and WW + CW of 3rd zone) @@ -235,11 +235,11 @@ #define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units #define TYPE_TM1829 25 #define TYPE_UCS8903 26 -#define TYPE_UCS8904 29 +#define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage()) #define TYPE_SK6812_RGBW 30 #define TYPE_TM1814 31 -//"Analog" types (PWM) (32-47) -#define TYPE_ONOFF 40 //binary output (relays etc.) +//"Analog" types (40-47) +#define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM) #define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel #define TYPE_ANALOG_2CH 42 //analog WW + CW #define TYPE_ANALOG_3CH 43 //analog RGB @@ -257,11 +257,13 @@ #define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused) #define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus) -#define IS_DIGITAL(t) ((t) < 80 && ((t) & 0x10)) //digital are 16-31 and 48-63 -#define IS_PWM(t) ((t) > 40 && (t) < 46) -#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only -#define IS_2PIN(t) ((t) > 47) -#define IS_VIRTUAL(t) ((t) >= 80) +#define IS_TYPE_VALID(t) ((t) > 15 && (t) < 128) +#define IS_DIGITAL(t) (((t) > 15 && (t) < 40) || ((t) > 47 && (t) < 64)) //digital are 16-39 and 48-63 +#define IS_2PIN(t) ((t) > 47 && (t) < 64) +#define IS_16BIT(t) ((t) == TYPE_UCS8903 || (t) == TYPE_UCS8904) +#define IS_PWM(t) ((t) > 40 && (t) < 46) //does not include on/Off type +#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only +#define IS_VIRTUAL(t) ((t) >= 80 && (t) < 96) //this was a poor choice a better would be 96-111 //Color orders #define COL_ORDER_GRB 0 //GRB(w),defaut diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm old mode 100755 new mode 100644 index ae1063f7d..10605e0f9 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -16,11 +16,13 @@ function B(){window.open(getURL("/settings"),"_self");} function gId(n){return d.getElementById(n);} function off(n){d.getElementsByName(n)[0].value = -1;} - function isPWM(t) { return t > 40 && t < 46; } // is PWM type - function isAna(t) { return t == 40 || isPWM(t); } // is analog type - function isDig(t) { return t < 80 && (t & 0x10); }// is digital type - function isD2P(t) { return t > 47 && t < 64; } // is digital 2 pin type - function isVir(t) { return t >= 80; } // is virtual type + // these functions correspond to C macros found in const.h + function isPWM(t) { return t > 40 && t < 46; } // is PWM type + function isAna(t) { return t == 40 || isPWM(t); } // is analog type + function isDig(t) { return (t > 15 && t < 40) || isD2P(t); } // is digital type + function isD2P(t) { return t > 47 && t < 64; } // is digital 2 pin type + function is16b(t) { return t == 26 || t == 29 } // is digital 16 bit type + function isVir(t) { return t >= 80 && t < 96; } // is virtual type // https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript function loadJS(FILE_URL, async = true) { let scE = d.createElement("script"); @@ -175,25 +177,25 @@ } //returns mem usage function getMem(t, n) { + if (isAna(t)) return 5; // analog let len = parseInt(d.getElementsByName("LC"+n)[0].value); len += parseInt(d.getElementsByName("SL"+n)[0].value); // skipped LEDs are allocated too let dbl = 0; - if (d.Sf.LD.checked) dbl = len * 4; // double buffering - if (t < 32) { - if (t==26 || t==29) len *= 2; // 16 bit LEDs + let ch = 3; + let mul = 1; + if (isDig(t)) { + if (is16b(t)) len *= 2; // 16 bit LEDs + if (t > 28 && t < 40) ch = 4; //RGBW if (maxM < 10000 && d.getElementsByName("L0"+n)[0].value == 3) { //8266 DMA uses 5x the mem - if (t > 28) return len*20 + dbl; //RGBW - return len*15 + dbl; - } else if (maxM >= 10000) //ESP32 RMT uses double buffer? - { - if (t > 28) return len*8 + dbl; //RGBW - return len*6 + dbl; + mul = 5; } - if (t > 28) return len*4 + dbl; //RGBW - return len*3 + dbl; + if (maxM >= 10000) { //ESP32 RMT uses double buffer? + mul = 2; + } + if (d.Sf.LD.checked) dbl = len * ch; // double buffering } - if (t > 31 && t < 48) return 5; // analog - return len*3 + dbl; + if (isVir(t) && t == 88) ch = 4; + return len * ch * mul + dbl; } function UI(change=false)