From 36a0a240f98bed24dae9c1d75d86a482f502018b Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 1 Dec 2020 00:33:47 +0100 Subject: [PATCH 01/29] First progress in busmnger --- wled00/bus_manager.h | 135 +++++++++++++++++++++++++++++++++++++++++++ wled00/const.h | 10 ++++ 2 files changed, 145 insertions(+) create mode 100644 wled00/bus_manager.h diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h new file mode 100644 index 00000000..feac1dda --- /dev/null +++ b/wled00/bus_manager.h @@ -0,0 +1,135 @@ +#ifndef BusManager_h +#define BusManager_h + +/* + * Class for addressing various light types + */ + +#include "wled.h" + +class BusManager { + public: + BusManager() { + + }; + + int add(uint8_t busType, uint8_t* pins, uint16_t len = 1) { + if (numBusses >= WLED_MAX_BUSSES) return -1; + if (IS_DIGITAL(busType)) { + busses[numBusses] = new BusDigital(busType, pins, len); + } else { + busses[numBusses] = new BusPwm(busType, pins); + } + numBusses++; + return numBusses -1; + } + + void removeAll() { + for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; + numBusses = 0; + } + //void remove(uint8_t id); + + void show() { + for (uint8_t i = 0; i < numBusses; i++) { + busses[i]->show(); + } + } + + void setPixelColor(uint16_t pix, uint32_t c) { + for (uint8_t i = 0; i < numBusses; i++) { + Bus* b = busses[i]; + uint16_t bstart = b->getStart(); + if (pix < bstart) continue; + busses[i]->setPixelColor(pix - bstart, c); + } + } + + + private: + uint8_t numBusses = 0; + Bus* busses[WLED_MAX_BUSSES]; +}; + +//parent class of BusDigital and BusPwm +class Bus { + public: + Bus(uint8_t type) { + _type = type; + }; + + virtual void show() {} + + virtual void setPixelColor(uint16_t pix, uint32_t c) {}; + + virtual void setBrightness(uint8_t b) {}; + + virtual uint32_t getPixelColor(uint16_t pix) { return 0; }; + + virtual ~Bus() { //throw the bus under the bus + + } + + uint16_t getStart() { + return _start; + } + + void setStart(uint16_t start) { + _start = start; + } + + virtual uint8_t getColorOrder() { + return COL_ORDER_RGB; + } + + virtual void setColorOrder() {} + + uint8_t getType() { + return _type; + } + + protected: + uint8_t _type = TYPE_NONE; + uint16_t _start; +}; + +class BusDigital : public Bus { + public: + BusDigital(uint8_t type, uint8_t* pins, uint16_t len) : Bus(type) { + if (!IS_DIGITAL(type)) return; + _pins[0] = pins[0]; + if (IS_2PIN(type)) _pins[1] = pins[1]; + _len = len; + }; + + uint8_t getColorOrder() { + return _colorOrder; + } + + void setColorOrder(uint8_t colorOrder) { + if (colorOrder > 5) return; + _colorOrder = colorOrder; + } + + private: + uint8_t _colorOrder = COL_ORDER_GRB; + uint8_t _pins[2]; + uint16_t _len; +}; + +class BusPwm : public Bus { + public: + BusPwm(uint8_t type, uint8_t* pins) : Bus(type) { + if (!IS_ANALOG(type)) return; + uint8_t numPins = NUM_PWM_PINS(type); + if (numPins == 0) numPins = 1; + for (uint8_t i = 0; i < numPins; i++) { + _pins[i] = pins[i]; + } + }; + private: + uint8_t _pins[5]; + uint8_t _data[5]; +}; + +#endif diff --git a/wled00/const.h b/wled00/const.h index 421747a4..f69d3ecd 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -13,6 +13,12 @@ //increase if you need more #define WLED_MAX_USERMODS 4 +#ifdef ESP8266 +#define WLED_MAX_BUSSES 2 +#else +#define WLED_MAX_BUSSES 8 +#endif + //Usermod IDs #define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present #define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID @@ -103,6 +109,10 @@ #define TYPE_P9813 53 #define TYPE_TM1814 54 +#define IS_DIGITAL(t) (t & 0x10) //digital are 16-31 and 48-63 +#define IS_ANALOG(t) (t > 39 && t < 46) +#define NUM_PWM_PINS(t) (t - 40) //for analog PWM 40-45 only +#define IS_2PIN(t) (t > 47) //Color orders #define COL_ORDER_GRB 0 //GRB(w),defaut From 854501385e5cb766095f824bbe1a6c75c9973320 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 7 Dec 2020 01:39:42 +0100 Subject: [PATCH 02/29] Bus progress --- wled00/bus_manager.h | 128 ++++++++- wled00/bus_wrapper.h | 248 ++++++++++++++++++ wled00/const.h | 12 +- wled00/data/index.htm | 1 - wled00/fcn_declare.h | 5 + wled00/html_ui.h | 579 ++++++++++++++++++++--------------------- wled00/json.cpp | 3 +- wled00/pin_manager.cpp | 40 ++- wled00/wled.h | 1 - 9 files changed, 709 insertions(+), 308 deletions(-) create mode 100644 wled00/bus_wrapper.h diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index feac1dda..4cc16f0c 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -6,6 +6,7 @@ */ #include "wled.h" +#include "bus_wrapper.h" class BusManager { public: @@ -16,7 +17,7 @@ class BusManager { int add(uint8_t busType, uint8_t* pins, uint16_t len = 1) { if (numBusses >= WLED_MAX_BUSSES) return -1; if (IS_DIGITAL(busType)) { - busses[numBusses] = new BusDigital(busType, pins, len); + busses[numBusses] = new BusDigital(busType, pins, len, numBusses); } else { busses[numBusses] = new BusPwm(busType, pins); } @@ -45,6 +46,11 @@ class BusManager { } } + void setBrightness(uint8_t b) { + for (uint8_t i = 0; i < numBusses; i++) { + busses[i]->setBrightness(b); + } + } private: uint8_t numBusses = 0; @@ -62,7 +68,7 @@ class Bus { virtual void setPixelColor(uint16_t pix, uint32_t c) {}; - virtual void setBrightness(uint8_t b) {}; + virtual void setBrightness(uint8_t b) { _bri = b; }; virtual uint32_t getPixelColor(uint16_t pix) { return 0; }; @@ -88,20 +94,38 @@ class Bus { return _type; } + bool isOk() { + return _valid; + } + protected: uint8_t _type = TYPE_NONE; + uint8_t _bri = 255; uint16_t _start; + bool _valid = false; }; + class BusDigital : public Bus { public: - BusDigital(uint8_t type, uint8_t* pins, uint16_t len) : Bus(type) { - if (!IS_DIGITAL(type)) return; + BusDigital(uint8_t type, uint8_t* pins, uint16_t len, uint8_t nr) : Bus(type) { + if (!IS_DIGITAL(type) || !len) return; _pins[0] = pins[0]; if (IS_2PIN(type)) _pins[1] = pins[1]; _len = len; + _iType = PolyBus::getI(type, _pins, nr); + if (_iType == I_NONE) return; + _valid = true; }; + void show() { + PolyBus::show(_busPtr, _iType); + } + + void setPixelColor(uint16_t pix, uint32_t c) { + + } + uint8_t getColorOrder() { return _colorOrder; } @@ -113,23 +137,109 @@ class BusDigital : public Bus { private: uint8_t _colorOrder = COL_ORDER_GRB; - uint8_t _pins[2]; - uint16_t _len; + uint8_t _pins[2] = {255, 255}; + uint8_t _iType = I_NONE; + uint16_t _len = 0; + void * _busPtr = nullptr; }; + class BusPwm : public Bus { public: BusPwm(uint8_t type, uint8_t* pins) : Bus(type) { - if (!IS_ANALOG(type)) return; + if (!IS_PWM(type)) return; uint8_t numPins = NUM_PWM_PINS(type); - if (numPins == 0) numPins = 1; + + #ifdef ESP8266 + analogWriteRange(255); //same range as one RGB channel + analogWriteFreq(WLED_PWM_FREQ_ESP8266); + #else + _ledcStart = pinManager.allocateLedc(numPins); + if (_ledcStart == 255) { //no more free LEDC channels + deallocatePins(); return; + } + #endif + for (uint8_t i = 0; i < numPins; i++) { _pins[i] = pins[i]; + if (!pinManager.allocatePin(_pins[i])) { + deallocatePins(); return; + } + #ifdef ESP8266 + pinMode(_pins[i], OUTPUT); + #else + ledcSetup(_ledcStart + i, WLED_PWM_FREQ_ESP32, 8); + ledcAttachPin(_pins[i], _ledcStart + i); + #endif } + + _valid = true; }; + + void setPixelColor(uint16_t pix, uint32_t c) { + if (pix != 0 || !_valid) return; //only react to first pixel + uint8_t r = c >> 16; + uint8_t g = c >> 8; + uint8_t b = c ; + uint8_t w = c >> 24; + + switch (_type) { + case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value + _data[0] = max(r, max(g, max(b, w))); break; + + case TYPE_ANALOG_2CH: //warm white + cold white, we'll need some nice handling here, for now just R+G channels + case TYPE_ANALOG_3CH: //standard dumb RGB + case TYPE_ANALOG_4CH: //RGBW + case TYPE_ANALOG_5CH: //we'll want the white handling from 2CH here + RGB + _data[0] = r; _data[1] = g; _data[2] = b; _data[3] = w; _data[4] = 0; break; + + default: return; + } + } + + //does no index check + uint32_t getPixelColor(uint16_t pix) { + return ((_data[3] << 24) | (_data[0] << 16) | (_data[1] << 8) | (_data[2])); + } + + void show() { + uint8_t numPins = NUM_PWM_PINS(_type); + for (uint8_t i = 0; i < numPins; i++) { + uint8_t scaled = (_data[i] * _bri) / 255; + #ifdef ESP8266 + analogWrite(_pins[i], scaled); + #else + ledcWrite(_ledcStart + i, scaled); + #endif + } + } + + ~BusPwm() { + deallocatePins(); + }; + private: uint8_t _pins[5]; - uint8_t _data[5]; + uint8_t _data[5] = {255, 255, 255, 255, 255}; + #ifdef ARDUINO_ARCH_ESP32 + uint8_t _ledcStart = 255; + #endif + + void deallocatePins() { + uint8_t numPins = NUM_PWM_PINS(_type); + for (uint8_t i = 0; i < numPins; i++) { + if (!pinManager.isPinOk(_pins[i])) continue; + #ifdef ESP8266 + digitalWrite(_pins[i], LOW); //turn off PWM interrupt + #else + if (_ledcStart < 16) ledcDetachPin(_pins[i], _ledcStart + i); + #endif + pinManager.deallocatePin(_pins[i]); + } + #ifdef ARDUINO_ARCH_ESP32 + pinManager.deallocateLedc(_ledcStart, numPins); + #endif + } }; #endif diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h new file mode 100644 index 00000000..98b3c789 --- /dev/null +++ b/wled00/bus_wrapper.h @@ -0,0 +1,248 @@ +#ifndef BusWrapper_h +#define BusWrapper_h + +#include "wled.h" + +//Hardware SPI Pins +#define P_8266_HS_MOSI 13 +#define P_8266_HS_CLK 14 +#define P_32_HS_MOSI 13 +#define P_32_HS_CLK 14 +#define P_32_VS_MOSI 23 +#define P_32_VS_CLK 18 + +//The dirty list of possible bus types. Quite a lot... +#define I_NONE 0 +//ESP8266 RGB +#define I_8266_U0_NEO_3 1 +#define I_8266_U1_NEO_3 2 +#define I_8266_DM_NEO_3 3 +#define I_8266_BB_NEO_3 4 +//RGBW +#define I_8266_U0_NEO_4 5 +#define I_8266_U1_NEO_4 6 +#define I_8266_DM_NEO_4 7 +#define I_8266_BB_NEO_4 8 +//400Kbps +#define I_8266_U0_400_3 9 +#define I_8266_U1_400_3 10 +#define I_8266_DM_400_3 11 +#define I_8266_BB_400_3 12 +//TM1418 (RGBW) +#define I_8266_U0_TM1_4 13 +#define I_8266_U1_TM1_4 14 +#define I_8266_DM_TM1_4 15 +#define I_8266_BB_TM1_4 16 + +/*** ESP32 Neopixel methods ***/ +//RGB +#define I_32_R0_NEO_3 17 +#define I_32_R1_NEO_3 18 +#define I_32_R2_NEO_3 19 +#define I_32_R3_NEO_3 20 +#define I_32_R4_NEO_3 21 +#define I_32_R5_NEO_3 22 +#define I_32_R6_NEO_3 23 +#define I_32_R7_NEO_3 24 +#define I_32_I0_NEO_3 25 +#define I_32_I1_NEO_3 26 +//RGBW +#define I_32_R0_NEO_4 27 +#define I_32_R1_NEO_4 28 +#define I_32_R2_NEO_4 29 +#define I_32_R3_NEO_4 30 +#define I_32_R4_NEO_4 31 +#define I_32_R5_NEO_4 32 +#define I_32_R6_NEO_4 33 +#define I_32_R7_NEO_4 34 +#define I_32_I0_NEO_4 35 +#define I_32_I1_NEO_4 36 +//400Kbps +#define I_32_R0_400_3 37 +#define I_32_R1_400_3 38 +#define I_32_R2_400_3 39 +#define I_32_R3_400_3 40 +#define I_32_R4_400_3 41 +#define I_32_R5_400_3 42 +#define I_32_R6_400_3 43 +#define I_32_R7_400_3 44 +#define I_32_I0_400_3 45 +#define I_32_I1_400_3 46 +//TM1418 (RGBW) +#define I_32_R0_TM1_4 47 +#define I_32_R1_TM1_4 48 +#define I_32_R2_TM1_4 49 +#define I_32_R3_TM1_4 50 +#define I_32_R4_TM1_4 51 +#define I_32_R5_TM1_4 52 +#define I_32_R6_TM1_4 53 +#define I_32_R7_TM1_4 54 +#define I_32_I0_TM1_4 55 +#define I_32_I1_TM1_4 56 +//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S) + +//APA102 +#define I_HS_DOT_3 57 //hardware SPI +#define I_SS_DOT_3 58 //soft SPI + +//LPD8806 +#define I_HS_LPD_3 59 +#define I_SS_LPD_3 60 + +//WS2801 +#define I_HS_WS1_3 61 +#define I_SS_WS1_3 62 + +//P9813 +#define I_HS_P98_3 63 +#define I_SS_P98_3 64 + + +/*** ESP8266 Neopixel methods ***/ +#ifdef ESP8266 +//RGB +#define B_8266_U0_NEO_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio1 +#define B_8266_U1_NEO_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio2 +#define B_8266_DM_NEO_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio3 +#define B_8266_BB_NEO_3 NeoPixelBrightnessBus //3 chan, esp8266, bb (any pin) +//RGBW +#define B_8266_U0_NEO_4 NeoPixelBrightnessBus //4 chan, esp8266, gpio1 +#define B_8266_U1_NEO_4 NeoPixelBrightnessBus //4 chan, esp8266, gpio2 +#define B_8266_DM_NEO_4 NeoPixelBrightnessBus //4 chan, esp8266, gpio3 +#define B_8266_BB_NEO_4 NeoPixelBrightnessBus //4 chan, esp8266, bb (any pin) +//400Kbps +#define B_8266_U0_400_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio1 +#define B_8266_U1_400_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio2 +#define B_8266_DM_400_3 NeoPixelBrightnessBus //3 chan, esp8266, gpio3 +#define B_8266_BB_400_3 NeoPixelBrightnessBus //3 chan, esp8266, bb (any pin) +//TM1418 (RGBW) +#define B_8266_U0_TM1_4 NeoPixelBrightnessBus +#define B_8266_U1_TM1_4 NeoPixelBrightnessBus +#define B_8266_DM_TM1_4 NeoPixelBrightnessBus +#define B_8266_BB_TM1_4 NeoPixelBrightnessBus +#endif + +/*** ESP32 Neopixel methods ***/ +#ifdef ARDUINO_ARCH_ESP32 +//RGB +#define B_32_R0_NEO_3 NeoPixelBrightnessBus +#define B_32_R1_NEO_3 NeoPixelBrightnessBus +#define B_32_R2_NEO_3 NeoPixelBrightnessBus +#define B_32_R3_NEO_3 NeoPixelBrightnessBus +#define B_32_R4_NEO_3 NeoPixelBrightnessBus +#define B_32_R5_NEO_3 NeoPixelBrightnessBus +#define B_32_R6_NEO_3 NeoPixelBrightnessBus +#define B_32_R7_NEO_3 NeoPixelBrightnessBus +#define B_32_I0_NEO_3 NeoPixelBrightnessBus +#define B_32_I1_NEO_3 NeoPixelBrightnessBus +//RGBW +#define B_32_R0_NEO_4 NeoPixelBrightnessBus +#define B_32_R1_NEO_4 NeoPixelBrightnessBus +#define B_32_R2_NEO_4 NeoPixelBrightnessBus +#define B_32_R3_NEO_4 NeoPixelBrightnessBus +#define B_32_R4_NEO_4 NeoPixelBrightnessBus +#define B_32_R5_NEO_4 NeoPixelBrightnessBus +#define B_32_R6_NEO_4 NeoPixelBrightnessBus +#define B_32_R7_NEO_4 NeoPixelBrightnessBus +#define B_32_I0_NEO_4 NeoPixelBrightnessBus +#define B_32_I1_NEO_4 NeoPixelBrightnessBus +//400Kbps +#define B_32_R0_400_3 NeoPixelBrightnessBus +#define B_32_R1_400_3 NeoPixelBrightnessBus +#define B_32_R2_400_3 NeoPixelBrightnessBus +#define B_32_R3_400_3 NeoPixelBrightnessBus +#define B_32_R4_400_3 NeoPixelBrightnessBus +#define B_32_R5_400_3 NeoPixelBrightnessBus +#define B_32_R6_400_3 NeoPixelBrightnessBus +#define B_32_R7_400_3 NeoPixelBrightnessBus +#define B_32_I0_400_3 NeoPixelBrightnessBus +#define B_32_I1_400_3 NeoPixelBrightnessBus +//TM1418 (RGBW) +#define B_32_R0_TM1_4 NeoPixelBrightnessBus +#define B_32_R1_TM1_4 NeoPixelBrightnessBus +#define B_32_R2_TM1_4 NeoPixelBrightnessBus +#define B_32_R3_TM1_4 NeoPixelBrightnessBus +#define B_32_R4_TM1_4 NeoPixelBrightnessBus +#define B_32_R5_TM1_4 NeoPixelBrightnessBus +#define B_32_R6_TM1_4 NeoPixelBrightnessBus +#define B_32_R7_TM1_4 NeoPixelBrightnessBus +#define B_32_I0_TM1_4 NeoPixelBrightnessBus +#define B_32_I1_TM1_4 NeoPixelBrightnessBus +//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S) + +#endif + +//APA102 +#define B_HS_DOT_3 NeoPixelBrightnessBus //hardware SPI +#define B_SS_DOT_3 NeoPixelBrightnessBus //soft SPI + +//LPD8806 +#define B_HS_LPD_3 NeoPixelBrightnessBus +#define B_SS_LPD_3 NeoPixelBrightnessBus + +//WS2801 +#define B_HS_WS1_3 NeoPixelBrightnessBus +#define B_SS_WS1_3 NeoPixelBrightnessBus + +//P9813 +#define B_HS_P98_3 NeoPixelBrightnessBus +#define B_SS_P98_3 NeoPixelBrightnessBus + +//handles pointer type conversion for all possible bus types +class PolyBus { + public: + static void show(void* busPtr, uint8_t busType) { + (static_cast*>(busPtr))->Show(); + }; + //gives back the internal type index (I_XX_XXX_X above) for the input + static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { + if (!IS_DIGITAL(busType)) return I_NONE; + if (IS_2PIN(busType)) { //SPI LED chips + bool isHSPI = false; + #ifdef ESP8266 + if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true; + #else + if (pins[0] == P_32_HS_MOSI && pins[1] == P_32_HS_CLK) isHSPI = true; + if (pins[0] == P_32_VS_MOSI && pins[1] == P_V2_HS_CLK) isHSPI = true; + #endif + uint8_t t = I_NONE; + switch (busType) { + case TYPE_APA102: t = I_SS_DOT_3; + case TYPE_LPD8806: t = I_SS_LPD_3; + case TYPE_WS2801: t = I_SS_WS1_3; + case TYPE_P9813: t = I_SS_P98_3; + } + if (t > I_NONE && isHSPI) t--; //hardware SPI has one smaller ID than software + return t; + } else { + #ifdef ESP8266 + uint8_t offset = pins[0] -1; //for driver: 0 = uart0, 1 = uart1, 2 = dma, 3 = bitbang + if (offset > 3) offset = 3; + switch (busType) { + case TYPE_WS2812_RGB: + case TYPE_WS2812_WWA: + return I_8266_U0_NEO_3 + offset; + case TYPE_SK6812_RGBW: + return I_8266_U0_NEO_4 + offset; + case TYPE_WS2811_400KHZ: + return I_8266_U0_400_3 + offset; + } + #else //ESP32 + uint8_t offset = num; //RMT bus # == bus index in BusManager + if (offset > 9) return I_NONE; + switch (busType) { + case TYPE_WS2812_RGB: + case TYPE_WS2812_WWA: + return I_32_R0_NEO_3 + offset; + case TYPE_SK6812_RGBW: + return I_32_R0_NEO_4 + offset; + case TYPE_WS2811_400KHZ: + return I_32_R0_400_3 + offset; + } + #endif + } + return I_NONE; + } +}; + +#endif \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index 8c821cfc..3b74bb6f 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -95,6 +95,7 @@ #define TYPE_WS2812_RGB 22 #define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern) #define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units +#define TYPE_TM1814 25 #define TYPE_SK6812_RGBW 30 //"Analog" types (PWM) (32-47) #define TYPE_ONOFF 40 //binary output (relays etc.) @@ -108,11 +109,10 @@ #define TYPE_APA102 51 #define TYPE_LPD8806 52 #define TYPE_P9813 53 -#define TYPE_TM1814 54 #define IS_DIGITAL(t) (t & 0x10) //digital are 16-31 and 48-63 -#define IS_ANALOG(t) (t > 39 && t < 46) -#define NUM_PWM_PINS(t) (t - 40) //for analog PWM 40-45 only +#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) //Color orders @@ -181,7 +181,11 @@ #define E131_MAX_UNIVERSE_COUNT 9 -#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit +#define ABL_MILLIAMPS_DEFAULT 850 // auto lower brightness to stay close to milliampere limit + +// PWM settings +#define WLED_PWM_FREQ_ESP8266 880 //PWM frequency proven as good for LEDs +#define WLED_PWM_FREQ_ESP32 5000 #define TOUCH_THRESHOLD 32 // limit to recognize a touch, higher value means more sensitive diff --git a/wled00/data/index.htm b/wled00/data/index.htm index c8837d0f..c07ac747 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -1905,7 +1905,6 @@ function requestJson(command, rinfo = true, verbose = true) { nlTar = s.nl.tbri; nlFade = s.nl.fade; syncSend = s.udpn.send; - savedPresets = s.pss; currentPreset = s.ps; d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true; d.getElementById('cycs').value = s.ccnf.min; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 52f2ff34..bbf228d8 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -155,6 +155,7 @@ class PinManagerClass { uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits #else uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits + uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels #endif public: @@ -162,6 +163,10 @@ class PinManagerClass { bool allocatePin(byte gpio, bool output = true); bool isPinAllocated(byte gpio); bool isPinOk(byte gpio, bool output = true); + #ifdef ARDUINO_ARCH_ESP32 + byte allocateLedc(byte channels); + void deallocateLedc(byte pos, byte channels); + #endif }; //playlist.cpp diff --git a/wled00/html_ui.h b/wled00/html_ui.h index a579f49c..a1bebb73 100644 --- a/wled00/html_ui.h +++ b/wled00/html_ui.h @@ -7,7 +7,7 @@ */ // Autogenerated from wled00/data/index.htm, do not edit!! -const uint16_t PAGE_index_L = 34148; +const uint16_t PAGE_index_L = 34141; const uint8_t PAGE_index[] PROGMEM = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xdc, 0xbd, 0x69, 0x7b, 0xe2, 0x48, 0xd2, 0x28, 0xfa, 0xfd, 0xfc, 0x0a, 0x8a, 0x9a, 0xa9, 0x46, 0x85, 0x00, 0xb1, 0x1a, 0xe3, 0xa2, @@ -1855,293 +1855,292 @@ const uint8_t PAGE_index[] PROGMEM = { 0xca, 0xb0, 0xb8, 0x50, 0x7a, 0x9a, 0xb3, 0x19, 0x10, 0x47, 0x86, 0x2d, 0xfa, 0xab, 0x44, 0x35, 0xa0, 0xc2, 0xaf, 0x52, 0xda, 0x8c, 0x4f, 0x1a, 0x3a, 0x0e, 0x2b, 0x25, 0x96, 0xa6, 0xb2, 0x8c, 0xc6, 0x4a, 0xc9, 0x73, 0xf8, 0xcd, 0xf1, 0x0c, 0x4c, 0x08, 0xd9, 0xa2, 0xbf, 0x9e, 0x65, 0x30, - 0x1c, 0xf8, 0xe2, 0xac, 0xe0, 0x3a, 0x52, 0x38, 0xa4, 0xec, 0xac, 0x28, 0x78, 0x7b, 0xae, 0xc5, - 0x67, 0xc5, 0x9c, 0xb6, 0x1d, 0xfa, 0xee, 0x0b, 0x29, 0x6f, 0x29, 0xd0, 0x07, 0xdd, 0xd1, 0xd1, - 0x61, 0xb2, 0x9f, 0x25, 0x70, 0x80, 0xa0, 0xc3, 0x18, 0xdd, 0x26, 0x89, 0xb1, 0xbe, 0x94, 0x72, - 0x36, 0x12, 0x16, 0x96, 0x9b, 0x0b, 0x50, 0x5b, 0xb8, 0x9a, 0xf7, 0x97, 0xf1, 0xaa, 0xbd, 0x7c, - 0xe4, 0x28, 0xcf, 0xb7, 0x20, 0xee, 0xf2, 0x65, 0xb3, 0x3c, 0x89, 0x82, 0x83, 0xd1, 0x70, 0x4b, - 0xa5, 0x6a, 0x2d, 0x5a, 0xb7, 0x31, 0x71, 0x35, 0x55, 0x4d, 0x4b, 0x0a, 0x51, 0x12, 0x62, 0xe4, - 0x0c, 0xe6, 0x3a, 0x33, 0x0e, 0xa2, 0xe1, 0x32, 0x77, 0xab, 0xf1, 0x4f, 0x6d, 0xaf, 0x26, 0xb7, - 0xfd, 0x78, 0xde, 0x65, 0xc3, 0x34, 0x54, 0xa6, 0x45, 0x78, 0x27, 0x83, 0x2d, 0x13, 0xe5, 0xce, - 0xd4, 0x2d, 0xca, 0x06, 0x3f, 0x6c, 0x17, 0x58, 0x0e, 0x42, 0xc8, 0xf5, 0xb0, 0xf8, 0xb9, 0xa5, - 0x01, 0x55, 0xf2, 0x84, 0x25, 0x11, 0x7d, 0x4a, 0x95, 0x5d, 0x55, 0xb1, 0x57, 0x91, 0x87, 0x2c, - 0xc5, 0x13, 0x7f, 0x5b, 0xe2, 0x90, 0xee, 0x68, 0xe7, 0x58, 0x2f, 0x3c, 0x4a, 0xc4, 0xdc, 0x01, - 0xb0, 0x6a, 0xbc, 0x18, 0x05, 0xa4, 0x44, 0xfb, 0xfb, 0xd6, 0x68, 0xc3, 0xd9, 0x59, 0xf4, 0x40, - 0xa4, 0x17, 0x65, 0x99, 0x98, 0x40, 0x49, 0x3c, 0x3e, 0xa2, 0xb7, 0x77, 0x25, 0x6d, 0xe4, 0x48, - 0x3b, 0x38, 0x67, 0xb3, 0x45, 0x8b, 0x99, 0x4a, 0x35, 0x0b, 0x47, 0x45, 0x86, 0x32, 0x15, 0x63, - 0x3f, 0x55, 0xef, 0xb9, 0x72, 0x0f, 0xb0, 0xc2, 0xc9, 0x60, 0xe8, 0x62, 0x6b, 0x85, 0x3f, 0xa0, - 0x37, 0xd2, 0xd4, 0x22, 0x3b, 0xc2, 0xda, 0xe7, 0xca, 0xc7, 0x72, 0xc7, 0xaa, 0x71, 0xbf, 0xb8, - 0xdd, 0xca, 0x3d, 0x2c, 0x9d, 0x93, 0x55, 0x29, 0xbe, 0x6d, 0xed, 0xe7, 0xf7, 0x68, 0xd8, 0xa4, - 0x7e, 0xa7, 0x1a, 0xcf, 0x39, 0xee, 0xcf, 0x19, 0x34, 0xd8, 0x7a, 0x4d, 0xcf, 0x59, 0x90, 0x34, - 0x24, 0x64, 0x97, 0x46, 0xeb, 0x7b, 0x16, 0x85, 0x50, 0x9a, 0x0f, 0xf3, 0x34, 0x49, 0xbe, 0xd0, - 0xad, 0xca, 0x4e, 0xe0, 0x72, 0x18, 0x89, 0x2f, 0x74, 0x8b, 0xb2, 0xad, 0x61, 0x8e, 0x98, 0xce, - 0xe1, 0x26, 0x06, 0xa3, 0xfe, 0x2b, 0x89, 0x12, 0xd2, 0xe5, 0xf4, 0x39, 0xbc, 0x05, 0xe9, 0x47, - 0xf8, 0xe7, 0x5e, 0x55, 0xe0, 0xa6, 0xe0, 0x9f, 0x79, 0x6e, 0x7b, 0xa0, 0xb2, 0x20, 0xae, 0xae, - 0x4a, 0xfb, 0xb6, 0xaf, 0x98, 0xf4, 0x40, 0xa2, 0xfb, 0xd2, 0xe1, 0xd8, 0xaa, 0x08, 0x9b, 0x67, - 0x32, 0x13, 0xf8, 0x62, 0x0a, 0xbd, 0x20, 0x29, 0xe6, 0xda, 0xaa, 0x77, 0xcf, 0xbe, 0x09, 0xad, - 0x34, 0x30, 0xb2, 0x1b, 0x40, 0xd3, 0xf8, 0x68, 0x95, 0xae, 0x2f, 0x17, 0xa8, 0xb3, 0x0b, 0x23, - 0xf4, 0x40, 0x44, 0x5e, 0x2d, 0x6d, 0xfe, 0xdb, 0x5b, 0x39, 0xb0, 0x5b, 0xf9, 0xb2, 0x88, 0x94, - 0xc2, 0x03, 0x98, 0xb2, 0x72, 0xf0, 0x4c, 0xe1, 0x54, 0x88, 0xa0, 0x45, 0xb7, 0x78, 0xf1, 0xd6, - 0xda, 0xd2, 0x6b, 0xbb, 0xa5, 0xb7, 0xd6, 0x10, 0x64, 0x8c, 0x90, 0x45, 0x50, 0x88, 0x34, 0x84, - 0x7d, 0x22, 0x9a, 0x35, 0x1b, 0xd9, 0x68, 0xc4, 0x59, 0xc7, 0x30, 0xaa, 0x46, 0xd3, 0x2a, 0x91, - 0x0f, 0x2b, 0x74, 0x4c, 0x82, 0x0a, 0x77, 0xd4, 0x74, 0x75, 0xa8, 0xb1, 0xa3, 0x3f, 0xe4, 0xbd, - 0xd7, 0xe2, 0xbe, 0xb7, 0xf1, 0xdd, 0xb7, 0x9a, 0xa4, 0x59, 0x57, 0x51, 0xc6, 0x78, 0x4f, 0x47, - 0xdf, 0x25, 0x7d, 0x99, 0x98, 0x4e, 0x7f, 0x23, 0xc9, 0x3a, 0x5d, 0xc1, 0x18, 0x30, 0x83, 0xe4, - 0x66, 0x48, 0xb5, 0xf7, 0x88, 0x6d, 0x77, 0x5f, 0xd5, 0xdd, 0xe5, 0xe9, 0x48, 0xc5, 0xa7, 0x32, - 0xfa, 0x29, 0x68, 0xcc, 0x11, 0xee, 0x93, 0xa0, 0xfb, 0x94, 0x48, 0xd0, 0x58, 0x5e, 0xd8, 0x83, - 0x3f, 0x4a, 0x25, 0x42, 0xca, 0xfb, 0x47, 0x75, 0x74, 0x5c, 0xa0, 0xd0, 0x94, 0xcb, 0xf0, 0x3c, - 0x7d, 0xf1, 0x4f, 0x54, 0x62, 0x72, 0x50, 0x13, 0x72, 0xd6, 0xa5, 0xd3, 0xfe, 0xe3, 0x7b, 0x16, - 0x2b, 0x4e, 0xc4, 0x10, 0x15, 0x87, 0x38, 0x32, 0x0f, 0x56, 0x9d, 0xb7, 0xa1, 0x1c, 0x12, 0x2d, - 0x30, 0xf9, 0x9a, 0x9e, 0x98, 0x08, 0xe6, 0x25, 0xfc, 0xe5, 0x2c, 0x10, 0x50, 0x36, 0x68, 0x05, - 0x46, 0xf7, 0xcd, 0x17, 0x7e, 0x2d, 0x68, 0xa3, 0x4d, 0x03, 0x0c, 0xc5, 0x2c, 0x22, 0x38, 0xd0, - 0x5e, 0xbe, 0xdf, 0xf1, 0xed, 0x3b, 0x7f, 0x85, 0xd5, 0x55, 0x02, 0x58, 0x95, 0xc8, 0x85, 0x01, - 0x6d, 0x36, 0xdf, 0x80, 0x1b, 0xbc, 0x8f, 0x50, 0xf1, 0x5c, 0x8c, 0xe4, 0xb3, 0xa7, 0x7e, 0x6b, - 0x93, 0x13, 0x7d, 0x45, 0xd1, 0x40, 0x56, 0xe7, 0x47, 0x74, 0x8e, 0x66, 0xfc, 0xa0, 0xfb, 0x33, - 0xb9, 0x1f, 0xaf, 0xa2, 0xf2, 0x26, 0xcd, 0xaf, 0x18, 0x5f, 0xab, 0xf4, 0x86, 0x1a, 0xc7, 0x75, - 0x49, 0x3e, 0xce, 0x20, 0xee, 0xeb, 0xa1, 0xb8, 0x47, 0x8e, 0xa5, 0x18, 0xe3, 0xe4, 0x0f, 0xfd, - 0x70, 0x0f, 0x22, 0x49, 0x57, 0x97, 0x50, 0x08, 0xfb, 0x69, 0x41, 0x13, 0x0a, 0x73, 0x84, 0x28, - 0x14, 0xe8, 0xe0, 0x87, 0x1a, 0x13, 0xe3, 0x4b, 0x8d, 0x52, 0x4a, 0xea, 0x3e, 0x51, 0x27, 0xc9, - 0x7f, 0x39, 0x0b, 0xee, 0x36, 0x4a, 0x76, 0x44, 0x2e, 0x1e, 0x3f, 0xae, 0xe3, 0xe8, 0x46, 0xaf, - 0x0c, 0x7a, 0xbb, 0x60, 0x0f, 0xff, 0xb6, 0xa8, 0xc0, 0x65, 0x05, 0xa7, 0xba, 0x1a, 0x6a, 0xf9, - 0xad, 0xf1, 0x99, 0x59, 0x51, 0x88, 0x41, 0xfb, 0xde, 0x34, 0x7d, 0x93, 0x55, 0xb3, 0x17, 0x63, - 0x4f, 0xff, 0xf6, 0x1e, 0x86, 0x80, 0xa2, 0x2c, 0xea, 0x7e, 0x29, 0xfc, 0x7d, 0x30, 0xc5, 0x00, - 0xf0, 0xd3, 0x24, 0x58, 0x5d, 0x6d, 0xbf, 0xe6, 0x72, 0xdc, 0xb3, 0x49, 0xf0, 0xab, 0x17, 0x5c, - 0x3a, 0xd8, 0x9a, 0x0b, 0x7f, 0x74, 0xc2, 0x50, 0xb8, 0x93, 0x2f, 0x3d, 0xec, 0xf1, 0x2f, 0x73, - 0x1f, 0xe4, 0x38, 0x94, 0xa8, 0x13, 0x4c, 0x5b, 0x68, 0x4b, 0xc8, 0x6a, 0xb9, 0x20, 0x91, 0xad, - 0xed, 0x7e, 0x25, 0xd2, 0x86, 0x80, 0x0f, 0xcd, 0xf1, 0xeb, 0xa6, 0x2b, 0x18, 0xa8, 0x8e, 0x7b, - 0x19, 0x5c, 0xa1, 0xf4, 0x6b, 0xc5, 0xb6, 0xa0, 0xe8, 0x40, 0x43, 0xb7, 0xed, 0x5c, 0xe5, 0xfe, - 0x37, 0xe3, 0xa5, 0xdb, 0x72, 0xf1, 0x5e, 0xa9, 0xb8, 0x3f, 0x32, 0x96, 0x17, 0x5a, 0x12, 0xa1, - 0xfa, 0xc7, 0xfa, 0x34, 0xeb, 0x73, 0xcf, 0x99, 0xa4, 0xf8, 0xad, 0x71, 0x1e, 0xb6, 0xb8, 0x78, - 0xae, 0xa2, 0x1b, 0x53, 0x40, 0x7c, 0x8a, 0x6e, 0x94, 0x59, 0x9e, 0xa8, 0xc2, 0xd4, 0x74, 0x57, - 0xd0, 0xf1, 0x07, 0x1a, 0xbe, 0x04, 0xda, 0x75, 0x40, 0x5b, 0x74, 0xb7, 0xd9, 0x92, 0xdb, 0xc6, - 0xde, 0xbb, 0xfa, 0x0a, 0xec, 0xe6, 0x2c, 0x60, 0x5b, 0x94, 0x3f, 0xd0, 0xcb, 0x4e, 0xb6, 0xdb, - 0x15, 0x5c, 0xfc, 0x3e, 0xd7, 0x81, 0x55, 0xd1, 0x66, 0xc8, 0x5d, 0x69, 0xbc, 0x66, 0x6b, 0xfe, - 0x2f, 0x01, 0xf8, 0xf7, 0x78, 0x12, 0x58, 0x69, 0xdf, 0x0c, 0xb4, 0x6d, 0xce, 0x6f, 0x9b, 0xa2, - 0x57, 0x6d, 0xd1, 0xdb, 0xa0, 0x25, 0x9b, 0x74, 0x03, 0x00, 0x88, 0xc8, 0x80, 0x3a, 0x32, 0x16, - 0xfa, 0x16, 0x2b, 0x6a, 0x90, 0xe9, 0x92, 0xb9, 0x6d, 0x4a, 0x5d, 0xe9, 0xc3, 0x65, 0x55, 0x5d, - 0x1d, 0xd1, 0x51, 0xc5, 0xa6, 0xd4, 0x61, 0x6e, 0x5d, 0x37, 0xbc, 0x6d, 0xb9, 0xe3, 0x74, 0xdb, - 0xc7, 0x3a, 0x9c, 0xc9, 0xac, 0xee, 0xc4, 0x7d, 0x75, 0x39, 0xbb, 0x43, 0x7c, 0x50, 0x10, 0x83, - 0xfd, 0xd8, 0x1a, 0x8a, 0x66, 0x4f, 0x48, 0x24, 0x55, 0xf4, 0x50, 0x51, 0xf8, 0xc5, 0x03, 0x19, - 0xbd, 0x0a, 0x68, 0x20, 0x6f, 0x67, 0x33, 0xb5, 0xe0, 0x9b, 0x8a, 0xdc, 0x3f, 0x30, 0x16, 0x04, - 0xe4, 0xb3, 0x0a, 0x37, 0xa4, 0x82, 0x72, 0xa1, 0xcf, 0x9d, 0x6d, 0x41, 0x8d, 0xb1, 0x4c, 0xb4, - 0x15, 0x7f, 0x56, 0xde, 0x96, 0x42, 0xd2, 0xb2, 0xe5, 0x9e, 0x5e, 0x62, 0x91, 0x60, 0x8d, 0x31, - 0x70, 0x97, 0x19, 0x1a, 0x96, 0x4d, 0x48, 0x8a, 0x43, 0xc2, 0xe5, 0x7b, 0xec, 0xc9, 0xf3, 0x03, - 0x43, 0xb3, 0xdd, 0xf8, 0x64, 0xe8, 0xbf, 0x51, 0xde, 0xe8, 0xac, 0xfc, 0xa6, 0x38, 0x73, 0x8b, - 0x34, 0xc1, 0xa7, 0x7b, 0xbd, 0xef, 0x29, 0x92, 0x2d, 0x72, 0xbe, 0x7e, 0xbf, 0xef, 0x0d, 0x54, - 0x14, 0x15, 0x9b, 0x2c, 0x43, 0x3b, 0xf2, 0x04, 0x3f, 0xef, 0x32, 0xde, 0x02, 0x77, 0x51, 0x81, - 0xdb, 0x80, 0x65, 0x41, 0xa5, 0x83, 0x2f, 0x6d, 0xac, 0x81, 0x7d, 0x4d, 0x5c, 0xe3, 0x1a, 0x18, - 0x9f, 0x81, 0xea, 0x52, 0x39, 0xe9, 0x26, 0x11, 0x1e, 0x99, 0x28, 0x06, 0x0e, 0xa9, 0x22, 0x40, - 0xa6, 0xb2, 0xe0, 0xe4, 0xb9, 0xf3, 0x4d, 0xed, 0x87, 0x4c, 0xdc, 0x15, 0xb2, 0xbc, 0x1f, 0x75, - 0x30, 0x1b, 0x38, 0x16, 0x2e, 0x38, 0x10, 0x0d, 0xec, 0x7d, 0xbf, 0x80, 0xd8, 0x27, 0xf5, 0x66, - 0x32, 0x8d, 0xb6, 0x80, 0x2d, 0x26, 0xf0, 0x34, 0xac, 0xb0, 0x28, 0x2f, 0x2b, 0xbe, 0x78, 0xf0, - 0xf9, 0xbe, 0x30, 0x36, 0xf0, 0xb2, 0x53, 0xe8, 0x40, 0x99, 0xc0, 0xb3, 0xfd, 0xfb, 0x8e, 0xc6, - 0xef, 0xca, 0xf2, 0xdd, 0x31, 0x6f, 0x59, 0x7a, 0x60, 0x87, 0x35, 0x38, 0xe0, 0x61, 0xbe, 0xfd, - 0xfc, 0x41, 0xdd, 0x95, 0xaa, 0x1d, 0xcb, 0xc4, 0xd5, 0xa9, 0x72, 0x50, 0xab, 0x76, 0x90, 0xc5, - 0x95, 0x60, 0x3b, 0xd4, 0xb3, 0x63, 0x5e, 0xb2, 0x74, 0x64, 0xf7, 0x39, 0xe2, 0x3e, 0x1f, 0x76, - 0x2f, 0xf8, 0xc0, 0xcf, 0x29, 0xc2, 0x39, 0x53, 0xbd, 0xec, 0x23, 0x9d, 0x6f, 0xb6, 0x23, 0x37, - 0x9e, 0x12, 0x72, 0x25, 0xe6, 0x24, 0x17, 0xda, 0xd1, 0x6b, 0xc0, 0xf6, 0x19, 0x78, 0x18, 0xc0, - 0x53, 0xa4, 0x35, 0x25, 0x09, 0x4c, 0x51, 0xa1, 0xb2, 0x1b, 0x84, 0xc5, 0xbf, 0x06, 0x42, 0x27, - 0xb2, 0x61, 0x61, 0x12, 0x58, 0x70, 0x4a, 0xf9, 0xf0, 0x9d, 0x70, 0x6e, 0x82, 0x36, 0xae, 0x66, - 0xf5, 0x3d, 0x4f, 0xef, 0x62, 0x26, 0x60, 0x9e, 0x24, 0x4b, 0xdc, 0x05, 0x0f, 0x0e, 0x87, 0xb4, - 0x2b, 0x8e, 0xe4, 0xba, 0x55, 0xa4, 0x1a, 0x8f, 0x9b, 0xf1, 0xfe, 0x36, 0x27, 0x6d, 0x00, 0xd2, - 0x38, 0xdc, 0xdc, 0x3a, 0x6e, 0x84, 0x65, 0x42, 0x1d, 0xc8, 0x67, 0xed, 0xc7, 0xb5, 0x95, 0x5f, - 0xab, 0x8d, 0x47, 0x2f, 0x20, 0xc2, 0x04, 0xaf, 0xb1, 0x02, 0x16, 0xd3, 0xa9, 0x51, 0xa7, 0x78, - 0xe6, 0x4a, 0xce, 0x5e, 0xe7, 0x9d, 0x9d, 0xc1, 0x9a, 0x45, 0xc9, 0xe7, 0x6e, 0xe7, 0x59, 0xfc, - 0xac, 0xf3, 0x20, 0x58, 0xca, 0x57, 0xe8, 0x3b, 0x19, 0xb5, 0x85, 0x00, 0xd0, 0xdd, 0x77, 0xc6, - 0x4a, 0x86, 0xe9, 0xec, 0x10, 0xa4, 0xca, 0x0e, 0xdc, 0xed, 0x9d, 0xbc, 0xc7, 0x37, 0x7c, 0x13, - 0xd3, 0xd4, 0xa6, 0x75, 0x09, 0x62, 0x84, 0x40, 0xc3, 0x58, 0xa6, 0xec, 0x18, 0x2b, 0x42, 0x8b, - 0x14, 0xb0, 0x04, 0x4d, 0x8d, 0xd5, 0x84, 0xaa, 0x20, 0xba, 0x9d, 0x1a, 0xa3, 0x05, 0xda, 0xea, - 0x08, 0x18, 0x3d, 0x00, 0x4d, 0x85, 0x3b, 0xb4, 0x8f, 0x5c, 0xb8, 0xb7, 0x38, 0x6b, 0xbb, 0x76, - 0x84, 0x07, 0x71, 0xec, 0x95, 0xee, 0x70, 0x2c, 0x4c, 0x37, 0x0f, 0x89, 0xe7, 0x28, 0x9d, 0x2b, - 0x14, 0x6b, 0xd1, 0xe3, 0x01, 0xe9, 0xfb, 0xf1, 0x3d, 0x6f, 0xc5, 0x43, 0x7f, 0x23, 0xdd, 0x83, - 0x8c, 0xac, 0xb2, 0xdd, 0xb6, 0x2f, 0x1b, 0x66, 0x1d, 0xc7, 0x2b, 0x33, 0xf6, 0x34, 0xfd, 0x11, - 0x31, 0x45, 0xcf, 0xf4, 0x6e, 0x82, 0xca, 0x7b, 0x7a, 0x6e, 0xa0, 0x4e, 0x61, 0x5b, 0x44, 0x95, - 0x6c, 0x37, 0x41, 0x85, 0xb7, 0xa7, 0xd8, 0x37, 0x46, 0xcc, 0x45, 0x7b, 0xe0, 0x4c, 0xda, 0xdc, - 0x2e, 0xf4, 0xcd, 0x90, 0xb3, 0xe3, 0x0b, 0xb9, 0x15, 0x38, 0x3c, 0x7b, 0xa0, 0x6d, 0xad, 0x1e, - 0xc0, 0x98, 0xac, 0xed, 0x2f, 0x41, 0xc9, 0x46, 0x0e, 0x1c, 0x8d, 0xec, 0xb5, 0xb5, 0x52, 0x8b, - 0x08, 0xac, 0xfc, 0xcf, 0xed, 0x88, 0x04, 0x4a, 0xd3, 0x82, 0x24, 0x35, 0x3e, 0xe3, 0xcb, 0x71, - 0x7c, 0xf5, 0x49, 0xbe, 0xf8, 0x34, 0x31, 0xae, 0x50, 0x6c, 0x7b, 0x3f, 0xfd, 0x0d, 0xef, 0x60, - 0x38, 0xb0, 0x10, 0xd6, 0x4a, 0xbc, 0x31, 0xda, 0x17, 0x14, 0xfe, 0x1b, 0xd4, 0x44, 0xca, 0x67, - 0xee, 0xb4, 0x2e, 0xe7, 0x41, 0xa5, 0x8b, 0x74, 0xcb, 0x2f, 0x34, 0xb2, 0xf9, 0x15, 0xc5, 0x76, - 0x43, 0xfa, 0xa8, 0x86, 0xec, 0xc6, 0x18, 0x94, 0x31, 0x40, 0xd1, 0x13, 0x0c, 0x1e, 0x36, 0xe9, - 0xd4, 0xaf, 0x59, 0x51, 0xb2, 0xeb, 0x40, 0x95, 0x35, 0xa0, 0xfe, 0xf7, 0x1d, 0x2b, 0x48, 0xb7, - 0x85, 0x55, 0x8f, 0x27, 0xdc, 0x3d, 0xac, 0xac, 0x99, 0x42, 0xd6, 0x91, 0xba, 0xb6, 0xda, 0x3c, - 0x8c, 0x02, 0x7a, 0x0d, 0x77, 0xcc, 0x6d, 0xd0, 0x77, 0x9a, 0xd1, 0x67, 0x9a, 0x19, 0x25, 0xda, - 0x76, 0xa7, 0x87, 0xff, 0x0f, 0xdc, 0x25, 0x14, 0xd9, 0x71, 0xef, 0xf0, 0x6f, 0x25, 0x95, 0x9b, - 0x85, 0x7f, 0x77, 0x26, 0xbb, 0x99, 0x4d, 0x76, 0x4d, 0xff, 0xbc, 0x9a, 0x6e, 0xd3, 0xc3, 0xa8, - 0x97, 0xab, 0x88, 0xc3, 0x81, 0x52, 0xf4, 0xcb, 0xe5, 0x3a, 0x29, 0x63, 0x90, 0xd1, 0x8d, 0xc3, - 0x22, 0xe4, 0xa8, 0x40, 0xac, 0xab, 0x48, 0xbd, 0x87, 0x61, 0x2e, 0x17, 0x29, 0x40, 0x8f, 0x32, - 0xd8, 0x2f, 0xce, 0x6d, 0x0f, 0x44, 0xd5, 0xf5, 0xfe, 0xfe, 0x0e, 0x93, 0x49, 0x93, 0x37, 0xfc, - 0x66, 0x72, 0x46, 0x17, 0x5a, 0x43, 0xce, 0xe8, 0x3e, 0xbb, 0x65, 0x8d, 0x41, 0xf6, 0x37, 0xac, - 0x31, 0xf4, 0xd7, 0x45, 0xd3, 0xbc, 0xeb, 0x6f, 0x06, 0xea, 0x87, 0xd8, 0x82, 0x69, 0x19, 0x6f, - 0x03, 0x69, 0x19, 0x7f, 0x03, 0x44, 0xcb, 0x18, 0x7e, 0x2c, 0xe3, 0xdf, 0xb3, 0xe6, 0xd1, 0x2d, - 0xdd, 0xc0, 0xd4, 0xda, 0x03, 0xa9, 0xed, 0xf7, 0x94, 0xeb, 0x7b, 0x71, 0xbe, 0xa3, 0xfa, 0xde, - 0xb8, 0x9f, 0xef, 0xd0, 0x07, 0xba, 0xb3, 0x8f, 0x77, 0x58, 0x2b, 0xe4, 0x67, 0x2a, 0xd7, 0xca, - 0xee, 0x70, 0xfc, 0x77, 0x37, 0x5e, 0xcd, 0xcc, 0x66, 0x5d, 0x87, 0x62, 0x7e, 0x5b, 0x31, 0xa7, - 0x82, 0xa2, 0xbb, 0x37, 0x2d, 0x6d, 0x6b, 0xbb, 0x6d, 0x9b, 0x0c, 0xfc, 0xcd, 0x82, 0x64, 0xeb, - 0xd8, 0xea, 0x56, 0xba, 0xdf, 0x3c, 0x3c, 0xc4, 0x71, 0x73, 0x74, 0x0f, 0xa1, 0xb4, 0x69, 0xb9, - 0xe2, 0xff, 0x2f, 0x5d, 0x7a, 0x21, 0x65, 0xe0, 0x15, 0x79, 0xb7, 0x7d, 0x4a, 0x8a, 0xdb, 0x5d, - 0x60, 0xaf, 0x5c, 0xb4, 0xfb, 0xdf, 0xbc, 0x04, 0xf4, 0xb5, 0xfb, 0x16, 0x40, 0xe2, 0x9d, 0x00, - 0x69, 0x5c, 0xe0, 0x7f, 0x3b, 0x30, 0x1f, 0x51, 0x0c, 0x69, 0xc2, 0x91, 0xe0, 0xb3, 0x0d, 0x22, - 0xfe, 0x96, 0x1b, 0xb3, 0xf7, 0xff, 0x74, 0x8c, 0x27, 0x4b, 0x50, 0x56, 0xda, 0x1f, 0xb5, 0xef, - 0x82, 0x0e, 0xcb, 0x1f, 0xbd, 0x17, 0x5a, 0xad, 0x8c, 0x31, 0x80, 0x93, 0x87, 0xf6, 0x36, 0x84, - 0x1f, 0x8c, 0x85, 0x3f, 0x7e, 0x80, 0x44, 0xb4, 0x29, 0x90, 0x8f, 0xfc, 0x2a, 0xb8, 0x7d, 0xb0, - 0x42, 0x64, 0x57, 0xa0, 0xf0, 0x5e, 0x0f, 0xd5, 0xa8, 0x10, 0x21, 0xe3, 0xfe, 0x8f, 0x13, 0xf2, - 0x46, 0x3d, 0xa8, 0xb4, 0x03, 0x1b, 0xe0, 0xa8, 0x90, 0x8e, 0x09, 0xcc, 0x0a, 0x9a, 0x3f, 0x76, - 0xee, 0x31, 0x9b, 0xec, 0x47, 0x19, 0x13, 0x3a, 0x33, 0xe1, 0xd9, 0x75, 0xfc, 0xf6, 0x67, 0x2a, - 0x60, 0x97, 0x8c, 0xd5, 0xc5, 0x36, 0x0f, 0x0f, 0x83, 0x41, 0xa7, 0x69, 0x09, 0x02, 0x3d, 0x3a, - 0xbd, 0x85, 0x9f, 0xd6, 0xe2, 0xe0, 0x1b, 0xef, 0x05, 0xa8, 0x88, 0xd6, 0xcb, 0x1f, 0x40, 0x36, - 0x18, 0xf9, 0xdc, 0x0c, 0x1d, 0x14, 0xd1, 0x95, 0x06, 0x28, 0xa8, 0xa9, 0x0b, 0x20, 0x47, 0xf5, - 0x4f, 0xed, 0x67, 0x86, 0xf2, 0xb6, 0x6c, 0x44, 0xdb, 0xff, 0x44, 0xef, 0x0d, 0x79, 0xbe, 0x7c, - 0x24, 0xdb, 0x8a, 0x51, 0x9f, 0x7d, 0xa8, 0xed, 0x78, 0x9b, 0xa3, 0x76, 0xe7, 0x60, 0xd7, 0x99, - 0xc4, 0xba, 0x70, 0xca, 0x83, 0x9b, 0x76, 0xb0, 0x82, 0x2c, 0xae, 0xdc, 0x30, 0xe9, 0xd0, 0xe4, - 0xb2, 0x63, 0x2b, 0x68, 0x2b, 0xb4, 0xa3, 0x0c, 0x86, 0x6a, 0xe1, 0xc5, 0xb1, 0xec, 0x99, 0x77, - 0x03, 0x6b, 0x00, 0x85, 0x1c, 0x28, 0x67, 0x0c, 0x94, 0xe0, 0x43, 0x39, 0x1a, 0x19, 0x29, 0xeb, - 0x9b, 0xa2, 0xfc, 0xab, 0x17, 0x04, 0x2a, 0x6f, 0x90, 0x51, 0x0c, 0x71, 0x4b, 0xa7, 0x27, 0xcd, - 0x9c, 0xa5, 0x95, 0x85, 0x65, 0xdf, 0x65, 0xbb, 0x14, 0x23, 0x2c, 0x31, 0x7a, 0x80, 0xfd, 0x38, - 0xef, 0x76, 0xee, 0x3b, 0xbe, 0x38, 0x01, 0x4e, 0xf0, 0x47, 0x40, 0x3a, 0xbd, 0x5b, 0x95, 0xc1, - 0xad, 0x34, 0x1d, 0x81, 0x23, 0x77, 0xb8, 0x06, 0x61, 0x6d, 0x49, 0x38, 0xb3, 0x81, 0xfb, 0x06, - 0xb0, 0x3c, 0x1e, 0xa5, 0xe7, 0xd7, 0x8d, 0xe6, 0xff, 0x08, 0xca, 0xf2, 0x68, 0x0e, 0x94, 0xb5, - 0xa0, 0xeb, 0xf8, 0x0c, 0xdf, 0xa8, 0x9b, 0x46, 0x73, 0x0c, 0x89, 0xb7, 0x4c, 0x67, 0xf1, 0xfc, - 0x0e, 0x97, 0x1f, 0xdd, 0xf6, 0x4b, 0xb5, 0x91, 0x03, 0xd8, 0x4a, 0xf8, 0x61, 0x9a, 0xeb, 0x94, - 0x66, 0xba, 0x16, 0x8f, 0xe3, 0x5e, 0x67, 0xc7, 0x53, 0xca, 0x6f, 0x5b, 0x6f, 0xd3, 0xc6, 0xf1, - 0x99, 0xab, 0x15, 0x5b, 0xab, 0x15, 0xcd, 0x6a, 0x1b, 0xde, 0xa8, 0xcf, 0x80, 0xbd, 0xc0, 0xaa, - 0xa7, 0xca, 0xb8, 0x72, 0x28, 0x89, 0x89, 0x31, 0xfb, 0xa4, 0xe3, 0x4c, 0xfc, 0xb4, 0x65, 0x75, - 0x7e, 0x4d, 0x1a, 0x8b, 0xf3, 0xa7, 0x4f, 0x95, 0x10, 0xd5, 0xd4, 0x26, 0x86, 0xe2, 0xc5, 0x46, - 0x7f, 0xfa, 0x24, 0x0d, 0xb0, 0x2c, 0x56, 0x26, 0xe3, 0xc5, 0x33, 0x0b, 0xd3, 0xcc, 0x0b, 0x38, - 0x87, 0xe1, 0x5e, 0x0e, 0xde, 0xc5, 0x8f, 0x3f, 0x48, 0x94, 0xfa, 0x56, 0xd4, 0xef, 0xb3, 0xec, - 0x03, 0x76, 0x05, 0x59, 0x72, 0x0e, 0x2a, 0x11, 0x91, 0x21, 0x53, 0x0f, 0xba, 0x35, 0x3f, 0xdd, - 0x92, 0x77, 0xbd, 0x25, 0x8f, 0xb6, 0x9a, 0xf3, 0xfa, 0xc4, 0xda, 0x50, 0xdd, 0x03, 0x76, 0xc7, - 0xd9, 0x27, 0xd8, 0x96, 0x70, 0xd1, 0x8f, 0xbd, 0x36, 0x42, 0x43, 0x03, 0xaf, 0x48, 0x06, 0xcc, - 0x5f, 0x45, 0x37, 0xc9, 0x1d, 0xdb, 0xe6, 0x6a, 0xaf, 0x25, 0x6f, 0xa3, 0xaf, 0xb5, 0x0d, 0x0b, - 0xf1, 0x6d, 0x58, 0x14, 0x53, 0x31, 0xd9, 0xd5, 0x1a, 0x38, 0x23, 0xbe, 0xb0, 0x6b, 0xc8, 0x39, - 0xd2, 0xb9, 0xda, 0x2f, 0xdc, 0x15, 0x3a, 0xbd, 0xf6, 0x4a, 0x60, 0xe3, 0xc0, 0xf8, 0xd9, 0xb9, - 0x97, 0xcd, 0x48, 0xc5, 0xd0, 0x2a, 0x8d, 0x54, 0x51, 0x1a, 0x9f, 0x1f, 0xb5, 0xf4, 0xde, 0xd0, - 0x8a, 0x28, 0xdb, 0x4c, 0xe9, 0x6c, 0x18, 0xb2, 0x5e, 0x64, 0x7a, 0xf4, 0xef, 0x7f, 0x8e, 0x30, - 0xcd, 0xe9, 0x5a, 0x0c, 0x9f, 0xce, 0x66, 0x87, 0x17, 0xb2, 0xf3, 0x64, 0x5e, 0x60, 0x17, 0x5c, - 0x06, 0xf9, 0x25, 0x5e, 0x19, 0xe3, 0x1b, 0xd7, 0x8d, 0xcc, 0x9b, 0x78, 0x56, 0x2e, 0x26, 0xde, - 0x8b, 0x03, 0x99, 0x49, 0xef, 0x08, 0xcc, 0xd8, 0x56, 0xb4, 0xd6, 0xd1, 0xa1, 0xa3, 0xa3, 0x5a, - 0x51, 0xd5, 0x95, 0x6a, 0xad, 0x96, 0x2d, 0x3b, 0x3b, 0x1c, 0xaa, 0x6c, 0x7a, 0xf4, 0x90, 0x1f, - 0x9b, 0x47, 0x19, 0xa4, 0xde, 0x71, 0xd5, 0x22, 0xb4, 0xc5, 0xe2, 0x44, 0xfb, 0x31, 0xb7, 0xda, - 0xbb, 0x7e, 0x8b, 0x1f, 0xf4, 0xc3, 0x5e, 0xc3, 0x14, 0x49, 0x03, 0xb8, 0xc7, 0xa2, 0xee, 0xd1, - 0x99, 0xbd, 0xef, 0x56, 0x23, 0xf0, 0xa8, 0xa7, 0x3f, 0x73, 0xd8, 0x4e, 0x94, 0x3c, 0xca, 0x91, - 0x66, 0xee, 0x17, 0x24, 0x8b, 0x16, 0xf4, 0xef, 0xf5, 0x18, 0x5d, 0xfd, 0x88, 0x30, 0x21, 0xb7, - 0x5f, 0x7f, 0xb1, 0x8a, 0x63, 0xab, 0xc2, 0xca, 0x4b, 0x97, 0x20, 0x1c, 0x3f, 0x15, 0x87, 0xf4, - 0xe8, 0xd2, 0x21, 0xcb, 0x79, 0xb3, 0x54, 0x12, 0x06, 0x54, 0x5c, 0x54, 0x2b, 0xd6, 0xeb, 0x3d, - 0x7f, 0xa9, 0x44, 0x43, 0xc0, 0x4f, 0x12, 0x09, 0x2e, 0x10, 0x4c, 0x8b, 0x2e, 0x57, 0xde, 0xe7, - 0x51, 0xf9, 0x40, 0x7b, 0xb2, 0x71, 0x35, 0x4a, 0xca, 0xd7, 0xc4, 0x51, 0x9f, 0xb3, 0x34, 0x51, - 0x4f, 0x4b, 0xf2, 0xd3, 0x94, 0xc3, 0xb6, 0x90, 0x29, 0x84, 0x45, 0x2b, 0xc4, 0x2a, 0x61, 0xc2, - 0x6e, 0x2e, 0xbf, 0xd4, 0xcb, 0xa6, 0x70, 0xfb, 0x84, 0xd2, 0x54, 0xfd, 0x2c, 0xdf, 0xb2, 0xd4, - 0xf3, 0x8d, 0xf0, 0xe5, 0x47, 0x95, 0x69, 0x2e, 0x7a, 0x1c, 0xfd, 0x79, 0x5b, 0x3b, 0x7f, 0x73, - 0xb5, 0x73, 0x59, 0x6f, 0xe7, 0xe0, 0xc1, 0x76, 0xde, 0xb9, 0xda, 0x99, 0xd6, 0xdb, 0x79, 0xde, - 0x86, 0x16, 0xeb, 0xdd, 0x77, 0xf3, 0xf4, 0x98, 0x8d, 0x96, 0x45, 0x74, 0x7b, 0x4a, 0x5e, 0x9f, - 0xea, 0x45, 0x31, 0x54, 0x34, 0x02, 0xf2, 0xd7, 0x53, 0x76, 0x06, 0xb5, 0x02, 0x5d, 0xdf, 0x38, - 0xa8, 0x9f, 0x5e, 0xa6, 0xe5, 0xfd, 0x50, 0x3e, 0xe0, 0x75, 0xd3, 0x2f, 0xd3, 0x53, 0x59, 0xf5, - 0x65, 0xcb, 0xaa, 0x82, 0x4e, 0x43, 0xdb, 0xe1, 0xa0, 0xcc, 0xdb, 0xcb, 0xad, 0xe6, 0x9d, 0x9d, - 0x8d, 0xb8, 0xab, 0x18, 0x80, 0xda, 0x74, 0xab, 0xdf, 0x7a, 0x0d, 0xb3, 0x7b, 0xf3, 0x32, 0x0a, - 0x43, 0x3c, 0xe7, 0x57, 0x89, 0xfb, 0x57, 0xd1, 0xdd, 0x7b, 0x7c, 0xc3, 0x11, 0xe3, 0xd1, 0x3c, - 0xf7, 0xc9, 0x47, 0x5e, 0xad, 0xea, 0x2a, 0x0c, 0x3a, 0xa7, 0x3e, 0x07, 0xdb, 0x91, 0x82, 0x9d, - 0xd9, 0xa8, 0xb6, 0xcf, 0x2c, 0xd5, 0xe9, 0x79, 0x09, 0x47, 0x41, 0x89, 0x67, 0x2d, 0xa9, 0xd7, - 0x57, 0x91, 0xf7, 0x27, 0xf2, 0xdf, 0xaf, 0xd4, 0x1b, 0xf6, 0x5e, 0xfa, 0xbe, 0xf3, 0x69, 0xa0, - 0x66, 0xed, 0xf9, 0x3c, 0x08, 0x86, 0xc3, 0xea, 0x8b, 0x99, 0x1c, 0x71, 0xc6, 0x86, 0xd1, 0xf7, - 0xeb, 0x20, 0x0f, 0x2b, 0x4b, 0xf7, 0xc0, 0x8d, 0x9d, 0xda, 0xc2, 0xcd, 0xb7, 0xaf, 0x4d, 0x83, - 0x1e, 0x52, 0x43, 0x6f, 0x5f, 0x80, 0xd5, 0xc2, 0xd3, 0xed, 0xab, 0xcc, 0x14, 0xae, 0x23, 0xe0, - 0x02, 0xdd, 0x33, 0x1e, 0xdf, 0xe7, 0x9b, 0xde, 0xe3, 0xfb, 0x4b, 0xfc, 0x67, 0xba, 0xf1, 0x2f, - 0x1e, 0x64, 0x4b, 0x3a, 0xaf, 0xc8, 0xad, 0xeb, 0xb0, 0x5d, 0x37, 0x6c, 0xd2, 0x46, 0xe7, 0xfc, - 0x72, 0xdf, 0x93, 0x27, 0x62, 0xfb, 0xde, 0x85, 0xc5, 0x3a, 0xf6, 0x6b, 0xc1, 0x70, 0x92, 0xa9, - 0x0d, 0x02, 0x1f, 0xcb, 0x5d, 0x45, 0x09, 0x50, 0x59, 0x71, 0xdd, 0xe9, 0x89, 0x0e, 0xfe, 0x33, - 0x92, 0x1e, 0xe0, 0x0f, 0x35, 0x5e, 0x67, 0xa3, 0x86, 0x5f, 0x48, 0x28, 0xf7, 0x26, 0x78, 0x90, - 0xab, 0x4d, 0xfe, 0x83, 0x7b, 0xe9, 0xd1, 0x2e, 0xac, 0xba, 0xae, 0x76, 0x82, 0x02, 0xf0, 0xf7, - 0xec, 0x8c, 0xb8, 0x72, 0x8f, 0x99, 0x2a, 0xff, 0x99, 0xf6, 0x2a, 0x10, 0x9c, 0xf7, 0xce, 0xf0, - 0xff, 0xcf, 0xcd, 0xf5, 0x06, 0x0b, 0x4f, 0x56, 0x00, 0xa9, 0x96, 0xa6, 0xa1, 0xda, 0x4e, 0xad, - 0xcb, 0xa6, 0xad, 0x73, 0x9b, 0xea, 0xe1, 0xe0, 0xe1, 0x1e, 0x76, 0xea, 0x44, 0xf7, 0xf0, 0x80, - 0xe4, 0xf0, 0xef, 0x53, 0x4d, 0xd2, 0xbb, 0x08, 0xa1, 0x5c, 0xca, 0x52, 0x33, 0x98, 0x43, 0x4d, - 0xfb, 0xad, 0x52, 0x19, 0x80, 0x8a, 0x8d, 0x64, 0xd5, 0x21, 0x71, 0x11, 0x3e, 0x9b, 0x8c, 0x5e, - 0x71, 0x6c, 0x91, 0x45, 0x78, 0xf2, 0x1c, 0x5f, 0x39, 0x58, 0x90, 0xe3, 0x98, 0x4c, 0x39, 0x80, - 0x14, 0x48, 0x78, 0x3e, 0x7c, 0xa9, 0x92, 0x26, 0x93, 0xd1, 0x8b, 0x17, 0x3e, 0xd5, 0x7c, 0x6e, - 0x27, 0x0e, 0x5f, 0xf9, 0xba, 0xb9, 0x47, 0x2e, 0xb6, 0x89, 0x0f, 0x1c, 0x2b, 0x1e, 0x1e, 0x4a, - 0x92, 0xbd, 0x58, 0x14, 0xf8, 0xe4, 0xfa, 0x22, 0xdc, 0x10, 0x9d, 0xff, 0xb9, 0x07, 0x62, 0xc7, - 0x9f, 0xfd, 0x0b, 0xf8, 0x7a, 0x2d, 0x87, 0x5c, 0x7d, 0xb4, 0xf7, 0x6f, 0x7f, 0x57, 0x4c, 0x48, - 0xbe, 0xb3, 0x8e, 0x89, 0x5d, 0x0f, 0xed, 0xb1, 0x8b, 0xf1, 0x60, 0x70, 0x19, 0x97, 0x8b, 0xf5, - 0x14, 0x5a, 0x5f, 0x0e, 0xde, 0xc6, 0x79, 0x98, 0xa6, 0xe9, 0x55, 0x1c, 0x0d, 0x30, 0xca, 0xc9, - 0xe0, 0x26, 0xbe, 0x8a, 0xbd, 0x0a, 0xc2, 0x60, 0x4f, 0xc9, 0xad, 0xab, 0x1d, 0x13, 0x39, 0x64, - 0x35, 0xff, 0x99, 0xb4, 0x61, 0x76, 0x64, 0x37, 0x2c, 0x5c, 0xb9, 0x5a, 0x9b, 0x96, 0xce, 0xc5, - 0x43, 0xa7, 0x04, 0x8a, 0xef, 0x88, 0xc0, 0x4f, 0xcb, 0xda, 0x78, 0x55, 0xf8, 0x42, 0xca, 0xaa, - 0x1c, 0xfd, 0xdf, 0xa7, 0xab, 0x79, 0x9c, 0x2f, 0xc5, 0xcf, 0xd1, 0x34, 0x4d, 0xf9, 0x30, 0x2f, - 0x01, 0xe4, 0xc3, 0x7a, 0xf5, 0x76, 0xaa, 0xfe, 0xca, 0xfc, 0x02, 0x4e, 0x70, 0xd8, 0xca, 0x40, - 0xab, 0x02, 0x2a, 0xc3, 0x3c, 0x75, 0x8d, 0x33, 0xc7, 0xe8, 0x9a, 0x36, 0x4f, 0x6f, 0x1b, 0x52, - 0xa1, 0xc7, 0xa3, 0x51, 0x71, 0xaa, 0x70, 0xf1, 0x3b, 0x46, 0x68, 0xb4, 0x15, 0x0a, 0x34, 0xd7, - 0x08, 0xeb, 0x60, 0x3b, 0x7b, 0x9a, 0xcf, 0x9d, 0x3d, 0xd1, 0xf4, 0xe9, 0xdb, 0x3e, 0xcf, 0xc9, - 0xa4, 0xce, 0xee, 0xd5, 0x6d, 0xeb, 0xb0, 0x27, 0xaf, 0xea, 0x94, 0xbd, 0x6a, 0x8f, 0xaf, 0xa2, - 0x29, 0xa8, 0x8b, 0x7d, 0xc7, 0x3e, 0xda, 0xe5, 0x8e, 0x9d, 0x5a, 0x1a, 0x7e, 0xc3, 0xa5, 0xba, - 0x7a, 0x5e, 0xa5, 0x17, 0xd8, 0xf4, 0x16, 0xf8, 0xc2, 0x8e, 0xe7, 0x3e, 0xb1, 0x22, 0x88, 0xf1, - 0xb9, 0xd4, 0x69, 0xdb, 0x89, 0x76, 0x2f, 0x0e, 0xcf, 0x06, 0xab, 0xaa, 0xdb, 0xc1, 0xc1, 0xd9, - 0x58, 0x64, 0xb7, 0x56, 0xb1, 0xe2, 0xaf, 0xb7, 0x57, 0x73, 0x19, 0x1f, 0xab, 0x04, 0xfe, 0x54, - 0x92, 0x08, 0x3f, 0xa3, 0x82, 0x3c, 0x77, 0xa0, 0x1e, 0x73, 0xd3, 0xa6, 0xf5, 0xe8, 0xb6, 0xb7, - 0x3f, 0x1a, 0xb6, 0xb8, 0xbe, 0xa2, 0xaa, 0x27, 0xc3, 0xb0, 0x6a, 0xae, 0xe8, 0x65, 0x36, 0x34, - 0xa4, 0xfa, 0xc5, 0x7d, 0xae, 0xe2, 0x30, 0xec, 0xbf, 0xb1, 0xc3, 0xbd, 0x8d, 0x1b, 0x21, 0xd5, - 0xdc, 0xd7, 0x09, 0x1a, 0x9d, 0x16, 0x69, 0xb1, 0xd2, 0x57, 0xeb, 0xf6, 0x76, 0xab, 0x24, 0x6d, - 0x69, 0x33, 0xe3, 0x12, 0x4e, 0x43, 0x0e, 0x32, 0x7e, 0xe0, 0x81, 0xdf, 0x24, 0xb5, 0x72, 0x5b, - 0x86, 0x6f, 0x29, 0x7c, 0x65, 0xbd, 0x8a, 0x97, 0x3a, 0x26, 0xb4, 0x6a, 0x23, 0x5b, 0x9a, 0xac, - 0xa9, 0x9e, 0x2d, 0xc5, 0x20, 0xfd, 0x8f, 0x4d, 0x6b, 0xb2, 0xca, 0x3b, 0x2e, 0xb5, 0xc3, 0x0b, - 0x6c, 0x26, 0xe1, 0xba, 0xa0, 0x87, 0xc9, 0xf3, 0xa2, 0xf5, 0x8d, 0x69, 0x7d, 0x53, 0xe7, 0xf9, - 0xfd, 0x69, 0xb2, 0xce, 0xbb, 0xee, 0xf3, 0x86, 0x67, 0xdd, 0x8a, 0xed, 0x54, 0x52, 0x5f, 0x5b, - 0xd9, 0xa5, 0x09, 0xc2, 0xc1, 0x00, 0x4b, 0xa0, 0x5a, 0xef, 0x97, 0x0f, 0xe2, 0x11, 0x9a, 0x25, - 0x95, 0xe2, 0xd7, 0xf7, 0xf6, 0xf3, 0xa5, 0xb5, 0x20, 0xa0, 0x7d, 0x8c, 0xa8, 0x1c, 0xc4, 0x2b, - 0x8c, 0xec, 0xd5, 0x13, 0xa8, 0x70, 0x7c, 0x41, 0xbb, 0x4f, 0x02, 0x8c, 0x44, 0xbf, 0xe6, 0x0e, - 0x42, 0xdb, 0xed, 0x50, 0x86, 0x8d, 0x81, 0x83, 0x3b, 0xf9, 0x8c, 0x9e, 0xaa, 0x27, 0x41, 0x24, - 0x06, 0x89, 0x5f, 0x81, 0x80, 0x70, 0x54, 0x43, 0x14, 0x46, 0xeb, 0x21, 0xd1, 0x5d, 0x1a, 0x53, - 0x03, 0x1f, 0x23, 0xe3, 0xbf, 0xd9, 0x97, 0x74, 0x0d, 0xf8, 0x2f, 0x28, 0x5e, 0x6a, 0x35, 0x09, - 0xdd, 0x8b, 0xc7, 0x22, 0x12, 0xf5, 0xc7, 0x15, 0xc3, 0xab, 0x6e, 0xe3, 0x99, 0xfa, 0x7a, 0x74, - 0xd1, 0xc4, 0x0e, 0x99, 0xaa, 0x03, 0x9b, 0x6a, 0x2f, 0x17, 0x35, 0xdc, 0xa2, 0xdb, 0x91, 0x96, - 0x97, 0x20, 0x8b, 0xc2, 0xe2, 0xb1, 0x33, 0xe2, 0x3c, 0xfd, 0xf5, 0xd7, 0x9b, 0x45, 0x14, 0x25, - 0xbf, 0xfe, 0x5a, 0x04, 0xd0, 0x38, 0x6d, 0x35, 0x2d, 0xe5, 0x78, 0x42, 0x7e, 0xfd, 0x95, 0xe8, - 0x73, 0x6b, 0x99, 0x4e, 0x25, 0x12, 0x2a, 0xe1, 0x53, 0x61, 0x47, 0x7a, 0xcb, 0xfe, 0x37, 0xc9, - 0xec, 0x1a, 0xbb, 0xed, 0x21, 0x21, 0xcb, 0x60, 0x1a, 0x72, 0x94, 0x22, 0xcf, 0x3f, 0xe3, 0x59, - 0x3a, 0x37, 0xae, 0xbc, 0xac, 0xe9, 0xfd, 0xf5, 0xbd, 0x23, 0xae, 0x6b, 0xb1, 0x84, 0x3d, 0x76, - 0x01, 0xb2, 0xf5, 0x5e, 0x57, 0x4f, 0x1c, 0xf9, 0x66, 0x36, 0xdc, 0x2f, 0x31, 0xd0, 0x89, 0xc1, - 0x76, 0x77, 0x4f, 0x16, 0x47, 0x3e, 0xe3, 0xc4, 0xfb, 0xec, 0xd6, 0x31, 0x1e, 0xb1, 0x0f, 0xe3, - 0xec, 0x09, 0xad, 0xd4, 0xa1, 0xc7, 0x84, 0x67, 0xb7, 0x40, 0x68, 0xb4, 0xd4, 0x70, 0xe7, 0x7e, - 0xd6, 0x2d, 0x9e, 0xce, 0x6e, 0x07, 0x37, 0xbe, 0x7e, 0x4c, 0xea, 0xc0, 0xd7, 0xbe, 0xc2, 0xdd, - 0xae, 0x24, 0xc1, 0x13, 0x7e, 0xd5, 0xb9, 0xe0, 0x50, 0x06, 0xf4, 0xd4, 0x33, 0x67, 0x1c, 0x03, - 0xc9, 0xee, 0xcb, 0x40, 0xa2, 0x7c, 0xcc, 0xe7, 0x35, 0x0c, 0x45, 0xe6, 0xf0, 0xdd, 0x1f, 0x1d, - 0x98, 0x84, 0xdf, 0x8b, 0x4f, 0xe4, 0x25, 0x72, 0x56, 0x24, 0x0f, 0x04, 0xdc, 0x32, 0x43, 0xa6, - 0x1b, 0x44, 0x10, 0xc5, 0xf2, 0xf2, 0xae, 0xdb, 0xd9, 0xdf, 0x8f, 0x01, 0xb3, 0x12, 0xb0, 0xfd, - 0x89, 0x8a, 0x47, 0x81, 0xa3, 0x1c, 0x01, 0x90, 0xf3, 0x23, 0xe3, 0x4a, 0xfb, 0x25, 0x98, 0x26, - 0xf1, 0xea, 0xaa, 0x90, 0xc3, 0xd0, 0x9b, 0x66, 0x5b, 0xc3, 0x73, 0x68, 0x78, 0x4e, 0xa5, 0x76, - 0x9e, 0x56, 0xbe, 0xb1, 0xf6, 0x35, 0xad, 0xe1, 0xda, 0x6d, 0x9c, 0x01, 0xc9, 0x47, 0x0e, 0xc6, - 0x84, 0x92, 0x15, 0x6a, 0x4f, 0x58, 0xba, 0x22, 0x1e, 0xfe, 0x0f, 0x54, 0x57, 0xea, 0xb7, 0xc7, - 0x9c, 0x02, 0x12, 0x6c, 0xf9, 0x35, 0x4f, 0x6f, 0x22, 0x60, 0x38, 0x96, 0x21, 0xcc, 0x04, 0x10, - 0xbd, 0x6a, 0x94, 0xdd, 0xca, 0xb8, 0x87, 0x32, 0x67, 0x8a, 0x39, 0x0e, 0xff, 0xb6, 0xb4, 0xac, - 0x35, 0x67, 0x57, 0xe6, 0x43, 0x3d, 0xba, 0xfa, 0x2d, 0x10, 0xb9, 0x2f, 0x2a, 0x5d, 0x65, 0xf5, - 0xae, 0xa4, 0xf7, 0x30, 0x91, 0x6a, 0xab, 0x17, 0xa0, 0xcc, 0xc6, 0x53, 0xfe, 0x3b, 0x8d, 0xb1, - 0xea, 0x73, 0x90, 0xef, 0xe4, 0xad, 0x2c, 0x95, 0x24, 0x1f, 0x5f, 0xf9, 0x93, 0x54, 0x84, 0xae, - 0x87, 0xeb, 0x3a, 0x59, 0xb8, 0x04, 0x68, 0x64, 0x31, 0xbe, 0x65, 0xa5, 0xdf, 0xb8, 0x79, 0x99, - 0xba, 0x1b, 0xad, 0x9c, 0x3a, 0x16, 0x23, 0x34, 0xe1, 0xc6, 0x60, 0xa9, 0xcd, 0xa5, 0x45, 0x32, - 0x11, 0x03, 0x88, 0x54, 0x5f, 0x29, 0x8e, 0x1a, 0x4a, 0xf5, 0x4d, 0x8c, 0x07, 0x35, 0x5d, 0x93, - 0x5a, 0xb6, 0x4c, 0xf0, 0x2b, 0xcc, 0x07, 0x0f, 0x0f, 0x40, 0x82, 0x5d, 0xfb, 0x59, 0x3b, 0x1b, - 0x18, 0x7c, 0x94, 0x4d, 0xc1, 0xcc, 0x72, 0x68, 0xf5, 0xe9, 0x36, 0x89, 0x0d, 0x04, 0x59, 0x22, - 0xc9, 0x35, 0xc4, 0x1a, 0xa9, 0x0f, 0xfd, 0x6d, 0x6e, 0x8d, 0x9f, 0x01, 0x6b, 0x35, 0xc7, 0x46, - 0x85, 0x8d, 0x5d, 0x42, 0xa0, 0xa6, 0xe6, 0x88, 0xb5, 0x60, 0xd2, 0xd1, 0x0d, 0x10, 0x98, 0xe1, - 0xfc, 0x12, 0x4f, 0x47, 0x59, 0x1f, 0x66, 0x07, 0x0a, 0x53, 0xa3, 0x43, 0xf4, 0x9f, 0x5e, 0x97, - 0xa9, 0xf7, 0x87, 0x69, 0xd3, 0xac, 0x5b, 0x52, 0xf2, 0x5b, 0xc0, 0xbf, 0xe9, 0xe0, 0xe9, 0xae, - 0x33, 0xee, 0xbc, 0xc0, 0x3f, 0x4a, 0xaf, 0x4c, 0x6b, 0xad, 0x41, 0x94, 0xfa, 0x4d, 0x4e, 0x38, - 0x62, 0x2f, 0x2b, 0x0e, 0x48, 0x94, 0x82, 0xe3, 0x40, 0xbf, 0x80, 0x74, 0x2e, 0xe8, 0x13, 0xc3, - 0x1c, 0x75, 0x52, 0xaa, 0xd1, 0xa1, 0x31, 0xbe, 0xcd, 0xf3, 0xe0, 0xae, 0x1f, 0x17, 0xf4, 0x97, - 0x1b, 0x69, 0x52, 0xfe, 0x32, 0x82, 0x9d, 0xf1, 0xbb, 0x28, 0xca, 0xba, 0xbc, 0x47, 0xf6, 0x44, - 0xbf, 0xdf, 0xc7, 0x48, 0x97, 0xa1, 0x0a, 0x1b, 0x45, 0x24, 0x27, 0x53, 0xe4, 0x2d, 0x8c, 0x8e, - 0x1c, 0xc9, 0x75, 0x58, 0x59, 0x8f, 0xa2, 0x05, 0x17, 0x43, 0x15, 0xa9, 0x2c, 0xaf, 0x83, 0x65, - 0x3d, 0xd2, 0x4b, 0x56, 0x0e, 0x8a, 0xab, 0x12, 0xf3, 0xd6, 0x69, 0x5c, 0xcb, 0x97, 0x5c, 0x95, - 0x2e, 0x81, 0xb8, 0x5d, 0xf9, 0x6c, 0xa9, 0xcc, 0xd7, 0x21, 0x59, 0xac, 0xe6, 0x38, 0x8b, 0xde, - 0x1c, 0xf5, 0xb5, 0x64, 0x4a, 0xa0, 0x73, 0x47, 0x9c, 0x53, 0x7b, 0xc7, 0x5e, 0x0d, 0xf9, 0x5e, - 0x50, 0xf6, 0x58, 0xdc, 0x6f, 0xc4, 0x46, 0x09, 0xa0, 0x75, 0xcc, 0x50, 0x91, 0x9e, 0xb0, 0x3b, - 0xaa, 0xdc, 0x84, 0xcb, 0x3e, 0x1f, 0xe8, 0xc1, 0xaa, 0xae, 0xbb, 0xda, 0xd8, 0xef, 0x03, 0x4a, - 0xcc, 0x6e, 0x9d, 0x17, 0x35, 0x8b, 0xda, 0xa7, 0xb9, 0x6d, 0x9f, 0x58, 0x01, 0xf1, 0x7e, 0x62, - 0xec, 0x4b, 0x5e, 0x1e, 0xcc, 0x66, 0xdf, 0xa3, 0x4a, 0x18, 0xf7, 0x8b, 0x08, 0xd8, 0x3a, 0x9d, - 0xd4, 0xa1, 0x19, 0x28, 0x88, 0x7f, 0x2c, 0xcb, 0x26, 0x6a, 0xb5, 0x59, 0x7c, 0x99, 0xa2, 0xbd, - 0x48, 0x7a, 0x83, 0x4d, 0xe3, 0xe6, 0x62, 0xd5, 0x70, 0x96, 0x2f, 0x51, 0x86, 0xa3, 0x13, 0x66, - 0xb3, 0xc2, 0xb6, 0x2e, 0xd2, 0x35, 0x56, 0x40, 0xb1, 0xe3, 0xa1, 0x1e, 0xa8, 0xf8, 0x3a, 0xdb, - 0xb1, 0x34, 0xc1, 0x13, 0xad, 0x66, 0xf5, 0xe2, 0xc7, 0x03, 0xd8, 0xd3, 0xe3, 0xac, 0x3c, 0x11, - 0xc7, 0x03, 0x0c, 0xdc, 0x88, 0x7f, 0x17, 0xe5, 0x32, 0x39, 0xf9, 0xbf, 0x67, 0xbc, 0xb2, 0xce, - 0x05, 0x95, 0x01, 0x00 + 0x1c, 0xf8, 0xe2, 0x5d, 0xb8, 0x16, 0x86, 0x15, 0xe6, 0xa2, 0x68, 0xdb, 0x88, 0xef, 0xbe, 0x90, + 0x8e, 0x96, 0xe2, 0x79, 0xd0, 0x55, 0x1c, 0x9d, 0x19, 0xfb, 0x59, 0x02, 0xe7, 0x04, 0x3a, 0x73, + 0xd1, 0xa5, 0x91, 0x18, 0xeb, 0xbb, 0x27, 0x67, 0x23, 0x61, 0x61, 0x79, 0xb3, 0x00, 0x51, 0x85, + 0xab, 0x79, 0x7f, 0x19, 0xaf, 0xda, 0xcb, 0x47, 0x8e, 0xf2, 0x7c, 0xd9, 0xe1, 0x2e, 0x5f, 0x36, + 0xcb, 0x93, 0xc4, 0x37, 0x18, 0x0d, 0xb7, 0x54, 0xaa, 0xd6, 0xa2, 0xe5, 0x19, 0x13, 0xf3, 0x52, + 0xd5, 0xb4, 0x40, 0x10, 0x25, 0x21, 0x06, 0xc8, 0x60, 0xe6, 0x32, 0xe3, 0x58, 0x19, 0x2e, 0xab, + 0xb6, 0x1a, 0x9b, 0xd4, 0x66, 0x69, 0x72, 0x77, 0x8f, 0xe7, 0x5d, 0xb6, 0x3f, 0x43, 0x9d, 0x59, + 0x84, 0x57, 0x2f, 0xd8, 0x32, 0x11, 0xe8, 0x4c, 0x5d, 0x96, 0x6c, 0xf0, 0xc3, 0xf6, 0x74, 0xe5, + 0x58, 0x83, 0x5c, 0x0f, 0x8b, 0x9f, 0x5b, 0x8a, 0x4e, 0x25, 0x36, 0x58, 0x82, 0xcf, 0xa7, 0x54, + 0x99, 0x4f, 0x15, 0x7b, 0x15, 0xb1, 0xc7, 0xd2, 0x2f, 0xf1, 0xb7, 0x25, 0xf5, 0xe8, 0x8e, 0x76, + 0x0e, 0xe9, 0xc2, 0xa3, 0x44, 0xcc, 0x1d, 0x00, 0x47, 0xc6, 0xfb, 0x4f, 0x40, 0x4a, 0xb4, 0xbf, + 0x6f, 0x8d, 0x36, 0x9c, 0x9d, 0x45, 0x0f, 0x04, 0x74, 0x51, 0x06, 0x88, 0x09, 0x94, 0xc4, 0x53, + 0x22, 0x3a, 0x75, 0x57, 0xd2, 0x46, 0x8e, 0xb4, 0x83, 0x73, 0xb6, 0x4e, 0xb4, 0x78, 0xa6, 0xd4, + 0xa6, 0x70, 0xf0, 0x63, 0x28, 0x53, 0xb1, 0xe9, 0x53, 0xf5, 0x9e, 0x2b, 0x2f, 0x00, 0x2b, 0x6a, + 0x0c, 0x46, 0x28, 0xb6, 0x16, 0xf2, 0x03, 0xea, 0x21, 0x4d, 0x2d, 0xb2, 0x23, 0xac, 0x7d, 0xae, + 0x5c, 0x29, 0x77, 0xac, 0x1a, 0xf7, 0x8b, 0xdb, 0xad, 0x4c, 0xc2, 0x52, 0x2d, 0x59, 0x95, 0xe2, + 0xdb, 0xd6, 0x7e, 0x7e, 0x8f, 0x22, 0x4d, 0xaa, 0x71, 0xaa, 0x61, 0x9b, 0xe3, 0xfe, 0x9c, 0x41, + 0x83, 0x1d, 0xd6, 0xf4, 0x9c, 0x05, 0x49, 0x43, 0x10, 0x76, 0x29, 0xae, 0xbe, 0x67, 0x89, 0x07, + 0x85, 0xf6, 0x30, 0x4f, 0x93, 0xe4, 0x0b, 0x5d, 0x9e, 0xec, 0x04, 0x2e, 0x47, 0x8b, 0xf8, 0x42, + 0x97, 0x25, 0xdb, 0x1a, 0xe6, 0xc0, 0xe8, 0x1c, 0x55, 0x62, 0x30, 0xea, 0xbf, 0x92, 0x28, 0x21, + 0x95, 0x4d, 0x9f, 0xa3, 0x58, 0x90, 0x1a, 0x84, 0x7f, 0xee, 0x55, 0xe5, 0x6a, 0x8a, 0xf1, 0x99, + 0xe7, 0xb6, 0xa3, 0x29, 0xcb, 0xdb, 0xea, 0x46, 0xb4, 0x6f, 0xbb, 0x84, 0x49, 0x47, 0x23, 0xba, + 0x16, 0x1d, 0x8e, 0xad, 0x8a, 0xb0, 0x47, 0x26, 0x33, 0x81, 0x0f, 0xa3, 0xd0, 0x43, 0x91, 0x62, + 0xae, 0x8d, 0x77, 0xf7, 0xec, 0x0b, 0xcf, 0x4a, 0x03, 0x23, 0xbb, 0x01, 0xb4, 0x80, 0x8f, 0x56, + 0xe9, 0xfa, 0x72, 0x81, 0xaa, 0xb9, 0x30, 0x42, 0x47, 0xc3, 0x02, 0xdd, 0x47, 0xd9, 0xb4, 0xbf, + 0xbd, 0x95, 0x03, 0xbb, 0x95, 0x2f, 0x8b, 0x48, 0xe9, 0x35, 0x80, 0x29, 0x2b, 0x3f, 0xce, 0x14, + 0x0e, 0x7f, 0x08, 0x5a, 0x74, 0x8b, 0xf7, 0x6b, 0xad, 0x2d, 0xbd, 0xb6, 0x5b, 0x7a, 0x6b, 0x0d, + 0x41, 0x86, 0x02, 0x59, 0x04, 0x85, 0x48, 0x43, 0xd8, 0x27, 0xa2, 0x59, 0xb3, 0x91, 0x8d, 0x46, + 0x9c, 0x75, 0xda, 0xa2, 0x6a, 0x34, 0xad, 0x12, 0xf9, 0xb0, 0x42, 0xc7, 0x24, 0x8f, 0x70, 0x47, + 0x4d, 0x8f, 0x86, 0x1a, 0x3b, 0xfa, 0x43, 0x4e, 0x7a, 0x2d, 0x5e, 0x7a, 0x1b, 0xdf, 0x7d, 0x79, + 0x49, 0x0a, 0x74, 0x15, 0x4c, 0x8c, 0xb7, 0x6e, 0x74, 0x51, 0xd2, 0x77, 0x86, 0xe9, 0xf4, 0x37, + 0x12, 0xa0, 0xd3, 0x15, 0x8c, 0x01, 0x33, 0x48, 0x3c, 0x86, 0x54, 0x7b, 0x8f, 0xd8, 0x76, 0xc5, + 0x55, 0xdd, 0x5d, 0x9e, 0x8e, 0x54, 0x18, 0x2a, 0xa3, 0x86, 0x82, 0xc6, 0x1c, 0x51, 0x3d, 0x09, + 0xba, 0x4f, 0x89, 0x04, 0x8d, 0xc5, 0x82, 0x3d, 0xf8, 0xa3, 0x34, 0x1f, 0xa4, 0xa3, 0x7f, 0x54, + 0x47, 0xc7, 0x05, 0xca, 0x46, 0xb9, 0x8c, 0xc2, 0xd3, 0x17, 0xff, 0x44, 0x5d, 0x25, 0xc7, 0x2e, + 0x21, 0x9f, 0x5c, 0x3a, 0xd4, 0x3f, 0xbe, 0x67, 0xe9, 0xe1, 0x44, 0x0c, 0x51, 0x3f, 0x88, 0x23, + 0xf3, 0x60, 0xd5, 0x79, 0x1b, 0xca, 0x21, 0x09, 0x02, 0x93, 0xaf, 0xe9, 0x25, 0x89, 0x60, 0x5e, + 0xc2, 0x5f, 0xce, 0x02, 0x39, 0x64, 0x83, 0xc6, 0x5e, 0x74, 0xad, 0x7c, 0xe1, 0xd7, 0x62, 0x33, + 0xda, 0x34, 0xc0, 0x50, 0xcc, 0x22, 0x82, 0x03, 0xcd, 0xe2, 0xfb, 0x1d, 0xdf, 0xbe, 0xda, 0x57, + 0x58, 0x5d, 0x25, 0x80, 0x55, 0x89, 0x5c, 0x18, 0xd0, 0x66, 0xf3, 0x0d, 0xb8, 0xc1, 0x6b, 0x07, + 0x15, 0xb6, 0xc5, 0x08, 0x38, 0x7b, 0xea, 0xb7, 0xb6, 0x2c, 0xd1, 0x37, 0x11, 0x0d, 0x64, 0x75, + 0x7e, 0x44, 0x1f, 0x68, 0xc6, 0x0f, 0x7a, 0x39, 0x93, 0x97, 0xf1, 0x2a, 0x2a, 0x6f, 0xd2, 0xfc, + 0x8a, 0xf1, 0xb5, 0x4a, 0x6f, 0xa8, 0x71, 0x5c, 0x97, 0xe4, 0xca, 0x0c, 0x52, 0xbd, 0x1e, 0x8a, + 0x7b, 0xe4, 0x58, 0x8a, 0x31, 0x4e, 0x6e, 0xcf, 0x0f, 0xf7, 0x20, 0x92, 0x74, 0x75, 0x09, 0x85, + 0xb0, 0x9f, 0x16, 0x34, 0xa1, 0xcc, 0x46, 0x88, 0x42, 0xb9, 0x0d, 0x7e, 0xa8, 0x31, 0x31, 0xbe, + 0xd4, 0x28, 0xa5, 0x40, 0xee, 0x13, 0x75, 0x92, 0x98, 0x97, 0xb3, 0x7c, 0x6e, 0xa3, 0x64, 0x47, + 0xe4, 0xe2, 0x29, 0xe3, 0x3a, 0x8e, 0x6e, 0xf4, 0xca, 0xa0, 0x27, 0x0a, 0xf6, 0xf0, 0x6f, 0x8b, + 0xa6, 0x5b, 0x56, 0x70, 0x6a, 0xa5, 0xa1, 0x96, 0xdf, 0x1a, 0x86, 0x99, 0xf5, 0x81, 0x18, 0x9b, + 0xef, 0x4d, 0xd3, 0x05, 0x59, 0x35, 0x7b, 0x31, 0xf6, 0xf4, 0x6f, 0xef, 0x61, 0x08, 0x28, 0x98, + 0xa2, 0xee, 0x97, 0xa2, 0xdc, 0x07, 0x53, 0x8c, 0xf3, 0x3e, 0x4d, 0x82, 0xd5, 0xd5, 0xf6, 0xdb, + 0x2c, 0xc7, 0x75, 0x9a, 0x04, 0xbf, 0x7a, 0x8f, 0xa5, 0x63, 0xaa, 0xb9, 0xf0, 0x47, 0x07, 0x09, + 0x85, 0x3b, 0xf9, 0xa0, 0xc3, 0x1e, 0xff, 0x32, 0xd7, 0x3e, 0x8e, 0xb3, 0x87, 0x3a, 0xa8, 0xb4, + 0x45, 0xb0, 0x84, 0xac, 0x96, 0x7b, 0x10, 0xd9, 0xda, 0xee, 0x37, 0x1f, 0x6d, 0x08, 0xf8, 0xd0, + 0x1c, 0xbf, 0x6e, 0xba, 0x82, 0x81, 0xea, 0xb8, 0x97, 0xc1, 0x15, 0x4a, 0xbf, 0x56, 0x08, 0x0b, + 0x0a, 0x02, 0x34, 0x74, 0x9b, 0xc8, 0x55, 0xae, 0x79, 0x33, 0x5e, 0xba, 0x2d, 0xf7, 0xeb, 0x95, + 0x8a, 0xfb, 0x23, 0x63, 0x60, 0xa1, 0x25, 0x11, 0xaa, 0x7f, 0xac, 0x0f, 0xad, 0x3e, 0xf7, 0x9c, + 0x49, 0x8a, 0xdf, 0x1a, 0xce, 0x61, 0x8b, 0x27, 0xe7, 0x2a, 0xba, 0x31, 0x05, 0xc4, 0xa7, 0xe8, + 0x46, 0x59, 0xdf, 0x89, 0x2a, 0x4c, 0x4d, 0xaf, 0x04, 0x1d, 0x66, 0xa0, 0xe1, 0x32, 0xa0, 0x3d, + 0x04, 0xb4, 0xe1, 0x76, 0x9b, 0xc9, 0xb8, 0x6d, 0xd3, 0xbd, 0xab, 0x4b, 0xc0, 0x6e, 0x3e, 0x01, + 0xb6, 0xe1, 0xf8, 0x03, 0xbd, 0xec, 0x64, 0xa2, 0x5d, 0xc1, 0xc5, 0xef, 0xf3, 0x10, 0x58, 0x15, + 0x6d, 0xf6, 0xda, 0x95, 0xc6, 0x6b, 0x26, 0xe5, 0xff, 0x12, 0x80, 0x7f, 0x8f, 0xc3, 0x80, 0x95, + 0xf6, 0xcd, 0x40, 0xdb, 0x56, 0xfb, 0xb6, 0xc5, 0x79, 0xd5, 0xe4, 0xbc, 0x0d, 0x5a, 0x32, 0x3d, + 0x37, 0x00, 0x80, 0x88, 0x0c, 0xa8, 0x23, 0x9b, 0xa0, 0x6f, 0x31, 0x96, 0x06, 0x99, 0x2e, 0x99, + 0xdb, 0x16, 0xd3, 0x95, 0x3e, 0x5c, 0xc6, 0xd3, 0xd5, 0x11, 0x1d, 0x55, 0x4c, 0x47, 0x1d, 0x56, + 0xd5, 0x75, 0xfb, 0xda, 0x96, 0xab, 0x4c, 0xb7, 0x19, 0xac, 0xc3, 0x67, 0xcc, 0xea, 0x4e, 0xdc, + 0x57, 0x97, 0xb3, 0x3b, 0x92, 0x07, 0xc5, 0x2a, 0xd8, 0x8f, 0xad, 0xa1, 0x68, 0xf6, 0x84, 0x44, + 0x52, 0x45, 0x0f, 0x15, 0x85, 0x5f, 0x3c, 0x90, 0xd1, 0xab, 0x80, 0x06, 0xf2, 0x76, 0x36, 0x53, + 0x0b, 0xbe, 0xa9, 0xaf, 0xfd, 0x03, 0x63, 0x41, 0x40, 0x3e, 0xab, 0xa8, 0x42, 0x2a, 0xf6, 0x16, + 0xba, 0xd6, 0xd9, 0x86, 0xd2, 0x18, 0xb2, 0x44, 0x1b, 0xeb, 0x67, 0xe5, 0x6d, 0x29, 0x24, 0x2d, + 0x5b, 0x5e, 0xe8, 0x25, 0x16, 0x09, 0xd6, 0x18, 0xea, 0x76, 0x99, 0xa1, 0xfd, 0xd8, 0x84, 0xa4, + 0x38, 0x24, 0x5c, 0xbe, 0xae, 0x9e, 0x3c, 0x3f, 0x30, 0x34, 0xdb, 0x8d, 0x4f, 0x86, 0xfe, 0x1b, + 0xe5, 0x74, 0xce, 0x3a, 0x6e, 0x0a, 0x27, 0xb7, 0x48, 0x13, 0x7c, 0xa1, 0xd7, 0xfb, 0x9e, 0x02, + 0xd6, 0x22, 0xe7, 0xeb, 0xf7, 0xfb, 0xde, 0x40, 0x05, 0x4b, 0xb1, 0xc9, 0x32, 0xb4, 0x03, 0x4c, + 0xf0, 0x2b, 0x2e, 0xe3, 0x2d, 0x70, 0x17, 0x15, 0xb8, 0x0d, 0x58, 0x16, 0x54, 0x3a, 0xc6, 0xd2, + 0xc6, 0x1a, 0xd8, 0xd7, 0xc4, 0x35, 0xae, 0x81, 0x71, 0x0d, 0xa8, 0x2e, 0x95, 0x93, 0x6e, 0x12, + 0xe1, 0x91, 0x89, 0x42, 0xdd, 0x90, 0x2a, 0x02, 0x64, 0x2a, 0x0b, 0x4e, 0x9e, 0x3b, 0xdf, 0xd4, + 0x7e, 0xc8, 0x92, 0x5d, 0x21, 0xcb, 0xfb, 0x51, 0xc7, 0xac, 0x81, 0x63, 0xe1, 0x82, 0xe3, 0xcd, + 0xc0, 0xde, 0xf7, 0x0b, 0x88, 0x7d, 0x52, 0x6f, 0x26, 0xd3, 0x68, 0x0b, 0xd8, 0x62, 0xe9, 0x4e, + 0xc3, 0x0a, 0x8b, 0xf2, 0xb2, 0xe2, 0x72, 0x07, 0x9f, 0xef, 0x0b, 0x63, 0xea, 0x2e, 0x3b, 0x85, + 0x0e, 0x94, 0xa5, 0x3b, 0x9b, 0xb9, 0xef, 0x68, 0xe3, 0xae, 0x0c, 0xdc, 0x1d, 0xf3, 0x96, 0xa5, + 0x07, 0x76, 0xf4, 0x82, 0x03, 0x1e, 0xe6, 0xdb, 0xcf, 0x1f, 0xd4, 0x95, 0xa8, 0xda, 0xb1, 0x4c, + 0xf8, 0x9c, 0x2a, 0x07, 0xb5, 0x6a, 0x07, 0x59, 0x5c, 0x89, 0xa9, 0x43, 0x3d, 0x3b, 0xe6, 0x25, + 0x4b, 0x47, 0x76, 0x9f, 0x23, 0xee, 0xf3, 0x61, 0x2f, 0x82, 0x0f, 0xfc, 0x6a, 0x22, 0x9c, 0x33, + 0xd5, 0x03, 0x3e, 0xd2, 0xc7, 0x66, 0x3b, 0x72, 0xe3, 0x29, 0x21, 0x57, 0x62, 0x4e, 0x72, 0xa1, + 0x1d, 0x9d, 0x03, 0x6c, 0xd7, 0x80, 0x87, 0x01, 0x3c, 0x45, 0x5a, 0x53, 0x92, 0xc0, 0x14, 0x15, + 0x2a, 0xbb, 0x41, 0x58, 0xfc, 0x6b, 0x20, 0x74, 0x22, 0x1b, 0x16, 0x26, 0x81, 0x05, 0xa7, 0x94, + 0x0f, 0xdf, 0x09, 0xe7, 0x26, 0x68, 0xe3, 0x6a, 0x56, 0xdf, 0xf3, 0xf4, 0x2e, 0x66, 0xe2, 0xe2, + 0x49, 0xb2, 0xc4, 0x5d, 0xf0, 0xe0, 0x70, 0x48, 0xbb, 0xe2, 0x48, 0xae, 0x5b, 0x45, 0xaa, 0xf1, + 0xb8, 0x19, 0xd6, 0x6f, 0x73, 0xd2, 0x06, 0x20, 0x8d, 0xc3, 0xcd, 0xad, 0xe3, 0x46, 0xf4, 0x25, + 0xd4, 0x81, 0x7c, 0xd6, 0xee, 0x5a, 0x5b, 0xf9, 0xb5, 0xda, 0x78, 0xf4, 0x02, 0x22, 0x4c, 0xf0, + 0x1a, 0x2b, 0x60, 0x31, 0x9d, 0x1a, 0x75, 0x8a, 0x67, 0x6e, 0xde, 0xec, 0x75, 0xde, 0xd9, 0x19, + 0xac, 0x59, 0x94, 0x7c, 0xee, 0x76, 0x9e, 0xc5, 0xcf, 0x3a, 0x0f, 0x82, 0xa5, 0x5c, 0x82, 0xbe, + 0x93, 0xc1, 0x59, 0x08, 0x00, 0xdd, 0x7d, 0x67, 0xac, 0x64, 0x98, 0xce, 0x0e, 0xb1, 0xa8, 0xec, + 0xf8, 0xdc, 0xde, 0xc9, 0x7b, 0x7c, 0xaa, 0x37, 0x31, 0x4d, 0x6d, 0x5a, 0x97, 0x20, 0x06, 0x02, + 0x34, 0x8c, 0x65, 0xca, 0xfe, 0xaf, 0x22, 0xb4, 0x48, 0x01, 0x4b, 0xd0, 0xd4, 0x58, 0x4d, 0xa8, + 0x0a, 0xa2, 0xdb, 0xa9, 0x31, 0x5a, 0xa0, 0xad, 0x8e, 0x80, 0xd1, 0x03, 0xd0, 0x54, 0xb8, 0x43, + 0xfb, 0xc8, 0x85, 0x7b, 0x8b, 0xb3, 0xb6, 0x6b, 0x47, 0x14, 0x10, 0xc7, 0x5e, 0xe9, 0x8e, 0xba, + 0xc2, 0x74, 0xf3, 0x90, 0x78, 0x8e, 0xd2, 0xb9, 0x42, 0xb1, 0x16, 0x3d, 0x1e, 0x90, 0xbe, 0x1f, + 0xdf, 0xf3, 0x56, 0x3c, 0xf4, 0x37, 0xd2, 0x0b, 0xc8, 0xc8, 0x2a, 0xdb, 0x4d, 0xf8, 0xb2, 0x61, + 0xd6, 0x71, 0x3c, 0x26, 0x63, 0x4f, 0xd3, 0x1f, 0x11, 0x53, 0xf4, 0x4c, 0xef, 0x26, 0xa8, 0xbc, + 0xa7, 0x57, 0x05, 0xea, 0x14, 0xb6, 0x45, 0x54, 0xc9, 0x76, 0x13, 0x54, 0x78, 0x7b, 0x8a, 0x7d, + 0x63, 0xab, 0x5c, 0xb4, 0xc7, 0xc7, 0xa4, 0xcd, 0xed, 0x42, 0xdf, 0x0c, 0x39, 0x3b, 0xbe, 0x90, + 0x5b, 0x81, 0xc3, 0x81, 0x07, 0xda, 0xd6, 0xea, 0x01, 0x0c, 0xbd, 0xda, 0xfe, 0xe0, 0x93, 0x6c, + 0xe4, 0xc0, 0xd1, 0xc8, 0x5e, 0x5b, 0x2b, 0xb5, 0xc0, 0xbf, 0xca, 0xcd, 0xdc, 0x0e, 0x3c, 0xa0, + 0x34, 0x2d, 0x48, 0x52, 0xe3, 0x33, 0xbe, 0x03, 0xc7, 0xc7, 0x9d, 0xe4, 0xc3, 0x4e, 0x13, 0xe3, + 0xf1, 0xc4, 0x26, 0xf6, 0xd3, 0xdf, 0xf0, 0x0e, 0x86, 0xe3, 0x07, 0x61, 0xad, 0xc4, 0x1b, 0xa3, + 0x19, 0x41, 0xe1, 0xbf, 0x41, 0x4d, 0xa4, 0x7c, 0xcd, 0x4e, 0xeb, 0x72, 0x1e, 0x54, 0xba, 0x48, + 0xef, 0xfb, 0x42, 0x23, 0x9b, 0x1f, 0x4b, 0x6c, 0xb7, 0x97, 0x8f, 0x6a, 0xc8, 0x6e, 0x8c, 0x41, + 0xdd, 0xf9, 0x17, 0x3d, 0xc1, 0xe0, 0x61, 0x93, 0x4e, 0xfd, 0x9a, 0x15, 0x0c, 0xbb, 0x0e, 0x54, + 0x59, 0x03, 0xea, 0x7f, 0xdf, 0x7f, 0x82, 0x74, 0x5b, 0x58, 0xf5, 0x78, 0xc2, 0xdd, 0xc3, 0xca, + 0x9a, 0x29, 0x64, 0x1d, 0xa9, 0x6b, 0xab, 0xcd, 0xc3, 0x28, 0xa0, 0x47, 0x6f, 0xc7, 0xdc, 0x06, + 0x7d, 0xa7, 0x19, 0x7d, 0xa6, 0x99, 0x51, 0xa2, 0x6d, 0xf7, 0x6d, 0xf8, 0xff, 0xc0, 0x2b, 0x42, + 0x91, 0x1d, 0xf7, 0x0e, 0xff, 0x56, 0x52, 0xb9, 0x59, 0xf8, 0x77, 0x67, 0xb2, 0x9b, 0xd9, 0x64, + 0xd7, 0x74, 0xc3, 0xab, 0xe9, 0x36, 0x3d, 0x0c, 0x6e, 0xb9, 0x8a, 0x38, 0xea, 0x27, 0x05, 0xb9, + 0x5c, 0xae, 0x93, 0x32, 0x06, 0x19, 0xdd, 0xf8, 0x25, 0x42, 0x8e, 0x8a, 0xb7, 0xba, 0x8a, 0xd4, + 0xb3, 0x17, 0xe6, 0x72, 0x91, 0xe2, 0xf0, 0x28, 0xbb, 0xfc, 0xe2, 0xdc, 0x76, 0x34, 0x54, 0x5d, + 0xef, 0xef, 0xef, 0x30, 0x99, 0x34, 0x79, 0xc3, 0x6f, 0x26, 0x67, 0xf4, 0x94, 0x35, 0xe4, 0x8c, + 0x5e, 0xb2, 0x5b, 0xd6, 0x18, 0x64, 0x7f, 0xc3, 0x1a, 0x43, 0xb7, 0x5c, 0xb4, 0xc0, 0xbb, 0xfe, + 0x66, 0xa0, 0x7e, 0x88, 0x2d, 0x98, 0x96, 0xf1, 0x36, 0x90, 0x96, 0xf1, 0x37, 0x40, 0xb4, 0x8c, + 0xe1, 0xc7, 0x32, 0xfe, 0x3d, 0x6b, 0x1e, 0xbd, 0xcf, 0x0d, 0x4c, 0xad, 0x3d, 0x90, 0xda, 0x7e, + 0x4f, 0x79, 0xb8, 0x17, 0xe7, 0x3b, 0xaa, 0xef, 0x8d, 0x97, 0xf9, 0x0e, 0x7d, 0xa0, 0xd7, 0xfa, + 0x78, 0x87, 0xb5, 0x42, 0xee, 0xa4, 0x72, 0xad, 0xec, 0x0e, 0xc7, 0x7f, 0x77, 0xe3, 0xd5, 0xcc, + 0x6c, 0xd6, 0x75, 0x28, 0xe6, 0xb7, 0x15, 0xab, 0x29, 0x28, 0xba, 0x7b, 0xd3, 0xd2, 0x84, 0xb6, + 0xdb, 0xb6, 0xc9, 0xc0, 0xdf, 0x2c, 0x48, 0xb6, 0x8e, 0xad, 0x6e, 0x8c, 0xfb, 0xcd, 0xc3, 0x43, + 0x1c, 0x37, 0x47, 0xf7, 0x10, 0x4a, 0x9b, 0x06, 0x2a, 0xfe, 0xff, 0xd2, 0xa5, 0x17, 0x52, 0x06, + 0x5e, 0x91, 0x77, 0xdb, 0xa7, 0xa4, 0xb8, 0xdd, 0x05, 0xf6, 0xca, 0x45, 0xbb, 0xff, 0xcd, 0x4b, + 0x40, 0x5f, 0xbb, 0x6f, 0x01, 0x24, 0xde, 0x09, 0x90, 0xc6, 0x05, 0xfe, 0xb7, 0x03, 0xf3, 0x11, + 0xc5, 0x90, 0x26, 0x1c, 0x09, 0xbe, 0xce, 0x20, 0xe2, 0x6f, 0xb9, 0x31, 0x7b, 0xff, 0x4f, 0xc7, + 0x78, 0xb2, 0x04, 0x65, 0xa5, 0xfd, 0x51, 0xfb, 0x2e, 0xe8, 0xb0, 0xfc, 0xd1, 0x7b, 0xa1, 0xd5, + 0xca, 0x18, 0xe3, 0x34, 0x79, 0x68, 0x6f, 0x43, 0xf8, 0xc1, 0x90, 0xf7, 0xe3, 0x07, 0x48, 0x44, + 0x9b, 0x02, 0xf9, 0xc8, 0xaf, 0x82, 0xdb, 0x07, 0x2b, 0x44, 0x76, 0x05, 0x8a, 0xe2, 0xf5, 0x50, + 0x8d, 0x0a, 0x11, 0x32, 0xee, 0xff, 0x38, 0x21, 0x6f, 0xd4, 0xbb, 0x49, 0x3b, 0xb0, 0x01, 0x0e, + 0xfe, 0xe8, 0x98, 0xc0, 0xac, 0xa0, 0xf9, 0x63, 0x1f, 0x1e, 0xb3, 0xc9, 0x7e, 0x94, 0xa1, 0x9f, + 0x33, 0x13, 0x85, 0x5d, 0x87, 0x69, 0x7f, 0xa6, 0xe2, 0x72, 0xc9, 0x90, 0x5c, 0x6c, 0xf3, 0xf0, + 0x30, 0x18, 0x74, 0x9a, 0x96, 0x20, 0xd0, 0xdb, 0xd2, 0x5b, 0xf8, 0x69, 0x2d, 0xdc, 0xbd, 0x71, + 0x52, 0x80, 0x8a, 0x68, 0xa4, 0xfc, 0x01, 0x64, 0x83, 0x91, 0xcf, 0xcd, 0xd0, 0x41, 0x11, 0x3d, + 0x66, 0x80, 0x82, 0x9a, 0xba, 0x00, 0xf2, 0x47, 0xff, 0xd4, 0x7e, 0x66, 0x28, 0x6f, 0xcb, 0x46, + 0x50, 0xfd, 0x4f, 0xf4, 0xac, 0x90, 0xe7, 0xcb, 0xb7, 0xb0, 0xad, 0x50, 0xf4, 0xd9, 0x87, 0xda, + 0x8e, 0xb7, 0x39, 0x6a, 0xf7, 0x01, 0x76, 0x9d, 0x49, 0xac, 0x0b, 0xa7, 0x3c, 0xb8, 0x69, 0x07, + 0x2b, 0xc8, 0xe2, 0xca, 0x0d, 0x93, 0x8e, 0x40, 0x2e, 0x3b, 0xb6, 0x62, 0xb3, 0x42, 0x3b, 0xca, + 0x60, 0xa8, 0x16, 0x45, 0x1c, 0xcb, 0x9e, 0x79, 0x37, 0xb0, 0x06, 0x50, 0xc8, 0x81, 0x72, 0xc6, + 0x40, 0x09, 0x3e, 0x94, 0x3f, 0x91, 0x91, 0xb2, 0xbe, 0x29, 0x98, 0xbf, 0x7a, 0x28, 0xa0, 0xf2, + 0xd4, 0x18, 0x85, 0x0a, 0xb7, 0x74, 0x7a, 0xd2, 0x9a, 0x59, 0x5a, 0x59, 0x58, 0xf6, 0x5d, 0xb6, + 0xe7, 0x30, 0xc2, 0x12, 0xa3, 0xa3, 0xd7, 0x8f, 0xf3, 0x6e, 0xe7, 0xbe, 0xe3, 0x8b, 0x13, 0xe0, + 0x04, 0x7f, 0x04, 0xa4, 0xd3, 0xbb, 0x55, 0x19, 0xdc, 0x4a, 0xd3, 0x11, 0x38, 0x72, 0x87, 0x6b, + 0x10, 0xd6, 0x96, 0x84, 0x33, 0x1b, 0xb8, 0x6f, 0x00, 0xcb, 0xe3, 0x51, 0x7a, 0x7e, 0xdd, 0x36, + 0xfe, 0x8f, 0xa0, 0x2c, 0x8f, 0xe6, 0x40, 0x59, 0x0b, 0xba, 0x8e, 0xcf, 0xf0, 0x29, 0xba, 0x69, + 0x34, 0xc7, 0xc8, 0x77, 0xcb, 0x74, 0x16, 0xcf, 0xef, 0x70, 0xf9, 0xd1, 0x6d, 0xbf, 0x54, 0x1b, + 0x39, 0x80, 0xad, 0x44, 0x19, 0xa6, 0xb9, 0x4e, 0x69, 0xa6, 0x6b, 0x61, 0x37, 0xee, 0x75, 0x76, + 0x3c, 0xa5, 0xfc, 0xb6, 0xf5, 0x36, 0x6d, 0x1c, 0x9f, 0xb9, 0x5a, 0xb1, 0xb5, 0x5a, 0xd1, 0xac, + 0xb6, 0xe1, 0x8d, 0xfa, 0x0c, 0xd8, 0x0b, 0xac, 0x7a, 0xaa, 0x8c, 0x2b, 0x87, 0x92, 0x98, 0x18, + 0xb3, 0x4f, 0x3a, 0x9c, 0xc4, 0x4f, 0x5b, 0x56, 0xe7, 0xd7, 0xa4, 0xb1, 0x38, 0x7f, 0xfa, 0x54, + 0x89, 0x44, 0x4d, 0x6d, 0x62, 0xc4, 0x5d, 0x6c, 0xf4, 0xa7, 0x4f, 0xd2, 0x00, 0xcb, 0x62, 0x65, + 0x32, 0x2c, 0x3c, 0xb3, 0x30, 0xcd, 0xbc, 0x80, 0x73, 0x18, 0xee, 0xe5, 0xe0, 0x5d, 0xfc, 0xc6, + 0x83, 0x44, 0xa9, 0x6f, 0x05, 0xf7, 0x3e, 0xcb, 0x3e, 0x60, 0x57, 0x90, 0x25, 0xe7, 0xa0, 0x12, + 0xf8, 0x18, 0x32, 0xf5, 0xa0, 0x5b, 0xf3, 0xd3, 0x2d, 0x79, 0xd7, 0x5b, 0xf2, 0x68, 0xab, 0x39, + 0xaf, 0x4f, 0xac, 0x0d, 0xd5, 0x3d, 0x60, 0x77, 0x9c, 0x7d, 0x82, 0x6d, 0x09, 0x17, 0xfd, 0xd8, + 0x6b, 0x23, 0x34, 0x34, 0xf0, 0x8a, 0x64, 0x5c, 0xfc, 0x55, 0x74, 0x93, 0xdc, 0x11, 0x77, 0x9e, + 0x69, 0xe7, 0x24, 0x6f, 0xa3, 0xaf, 0xb5, 0x0d, 0x0b, 0xf1, 0x6d, 0x58, 0x14, 0x53, 0x31, 0xd9, + 0xd5, 0x1a, 0x38, 0x23, 0xbe, 0xb0, 0x6b, 0xc8, 0x39, 0xd2, 0xb9, 0xda, 0xfd, 0xdb, 0x15, 0x21, + 0xbd, 0xf6, 0x18, 0x60, 0xe3, 0xc0, 0xf8, 0xd9, 0xb9, 0x97, 0xcd, 0x48, 0xc5, 0xd0, 0x2a, 0x8d, + 0x54, 0x51, 0x1a, 0x9f, 0x1f, 0xb5, 0xf4, 0xde, 0xd0, 0x8a, 0x28, 0xdb, 0x4c, 0xe9, 0x53, 0x18, + 0xb2, 0x5e, 0x64, 0x7a, 0xf4, 0xef, 0x7f, 0x75, 0x30, 0xcd, 0xe9, 0x5a, 0x0c, 0x5f, 0xc8, 0x66, + 0xbf, 0x16, 0xb2, 0xf3, 0x64, 0x5e, 0x60, 0x17, 0x5c, 0x06, 0xf9, 0x25, 0x5e, 0x19, 0xe3, 0x53, + 0xd6, 0x8d, 0xcc, 0x9b, 0x78, 0x56, 0x2e, 0x26, 0xde, 0x8b, 0x03, 0x99, 0x49, 0xcf, 0x05, 0xcc, + 0xd8, 0x56, 0xb4, 0xd6, 0xd1, 0xa1, 0xa3, 0xa3, 0x5a, 0x51, 0xd5, 0x95, 0x6a, 0xad, 0x96, 0x2d, + 0x3b, 0x3b, 0x1c, 0xaa, 0x6c, 0x7a, 0xdb, 0x90, 0xdf, 0x94, 0x47, 0x19, 0xa4, 0xde, 0x71, 0xd5, + 0x22, 0xb4, 0xc5, 0xe2, 0x44, 0xbb, 0x2b, 0xb7, 0xda, 0xbb, 0x7e, 0x8b, 0xbb, 0xf3, 0xc3, 0xce, + 0xc1, 0x14, 0x30, 0x03, 0xb8, 0xc7, 0xa2, 0xee, 0xb8, 0x99, 0xbd, 0xef, 0x56, 0x03, 0xed, 0xa8, + 0x17, 0x3e, 0x73, 0xd8, 0x4e, 0x94, 0x3c, 0xca, 0x01, 0x65, 0xee, 0x17, 0x24, 0x8b, 0x16, 0xf4, + 0xef, 0xf5, 0x18, 0x3d, 0xfa, 0x88, 0x30, 0x21, 0xb7, 0x5f, 0x7f, 0x98, 0x8a, 0x43, 0xa8, 0xc2, + 0xca, 0x4b, 0x97, 0x20, 0x1c, 0x3f, 0x15, 0x87, 0xf4, 0xb6, 0xd2, 0x21, 0xcb, 0x79, 0xb3, 0x54, + 0x12, 0x06, 0x54, 0x5c, 0x54, 0x2b, 0xd6, 0xeb, 0x3d, 0x7f, 0xa9, 0x44, 0x43, 0xc0, 0x4f, 0x12, + 0x09, 0x2e, 0x10, 0x4c, 0x8b, 0x2e, 0x57, 0xde, 0xe7, 0x51, 0xf9, 0x40, 0x7b, 0xb2, 0x71, 0x35, + 0x4a, 0xca, 0xd7, 0xc4, 0x51, 0x9f, 0xb3, 0x34, 0x51, 0x2f, 0x48, 0xf2, 0x0b, 0x94, 0xc3, 0xb6, + 0xc8, 0x28, 0x84, 0x45, 0x2b, 0x92, 0x2a, 0x61, 0xc2, 0x6e, 0x2e, 0xbf, 0xd4, 0xcb, 0xa6, 0x70, + 0xbb, 0x7e, 0xd2, 0x54, 0xfd, 0x2c, 0x9f, 0xac, 0xd4, 0xf3, 0x8d, 0xf0, 0xe5, 0x47, 0x95, 0x69, + 0x2e, 0x7a, 0x1c, 0xe4, 0x79, 0x5b, 0x3b, 0x7f, 0x73, 0xb5, 0x73, 0x59, 0x6f, 0xe7, 0xe0, 0xc1, + 0x76, 0xde, 0xb9, 0xda, 0x99, 0xd6, 0xdb, 0x79, 0xde, 0x86, 0x16, 0xeb, 0x79, 0x77, 0xf3, 0xc2, + 0x98, 0x8d, 0x96, 0x45, 0x74, 0x7b, 0x4a, 0xce, 0x9d, 0xea, 0xe1, 0x30, 0x54, 0x34, 0x02, 0xf2, + 0xd7, 0x53, 0xf6, 0xf9, 0xb4, 0xe2, 0x59, 0xdf, 0x38, 0xa8, 0x9f, 0x1e, 0xa0, 0xe5, 0xfd, 0x50, + 0xbe, 0xd3, 0x75, 0xd3, 0x2f, 0xd3, 0x53, 0x59, 0xf5, 0x65, 0xcb, 0xaa, 0x82, 0x4e, 0x43, 0xdb, + 0xe1, 0xa0, 0xcc, 0xdb, 0xcb, 0xad, 0xe6, 0x9d, 0x9d, 0x8d, 0xb8, 0xab, 0x18, 0x80, 0xda, 0x74, + 0xab, 0xdf, 0x7a, 0x0d, 0xb3, 0x7b, 0xf3, 0x32, 0xd8, 0x42, 0x3c, 0xe7, 0xc7, 0x87, 0xfb, 0x57, + 0xd1, 0xdd, 0x7b, 0x7c, 0xaa, 0x11, 0xc3, 0xce, 0x3c, 0xf7, 0xc9, 0x15, 0x5e, 0xad, 0xea, 0x2a, + 0x0c, 0x3a, 0xa7, 0x3e, 0x07, 0xdb, 0x91, 0x82, 0x9d, 0xd9, 0xa8, 0xb6, 0xcf, 0x2c, 0xd5, 0xe9, + 0x79, 0x09, 0x47, 0x41, 0x89, 0x67, 0x2d, 0xa9, 0xd7, 0x57, 0x91, 0xf7, 0x27, 0x72, 0xd3, 0xaf, + 0xd4, 0x1b, 0xf6, 0x5e, 0xfa, 0xbe, 0xf3, 0x05, 0xa0, 0x66, 0xed, 0xf9, 0x3c, 0x08, 0x86, 0xc3, + 0xea, 0xc3, 0x98, 0x1c, 0x58, 0xc6, 0x86, 0xd1, 0xf7, 0xeb, 0x20, 0x0f, 0x2b, 0x4b, 0xf7, 0xc0, + 0x8d, 0x9d, 0xda, 0xc2, 0xcd, 0xb7, 0xaf, 0x4d, 0x83, 0x1e, 0x52, 0x43, 0x6f, 0x5f, 0x80, 0xd5, + 0xc2, 0xd3, 0xed, 0xab, 0xcc, 0x14, 0xae, 0x23, 0xe0, 0x02, 0xdd, 0x33, 0x1e, 0xdf, 0xe7, 0x9b, + 0xde, 0xe3, 0xfb, 0x4b, 0xfc, 0x67, 0xba, 0xf1, 0x2f, 0x1e, 0x64, 0x4b, 0x3a, 0xaf, 0xc8, 0xad, + 0xeb, 0xb0, 0x5d, 0x37, 0x6c, 0xd2, 0x46, 0xe7, 0xfc, 0x40, 0xdf, 0x93, 0x27, 0x62, 0xfb, 0xde, + 0x85, 0xc5, 0x3a, 0xf6, 0xa3, 0xc0, 0x70, 0x92, 0xa9, 0x0d, 0x02, 0xdf, 0xc4, 0x5d, 0x45, 0x09, + 0x50, 0x59, 0x71, 0xdd, 0xe9, 0x89, 0x0e, 0xfe, 0x33, 0x92, 0x8e, 0xde, 0x0f, 0x35, 0x5e, 0x67, + 0xa3, 0x86, 0x5f, 0x48, 0x28, 0xf7, 0x26, 0x78, 0x90, 0xab, 0x4d, 0xfe, 0x83, 0x7b, 0xe9, 0xd1, + 0x2e, 0xac, 0xba, 0xae, 0x76, 0x82, 0x02, 0xf0, 0xf7, 0xec, 0x8c, 0xb8, 0x72, 0x8f, 0x99, 0x2a, + 0xff, 0x99, 0xf6, 0x2a, 0x10, 0x9c, 0xf7, 0xce, 0xf0, 0xff, 0xcf, 0xcd, 0xf5, 0x06, 0x0b, 0x4f, + 0x56, 0x9c, 0xa8, 0x96, 0xa6, 0xa1, 0xda, 0x4e, 0xad, 0xcb, 0xa6, 0xad, 0x73, 0x9b, 0xea, 0xe1, + 0xe0, 0xe1, 0x1e, 0x76, 0xea, 0x44, 0xf7, 0xf0, 0x80, 0xe4, 0xf0, 0xef, 0x53, 0x4d, 0xd2, 0xf3, + 0x07, 0xa1, 0x5c, 0xca, 0x52, 0x33, 0x98, 0x43, 0x4d, 0xfb, 0x49, 0x52, 0x19, 0x67, 0x8a, 0x8d, + 0x64, 0xd5, 0x21, 0x71, 0x11, 0x3e, 0x9b, 0x8c, 0x5e, 0x71, 0x08, 0x91, 0x45, 0x78, 0xf2, 0x1c, + 0x1f, 0x33, 0x58, 0x90, 0xe3, 0x98, 0x4c, 0x39, 0x80, 0x14, 0x48, 0x78, 0x3e, 0x7c, 0xa9, 0x92, + 0x26, 0x93, 0xd1, 0x8b, 0x17, 0x3e, 0xd5, 0x7c, 0x6e, 0x27, 0x0e, 0x5f, 0xf9, 0xba, 0xb9, 0x47, + 0x2e, 0xb6, 0x89, 0xef, 0x18, 0x2b, 0x1e, 0x1e, 0x4a, 0x92, 0xbd, 0x58, 0x14, 0xf8, 0xb2, 0xfa, + 0x22, 0xdc, 0x10, 0x9d, 0xff, 0xb9, 0x07, 0x62, 0xc7, 0x9f, 0xfd, 0x0b, 0xf8, 0x7a, 0x2d, 0x87, + 0x5c, 0x7d, 0x9b, 0xf7, 0x6f, 0x7f, 0x57, 0x4c, 0x48, 0x3e, 0xa7, 0x8e, 0x89, 0x5d, 0x0f, 0xed, + 0xb1, 0x8b, 0xf1, 0x60, 0x70, 0x19, 0x97, 0x8b, 0xf5, 0x14, 0x5a, 0x5f, 0x0e, 0xde, 0xc6, 0x79, + 0x98, 0xa6, 0xe9, 0x55, 0x1c, 0x0d, 0x30, 0x98, 0xc9, 0xe0, 0x26, 0xbe, 0x8a, 0xbd, 0x0a, 0xc2, + 0x60, 0x4f, 0xc9, 0xad, 0xab, 0x1d, 0x13, 0x20, 0x64, 0x35, 0xff, 0x99, 0xb4, 0x61, 0x76, 0x00, + 0x37, 0x2c, 0x5c, 0xb9, 0x5a, 0x9b, 0x96, 0xce, 0xc5, 0x43, 0xa7, 0x04, 0x0a, 0xe3, 0x88, 0xc0, + 0x4f, 0xcb, 0xda, 0x78, 0x55, 0x94, 0x42, 0xca, 0xaa, 0x1c, 0xfd, 0xdf, 0xa7, 0xab, 0x79, 0x9c, + 0x2f, 0xc5, 0xcf, 0xd1, 0x34, 0x4d, 0xf9, 0x30, 0x2f, 0x01, 0xe4, 0xc3, 0x7a, 0xf5, 0x76, 0xaa, + 0xfe, 0x98, 0xfc, 0x02, 0x4e, 0x70, 0xd8, 0xca, 0x40, 0xab, 0x02, 0x2a, 0xc3, 0x3c, 0x75, 0x8d, + 0x33, 0xc7, 0x20, 0x9a, 0x36, 0x4f, 0x6f, 0x1b, 0x52, 0xa1, 0xc7, 0xa3, 0x51, 0x71, 0xaa, 0x70, + 0xf1, 0x3b, 0x46, 0x68, 0xb4, 0x15, 0x0a, 0x34, 0xd7, 0x08, 0xeb, 0x60, 0x3b, 0x7b, 0x9a, 0xcf, + 0x9d, 0x3d, 0xd1, 0xf4, 0xe9, 0xdb, 0x3e, 0xcf, 0xc9, 0xa4, 0xce, 0xee, 0xd5, 0x6d, 0xeb, 0xb0, + 0x27, 0xaf, 0xea, 0x94, 0xbd, 0x6a, 0x8f, 0xaf, 0xa2, 0x29, 0x76, 0x8b, 0x7d, 0xc7, 0x3e, 0xda, + 0xe5, 0x8e, 0x9d, 0x5a, 0x1a, 0x7e, 0xc3, 0xa5, 0xba, 0x7a, 0x45, 0xa5, 0x17, 0xd8, 0xf4, 0x16, + 0xf8, 0xc2, 0x0e, 0xdb, 0x3e, 0xb1, 0x02, 0x85, 0xf1, 0xb9, 0xd4, 0x69, 0xdb, 0x89, 0x76, 0x2f, + 0x0e, 0xcf, 0x06, 0xab, 0xaa, 0xdb, 0xc1, 0xc1, 0xd9, 0x58, 0x64, 0xb7, 0x56, 0xb1, 0xe2, 0xaf, + 0xb7, 0x57, 0xf3, 0x0c, 0x1f, 0xab, 0x04, 0xfe, 0x54, 0x92, 0x08, 0xbf, 0x96, 0x82, 0x3c, 0x77, + 0xa0, 0xde, 0x6c, 0xd3, 0xa6, 0xf5, 0xe8, 0xb6, 0xb7, 0x3f, 0x1a, 0xb6, 0xb8, 0xbe, 0xa2, 0xaa, + 0x27, 0xc3, 0xe8, 0x69, 0xae, 0x20, 0x65, 0x36, 0x34, 0xa4, 0xfa, 0xc5, 0x7d, 0xae, 0xe2, 0x30, + 0xec, 0xbf, 0xb1, 0xa3, 0xba, 0x8d, 0x1b, 0x91, 0xd3, 0xdc, 0xd7, 0x09, 0x1a, 0x9d, 0x16, 0x69, + 0xb1, 0xd2, 0x57, 0xeb, 0xf6, 0x76, 0xab, 0x24, 0x6d, 0x69, 0x33, 0xe3, 0xf9, 0x4d, 0x43, 0x0e, + 0x32, 0x7e, 0xc7, 0x81, 0x9f, 0x1e, 0xb5, 0x72, 0x5b, 0x86, 0x6f, 0x29, 0x7c, 0x65, 0xbd, 0x8a, + 0x33, 0x3a, 0x26, 0xb4, 0x6a, 0x23, 0x5b, 0x9a, 0xac, 0xa9, 0x9e, 0x2d, 0xc5, 0x20, 0xfd, 0x8f, + 0x4d, 0x6b, 0xb2, 0xca, 0x73, 0x2d, 0xb5, 0xc3, 0x0b, 0x6c, 0x26, 0xe1, 0xba, 0xa0, 0xf7, 0xc7, + 0xf3, 0xa2, 0xf5, 0x29, 0x69, 0x7d, 0x53, 0xe7, 0xf9, 0xfd, 0x69, 0xb2, 0xce, 0xbb, 0xee, 0xf3, + 0x86, 0x67, 0xdd, 0x8a, 0xed, 0x54, 0x52, 0x5f, 0x5b, 0xd9, 0xa5, 0x09, 0xc2, 0xc1, 0x00, 0x4b, + 0xa0, 0x5a, 0xef, 0x97, 0x0f, 0xe2, 0x11, 0x9a, 0x25, 0x95, 0xe2, 0xd7, 0xf7, 0xf6, 0x2b, 0xa5, + 0xb5, 0x58, 0x9f, 0x7d, 0x0c, 0x9c, 0x1c, 0xc4, 0x2b, 0x0c, 0xe0, 0xd5, 0x13, 0xa8, 0x70, 0x7c, + 0x41, 0xbb, 0x4f, 0x02, 0x8c, 0x44, 0x3f, 0xda, 0x0e, 0x42, 0xdb, 0xed, 0x50, 0x46, 0x87, 0x81, + 0x83, 0x3b, 0xf9, 0x8c, 0x9e, 0xaa, 0x97, 0x3f, 0x24, 0x06, 0x89, 0x5f, 0x81, 0x80, 0x70, 0x54, + 0x43, 0x14, 0x06, 0xe5, 0x21, 0xd1, 0x5d, 0x1a, 0x53, 0x03, 0x1f, 0x23, 0xe3, 0xbf, 0xd9, 0x97, + 0x74, 0x0d, 0xf8, 0x2f, 0x28, 0x2c, 0x6a, 0x35, 0x09, 0xdd, 0x8b, 0xc7, 0x22, 0x12, 0xf5, 0x37, + 0x14, 0xc3, 0xab, 0x6e, 0xe3, 0x35, 0xfa, 0x7a, 0x10, 0xd1, 0xc4, 0x8e, 0x8c, 0xaa, 0xe3, 0x97, + 0x6a, 0x2f, 0x17, 0x35, 0xdc, 0xa2, 0xdb, 0x91, 0x96, 0x97, 0x20, 0x8b, 0xc2, 0xe2, 0xb1, 0x33, + 0xe2, 0x3c, 0xfd, 0xf5, 0xd7, 0x9b, 0x45, 0x14, 0x25, 0xbf, 0xfe, 0x5a, 0x04, 0xd0, 0x38, 0x6d, + 0x35, 0x2d, 0xe5, 0x78, 0x42, 0x7e, 0xfd, 0x95, 0xe8, 0x73, 0x6b, 0x99, 0x4e, 0x25, 0xe0, 0x29, + 0xe1, 0x53, 0x61, 0x47, 0x7a, 0xcb, 0xfe, 0x37, 0xc9, 0xec, 0x1a, 0xbb, 0xed, 0x91, 0x1f, 0xcb, + 0x60, 0x1a, 0x72, 0x30, 0x22, 0xcf, 0x3f, 0xe3, 0x59, 0x3a, 0x37, 0xae, 0xbc, 0xac, 0xe9, 0xfd, + 0xf5, 0xbd, 0x23, 0x7c, 0x6b, 0xb1, 0x84, 0x3d, 0x76, 0x01, 0xb2, 0xf5, 0x5e, 0x57, 0x4f, 0x1c, + 0xf9, 0x66, 0x36, 0xdc, 0x2f, 0x31, 0x9e, 0x89, 0xc1, 0x76, 0x77, 0x4f, 0x16, 0x47, 0x3e, 0xe3, + 0xc4, 0xfb, 0xec, 0xd6, 0x31, 0x1e, 0xb1, 0x0f, 0xe3, 0xec, 0x09, 0xad, 0xd4, 0xa1, 0x37, 0x83, + 0x67, 0xb7, 0x40, 0x68, 0xb4, 0xd4, 0x70, 0xe7, 0x7e, 0xd6, 0x2d, 0x9e, 0xce, 0x6e, 0x07, 0x37, + 0xbe, 0x7e, 0x33, 0xea, 0xc0, 0xd7, 0xbe, 0xc2, 0xdd, 0xae, 0x24, 0xc1, 0x13, 0x7e, 0xbc, 0xb9, + 0xe0, 0x50, 0x06, 0xf4, 0xa2, 0x33, 0x67, 0x1c, 0x03, 0xc9, 0xee, 0xcb, 0x78, 0xa1, 0x7c, 0xcc, + 0xe7, 0x35, 0x0c, 0x45, 0xe6, 0xf0, 0xdd, 0x1f, 0x1d, 0x98, 0x84, 0xdf, 0x8b, 0x4f, 0xe4, 0x25, + 0x72, 0x56, 0x24, 0x0f, 0x04, 0xdc, 0x32, 0x43, 0xa6, 0x1b, 0x44, 0x10, 0xc5, 0xf2, 0xf2, 0xae, + 0xdb, 0xd9, 0xdf, 0x8f, 0x01, 0xb3, 0x12, 0xb0, 0xfd, 0x89, 0x0a, 0x3b, 0x81, 0xa3, 0x1c, 0x01, + 0x90, 0xf3, 0x23, 0xe3, 0x4a, 0xfb, 0x25, 0x98, 0x26, 0xf1, 0xea, 0xaa, 0x90, 0xc3, 0xd0, 0x9b, + 0x66, 0x5b, 0xc3, 0x73, 0x68, 0x78, 0x4e, 0xa5, 0x76, 0x9e, 0x56, 0xbe, 0xb1, 0xf6, 0x35, 0xad, + 0xe1, 0xda, 0x6d, 0x9c, 0x01, 0xc9, 0x47, 0x0e, 0xc6, 0x84, 0x92, 0x15, 0x6a, 0x4f, 0x58, 0xba, + 0x22, 0x1e, 0xfe, 0x0f, 0x54, 0x57, 0xea, 0x27, 0xc6, 0x9c, 0x02, 0x12, 0x6c, 0xf9, 0x35, 0x4f, + 0x6f, 0x22, 0x60, 0x38, 0x96, 0x21, 0xcc, 0x04, 0x10, 0x3d, 0x5e, 0x94, 0xdd, 0xca, 0xf0, 0x86, + 0x32, 0x67, 0x8a, 0x39, 0x0e, 0xff, 0xb6, 0xb4, 0xac, 0x35, 0x67, 0x57, 0xe6, 0x43, 0x3d, 0xba, + 0xfa, 0x2d, 0x10, 0xb9, 0x2f, 0x2a, 0x5d, 0x65, 0xf5, 0xae, 0xa4, 0xf7, 0x30, 0x91, 0x6a, 0xab, + 0x17, 0xa0, 0xcc, 0xc6, 0x53, 0xfe, 0x3b, 0x8d, 0xb1, 0xea, 0xab, 0x8f, 0xef, 0xe4, 0xad, 0x2c, + 0x95, 0x24, 0x1f, 0x5f, 0xf9, 0x93, 0x54, 0x84, 0xae, 0xf7, 0xe9, 0x3a, 0x59, 0xb8, 0x04, 0x68, + 0x64, 0x31, 0xbe, 0x65, 0xa5, 0xdf, 0xb8, 0x79, 0x99, 0xba, 0x1b, 0xad, 0x9c, 0x3a, 0x16, 0x23, + 0x34, 0xe1, 0xc6, 0x98, 0xa8, 0xcd, 0xa5, 0x45, 0x32, 0x11, 0x03, 0x88, 0x54, 0x5f, 0x29, 0x8e, + 0x1a, 0x4a, 0xf5, 0x4d, 0x8c, 0x07, 0x35, 0x5d, 0x93, 0x5a, 0xb6, 0x4c, 0xf0, 0x2b, 0xcc, 0x07, + 0x0f, 0x0f, 0x40, 0x82, 0x5d, 0xfb, 0xf5, 0x3a, 0x1b, 0x18, 0x7c, 0x7b, 0x4d, 0xc1, 0xcc, 0x72, + 0x68, 0xf5, 0x85, 0x36, 0x89, 0x0d, 0x04, 0x59, 0x22, 0xc9, 0x35, 0xc4, 0x1a, 0xa9, 0x0f, 0xfd, + 0x6d, 0x6e, 0x8d, 0x9f, 0x01, 0x6b, 0x35, 0xc7, 0x46, 0x85, 0x8d, 0x5d, 0x22, 0x9d, 0xa6, 0xe6, + 0x88, 0xb5, 0x60, 0xd2, 0xd1, 0x0d, 0x10, 0x98, 0xe1, 0xfc, 0x12, 0x4f, 0x47, 0x59, 0x1f, 0x66, + 0x07, 0x0a, 0x53, 0xa3, 0x43, 0xf4, 0x9f, 0x5e, 0x97, 0xa9, 0xf7, 0x87, 0x69, 0xd3, 0xac, 0x5b, + 0x52, 0xf2, 0x5b, 0xc0, 0xbf, 0xe9, 0xe0, 0xe9, 0xae, 0x33, 0xee, 0xbc, 0xc0, 0x3f, 0x4a, 0xaf, + 0x4c, 0x6b, 0xad, 0x41, 0x94, 0xfa, 0xe9, 0x4d, 0x38, 0x62, 0x2f, 0x2b, 0x0e, 0x48, 0x94, 0x82, + 0xe3, 0x40, 0xbf, 0x80, 0x74, 0x2e, 0xe8, 0x13, 0xa3, 0x19, 0x75, 0x52, 0xaa, 0xd1, 0xa1, 0x31, + 0xbe, 0xcd, 0xf3, 0xe0, 0xae, 0x1f, 0x17, 0xf4, 0x97, 0x1b, 0x69, 0x52, 0xfe, 0x32, 0x82, 0x9d, + 0xf1, 0xbb, 0x28, 0xca, 0xba, 0xbc, 0x47, 0xf6, 0x44, 0xbf, 0xdf, 0xc7, 0x80, 0x96, 0xa1, 0x8a, + 0x0e, 0x45, 0x24, 0x27, 0x53, 0xe4, 0x2d, 0x8c, 0x0e, 0x10, 0xc9, 0x75, 0x58, 0x59, 0x8f, 0xa2, + 0x05, 0x17, 0x43, 0x15, 0xa9, 0x2c, 0xaf, 0x63, 0x62, 0x3d, 0xd2, 0x4b, 0x56, 0x0e, 0x8a, 0xab, + 0x12, 0xf3, 0xd6, 0x69, 0x5c, 0xcb, 0x97, 0x5c, 0x95, 0x2e, 0x81, 0xb8, 0x5d, 0xf9, 0x3a, 0xa9, + 0xcc, 0xd7, 0x21, 0x59, 0xac, 0xe6, 0x38, 0x8b, 0x9e, 0x16, 0xf5, 0xb5, 0x64, 0x4a, 0xa0, 0x73, + 0x47, 0x9c, 0x53, 0x7b, 0xae, 0x5e, 0x0d, 0xf9, 0x5e, 0x50, 0xf6, 0x58, 0xdc, 0x6f, 0xc4, 0x46, + 0x09, 0xa0, 0x75, 0xcc, 0x50, 0x91, 0x9e, 0xb0, 0x3b, 0xaa, 0xdc, 0x84, 0xcb, 0x3e, 0x1f, 0xe8, + 0xc1, 0xaa, 0xae, 0xbb, 0xda, 0xd8, 0xcf, 0x00, 0x4a, 0xcc, 0x6e, 0x9d, 0x17, 0x35, 0x8b, 0xda, + 0xa7, 0xb9, 0x6d, 0x9f, 0x58, 0x01, 0xf1, 0x7e, 0x62, 0xec, 0x4b, 0x5e, 0x1e, 0xcc, 0x66, 0xdf, + 0xa3, 0x4a, 0x18, 0xf7, 0x8b, 0x08, 0xd8, 0x3a, 0x9d, 0xd4, 0xa1, 0x19, 0x28, 0x88, 0x7f, 0x2c, + 0xcb, 0x26, 0x6a, 0xb5, 0x59, 0x7c, 0x99, 0xa2, 0xbd, 0x48, 0x7a, 0x83, 0x4d, 0xe3, 0xe6, 0x62, + 0xd5, 0x70, 0x96, 0x2f, 0x51, 0x86, 0xa3, 0x13, 0x66, 0xb3, 0xc2, 0xb6, 0x2e, 0xd2, 0x35, 0x56, + 0x40, 0xb1, 0xe3, 0xa1, 0x1e, 0xa8, 0xf8, 0x3a, 0xdb, 0xb1, 0x34, 0xc1, 0x13, 0xad, 0x66, 0xf5, + 0xe2, 0xc7, 0x03, 0xd8, 0xd3, 0xe3, 0xac, 0x3c, 0x11, 0xc7, 0x03, 0x8c, 0xcf, 0x88, 0x7f, 0x17, + 0xe5, 0x32, 0x39, 0xf9, 0xbf, 0x4e, 0x14, 0xf6, 0x99, 0xec, 0x94, 0x01, 0x00 }; diff --git a/wled00/json.cpp b/wled00/json.cpp index 7c3ce05f..755f8096 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -341,7 +341,6 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme if (errorFlag) root[F("error")] = errorFlag; root[F("ps")] = currentPreset; - root[F("pss")] = savedPresets; root[F("pl")] = (presetCyclingEnabled) ? 0: -1; usermods.addToJsonState(root); @@ -603,7 +602,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) for (uint16_t i= 0; i < used; i += n) { - olen += sprintf(obuf + olen, "\"%06X\",", strip.getPixelColor(i)); + olen += sprintf(obuf + olen, "\"%06X\",", strip.getPixelColor(i) & 0xFFFFFF); } olen -= 1; oappend((const char*)F("],\"n\":")); diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index 66986fa8..919ece0e 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -51,4 +51,42 @@ bool PinManagerClass::isPinOk(byte gpio, bool output) #endif return false; -} \ No newline at end of file +} + +#ifdef ARDUINO_ARCH_ESP32 +byte PinManagerClass::allocateLedc(byte channels) +{ + if (channels > 16 || channels == 0) return 255; + byte ca = 0; + for (byte i = 0; i < 16; i++) { + byte by = i >> 3; + byte bi = i - 8*by; + if (bitRead(ledcAlloc[by], bi)) { //found occupied pin + ca = 0; + } else { + ca++; + } + if (ca >= channels) { //enough free channels + byte in = (i + 1) - ca; + for (byte j = 0; j < ca; j++) { + byte b = in + j; + byte by = b >> 3; + byte bi = b - 8*by; + bitWrite(ledcAlloc[by], bi, true); + } + return in; + } + } + return 255; //not enough consecutive free LEDC channels +} + +void PinManagerClass::deallocateLedc(byte pos, byte channels) +{ + for (byte j = pos; j < pos + channels; j++) { + if (j > 16) return; + byte by = j >> 3; + byte bi = j - 8*by; + bitWrite(ledcAlloc[by], bi, false); + } +} +#endif \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index 8915bbcd..6b15734c 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -498,7 +498,6 @@ WLED_GLOBAL JsonDocument* fileDoc; WLED_GLOBAL bool doCloseFile _INIT(false); // presets -WLED_GLOBAL uint16_t savedPresets _INIT(0); WLED_GLOBAL int16_t currentPreset _INIT(-1); WLED_GLOBAL bool isPreset _INIT(false); From c4d8ef59544d01cf4fb15cfd3beafaef17e3ec71 Mon Sep 17 00:00:00 2001 From: Sander Schutten Date: Sat, 19 Dec 2020 17:26:36 +0000 Subject: [PATCH 03/29] Added liveviewws-page for liveview via websockets --- tools/cdata.js | 8 + wled00/data/liveviewws.htm | 62 + wled00/html_other.h | 11 + wled00/html_ui.h | 2832 ++++++++++++++++++------------------ wled00/wled_server.cpp | 12 +- 5 files changed, 1503 insertions(+), 1422 deletions(-) create mode 100644 wled00/data/liveviewws.htm diff --git a/tools/cdata.js b/tools/cdata.js index aa473deb..dd2bc7f2 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -386,6 +386,14 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()====="; method: "plaintext", filter: "html-minify", }, + { + file: "liveviewws.htm", + name: "PAGE_liveviewws", + prepend: "=====(", + append: ")=====", + method: "plaintext", + filter: "html-minify", + }, { file: "404.htm", name: "PAGE_404", diff --git a/wled00/data/liveviewws.htm b/wled00/data/liveviewws.htm new file mode 100644 index 00000000..bc1e8293 --- /dev/null +++ b/wled00/data/liveviewws.htm @@ -0,0 +1,62 @@ + + + + + + + WLED Live Preview + + + +
+ + + \ No newline at end of file diff --git a/wled00/html_other.h b/wled00/html_other.h index 1e51b213..c363f6b3 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -76,6 +76,17 @@ update();var tmout=null;function update(){if(document.hidden)return clearTimeout )====="; +// Autogenerated from wled00/data/liveviewws.htm, do not edit!! +const char PAGE_liveviewws[] PROGMEM = R"=====( +WLED Live Preview
)====="; + + // Autogenerated from wled00/data/404.htm, do not edit!! const char PAGE_404[] PROGMEM = R"=====(send_P(200, "text/html", PAGE_liveview); - }); + #ifdef WLED_ENABLE_WEBSOCKETS + server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send_P(200, "text/html", PAGE_liveviewws); + }); + #else + server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send_P(200, "text/html", PAGE_liveview); + }); + #endif //settings page server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){ From fcf0e08e013dd3f38a6c841d2039d2b18c36fb7c Mon Sep 17 00:00:00 2001 From: xBelladonna Date: Sat, 26 Dec 2020 05:47:30 +0930 Subject: [PATCH 04/29] Add BME280 v2 usermod --- usermods/BME280_v2/usermod_bme280.h | 212 ++++++++++++++++++++++++++++ wled00/usermods_list.cpp | 13 ++ 2 files changed, 225 insertions(+) create mode 100644 usermods/BME280_v2/usermod_bme280.h diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h new file mode 100644 index 00000000..80a31a4f --- /dev/null +++ b/usermods/BME280_v2/usermod_bme280.h @@ -0,0 +1,212 @@ +#pragma once + +#include "wled.h" +#include +#include +#include // BME280 sensor +#include // BME280 extended measurements + +class UsermodBME280 : public Usermod +{ +private: +// User-defined configuration +#define Celsius // Show temperature mesaurement in Celcius. Comment out for Fahrenheit +#define TemperatureDecimals 1 // Number of decimal places in published temperaure values +#define HumidityDecimals 0 // Number of decimal places in published humidity values +#define PressureDecimals 2 // Number of decimal places in published pressure values +#define TemperatureInterval 5 // Interval to measure temperature (and humidity, dew point if available) in seconds +#define PressureInterval 300 // Interval to measure pressure in seconds + +// Sanity checks +#if !defined(TemperatureDecimals) || TemperatureDecimals < 0 + #define TemperatureDecimals 0 +#endif +#if !defined(HumidityDecimals) || HumidityDecimals < 0 + #define HumidityDecimals 0 +#endif +#if !defined(PressureDecimals) || PressureDecimals < 0 + #define PressureDecimals 0 +#endif +#if !defined(TemperatureInterval) || TemperatureInterval < 0 + #define TemperatureInterval 1 +#endif +#if !defined(PressureInterval) || PressureInterval < 0 + #define PressureInterval TemperatureInterval +#endif + +#ifdef ARDUINO_ARCH_ESP32 // ESP32 boards + uint8_t SCL_PIN = 22; + uint8_t SDA_PIN = 21; +#else // ESP8266 boards + uint8_t SCL_PIN = 5; + uint8_t SDA_PIN = 4; + //uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 +#endif + + // BME280 sensor settings + BME280I2C::Settings settings{ + BME280::OSR_X16, // Temperature oversampling x16 + BME280::OSR_X16, // Humidity oversampling x16 + BME280::OSR_X16, // Pressure oversampling x16 + // Defaults + BME280::Mode_Forced, + BME280::StandbyTime_1000ms, + BME280::Filter_Off, + BME280::SpiEnable_False, + BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76 + }; + + BME280I2C bme{settings}; + + uint8_t SensorType; + + // Measurement timers + long timer; + long lastTemperatureMeasure = 0; + long lastPressureMeasure = 0; + + // Current sensor values + float SensorTemperature; + float SensorHumidity; + float SensorHeatIndex; + float SensorDewPoint; + float SensorPressure; + // Track previous sensor values + float lastTemperature; + float lastHumidity; + float lastHeatIndex; + float lastDewPoint; + float lastPressure; + + // Store packet IDs of MQTT publications + uint16_t mqttTemperaturePub = 0; + uint16_t mqttPressurePub = 0; + + void UpdateBME280Data(int SensorType) + { + float _temperature, _humidity, _pressure; + #ifdef Celsius + BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); + EnvironmentCalculations::TempUnit envTempUnit(EnvironmentCalculations::TempUnit_Celsius); + #else + BME280::TempUnit tempUnit(BME280::TempUnit_Fahrenheit); + EnvironmentCalculations::TempUnit envTempUnit(EnvironmentCalculations::TempUnit_Fahrenheit); + #endif + BME280::PresUnit presUnit(BME280::PresUnit_hPa); + + bme.read(_pressure, _temperature, _humidity, tempUnit, presUnit); + + SensorTemperature = _temperature; + SensorHumidity = _humidity; + SensorPressure = _pressure; + if (SensorType == 1) + { + SensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit); + SensorDewPoint = EnvironmentCalculations::DewPoint(_temperature, _humidity, envTempUnit); + } + } + +public: + void setup() + { + Wire.begin(SDA_PIN, SCL_PIN); + + if (!bme.begin()) + { + SensorType = 0; + Serial.println("Could not find BME280I2C sensor!"); + } + else + { + switch (bme.chipModel()) + { + case BME280::ChipModel_BME280: + SensorType = 1; + Serial.println("Found BME280 sensor! Success."); + break; + case BME280::ChipModel_BMP280: + SensorType = 2; + Serial.println("Found BMP280 sensor! No Humidity available."); + break; + default: + SensorType = 0; + Serial.println("Found UNKNOWN sensor! Error!"); + } + } + } + + void loop() + { + // BME280 sensor MQTT publishing + // Check if sensor present and MQTT Connected, otherwise it will crash the MCU + if (SensorType != 0 && mqtt != nullptr) + { + // Timer to fetch new temperature, humidity and pressure data at intervals + timer = millis(); + + if (timer - lastTemperatureMeasure >= TemperatureInterval * 1000 || mqttTemperaturePub == 0) + { + lastTemperatureMeasure = timer; + + UpdateBME280Data(SensorType); + + float Temperature = roundf(SensorTemperature * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals); + float Humidity, HeatIndex, DewPoint; + + // If temperature has changed since last measure, create string populated with device topic + // from the UI and values read from sensor, then publish to broker + if (Temperature != lastTemperature) + { + String topic = String(mqttDeviceTopic) + "/temperature"; + mqttTemperaturePub = mqtt->publish(topic.c_str(), 0, false, String(Temperature, TemperatureDecimals).c_str()); + } + + lastTemperature = Temperature; // Update last sensor temperature for next loop + + if (SensorType == 1) // Only if sensor is a BME280 + { + Humidity = roundf(SensorHumidity * pow(10, HumidityDecimals)) / pow(10, HumidityDecimals); + HeatIndex = roundf(SensorHeatIndex * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals); + DewPoint = roundf(SensorDewPoint * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals); + + if (Humidity != lastHumidity) + { + String topic = String(mqttDeviceTopic) + "/humidity"; + mqtt->publish(topic.c_str(), 0, false, String(Humidity, HumidityDecimals).c_str()); + } + + if (HeatIndex != lastHeatIndex) + { + String topic = String(mqttDeviceTopic) + "/heat_index"; + mqtt->publish(topic.c_str(), 0, false, String(HeatIndex, TemperatureDecimals).c_str()); + } + + if (DewPoint != lastDewPoint) + { + String topic = String(mqttDeviceTopic) + "/dew_point"; + mqtt->publish(topic.c_str(), 0, false, String(DewPoint, TemperatureDecimals).c_str()); + } + + lastHumidity = Humidity; + lastHeatIndex = HeatIndex; + lastDewPoint = DewPoint; + } + } + + if (timer - lastPressureMeasure >= PressureInterval * 1000 || mqttPressurePub == 0) + { + lastPressureMeasure = timer; + + float Pressure = roundf(SensorPressure * pow(10, PressureDecimals)) / pow(10, PressureDecimals); + + if (Pressure != lastPressure) + { + String topic = String(mqttDeviceTopic) + "/pressure"; + mqttPressurePub = mqtt->publish(topic.c_str(), 0, true, String(Pressure, PressureDecimals).c_str()); + } + + lastPressure = Pressure; + } + } + } +}; \ No newline at end of file diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 90b18074..fbbe0391 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -14,6 +14,13 @@ #include "../usermods/Temperature/usermod_temperature.h" #endif //#include "usermod_v2_empty.h" +#ifdef USERMOD_BUZZER +#include "../usermods/buzzer/usermod_v2_buzzer.h" +#endif +// BME280 v2 usermod. Define "USERMOD_BME280" in my_config.h +#ifdef USERMOD_BME280 +#include "../usermods/BME280_v2/usermod_bme280.h" +#endif void registerUsermods() { @@ -27,4 +34,10 @@ void registerUsermods() usermods.add(new UsermodTemperature()); #endif //usermods.add(new UsermodRenameMe()); + #ifdef USERMOD_BUZZER + usermods.add(new BuzzerUsermod()); + #endif + #ifdef USERMOD_BME280 + usermods.add(new UsermodBME280()); + #endif } \ No newline at end of file From 36abe8e808800f279711317fc832757261b7ca32 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 26 Dec 2020 00:57:39 +0100 Subject: [PATCH 05/29] Added PR message to BME280 usermod as readme --- usermods/BME280_v2/README.md | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 usermods/BME280_v2/README.md diff --git a/usermods/BME280_v2/README.md b/usermods/BME280_v2/README.md new file mode 100644 index 00000000..216ca630 --- /dev/null +++ b/usermods/BME280_v2/README.md @@ -0,0 +1,40 @@ +Hello! I have written a v2 usermod for the BME280/BMP280 sensor based on the [existing v1 usermod](https://github.com/Aircoookie/WLED/blob/master/usermods/Wemos_D1_mini%2BWemos32_mini_shield/usermod_bme280.cpp). It is not just a refactor, there are many changes which I made to fit my use case, and I hope they will fit the use cases of others as well! Most notably, this usermod is *just* for the BME280 and does not control a display like in the v1 usermod designed for the WeMos shield. + +- Requires libraries `BME280@~3.0.0` (by [finitespace](https://github.com/finitespace/BME280)) and `Wire`. Please add these under `lib_deps` in your `platform.ini` (or `platform_override.ini`). +- Data is published over MQTT so make sure you've enabled the MQTT sync interface. +- This usermod also writes to serial (GPIO1 on ESP8266). Please make sure nothing else listening on the serial TX pin of your board will get confused by log messages! + +To enable, compile with `USERMOD_BME280` defined (i.e. `platformio_override.ini`) +```ini +build_flags = + ${common.build_flags_esp8266} + -D USERMOD_BME280 +``` +or define `USERMOD_BME280` in `my_config.h` +```c++ +#define USERMOD_BME280 +``` + +Changes include: +- Adjustable measure intervals + - Temperature and pressure have separate intervals due to pressure not frequently changing at any constant altitude +- Adjustment of number of decimal places in published sensor values + - Separate adjustment for temperature, humidity and pressure values + - Values are rounded to the specified number of decimal places +- Pressure measured in units of hPa instead of Pa +- Calculation of heat index (apparent temperature) and dew point + - These, along with humidity measurements, are disabled if the sensor is a BMP280 +- 16x oversampling of sensor during measurement +- Values are only published if they are different from the previous value +- Values are published on startup (continually until the MQTT broker acknowledges a successful publication) + +Adjustments are made through preprocessor definitions at the start of the class definition. + +MQTT topics are as follows: +Measurement type | MQTT topic +--- | --- +Temperature | `/temperature` +Humidity | `/humidity` +Pressure | `/pressure` +Heat index | `/heat_index` +Dew point | `/dew_point` \ No newline at end of file From ef904e01ec750709edb526c5670e148d09c78a7d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 15 Jan 2021 15:43:11 +0100 Subject: [PATCH 06/29] Circular include problem --- wled00/FX.h | 42 ++++- wled00/FX_fcn.cpp | 88 +++------ wled00/NpbWrapper.h | 439 ------------------------------------------- wled00/bus_manager.h | 135 ++++++++----- wled00/bus_wrapper.h | 78 +++++++- 5 files changed, 220 insertions(+), 562 deletions(-) delete mode 100644 wled00/NpbWrapper.h diff --git a/wled00/FX.h b/wled00/FX.h index 27329a0a..bfe0f6bc 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -27,10 +27,40 @@ #ifndef WS2812FX_h #define WS2812FX_h +//TEMPORARY DEFINES FOR TESTING - MAKE THESE RUNTIME CONFIGURABLE TOO! +#ifndef LEDPIN +#define LEDPIN 2 +#endif + +#ifndef BTNPIN +#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) +#endif + +#ifndef TOUCHPIN +//#define TOUCHPIN T0 //touch pin. Behaves the same as button. ESP32 only. +#endif + +#ifndef IRPIN +#define IRPIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#endif + +#ifndef RLYPIN +#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#endif + +#ifndef AUXPIN +#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) +#endif + +#ifndef RLYMDE +#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on +#endif +//END OF TEMP DEFINES + #ifdef ESP32_MULTISTRIP #include "../usermods/esp32_multistrip/NpbWrapper.h" #else - #include "NpbWrapper.h" + #include "bus_manager.h" #endif #include "const.h" @@ -584,7 +614,7 @@ class WS2812FX { ablMilliampsMax = 850; currentMilliamps = 0; timebase = 0; - bus = new NeoPixelWrapper(); + busses = new BusManager(); resetSegments(); } @@ -794,7 +824,7 @@ class WS2812FX { mode_dynamic_smooth(void); private: - NeoPixelWrapper *bus; + BusManager *busses; uint32_t crgb_to_col(CRGB fastled); CRGB col_to_crgb(uint32_t); @@ -855,12 +885,6 @@ class WS2812FX { uint32_t _colors_t[3]; uint8_t _bri_t; - #ifdef WLED_USE_ANALOG_LEDS - uint32_t _analogLastShow = 0; - RgbwColor _analogLastColor = 0; - uint8_t _analogLastBri = 0; - #endif - uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 8c1681a3..0fbd05d4 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -56,14 +56,13 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) _length = countPixels; _skipFirstMode = skipFirst; - uint8_t ty = 1; - if (supportWhite) ty = 2; _lengthRaw = _length; if (_skipFirstMode) { _lengthRaw += LED_SKIP_AMOUNT; } - bus->Begin((NeoPixelType)ty, _lengthRaw); + uint8_t pins[] = {2}; + busses->add(supportWhite? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, countPixels); _segments[0].start = 0; _segments[0].stop = _length; @@ -167,19 +166,17 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } } - RgbwColor col; - col.R = r; col.G = g; col.B = b; col.W = w; - uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; if (SEGLEN) {//from segment //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) if (_bri_t < 255) { - col.R = scale8(col.R, _bri_t); - col.G = scale8(col.G, _bri_t); - col.B = scale8(col.B, _bri_t); - col.W = scale8(col.W, _bri_t); + r = scale8(r, _bri_t); + g = scale8(g, _bri_t); + b = scale8(b, _bri_t); + w = scale8(w, _bri_t); } + uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ bool reversed = reverseMode ^ IS_REVERSE; @@ -193,12 +190,12 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; #endif if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) { - bus->SetPixelColor(indexSet + skip, col); + busses->setPixelColor(indexSet + skip, col); if (IS_MIRROR) { //set the corresponding mirrored pixel if (reverseMode) { - bus->SetPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); + busses->setPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); } else { - bus->SetPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); + busses->setPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); } } } @@ -208,11 +205,12 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) #ifdef WLED_CUSTOM_LED_MAPPING if (i < customMappingSize) i = customMappingTable[i]; #endif - bus->SetPixelColor(i + skip, col); + uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); + busses->setPixelColor(i + skip, col); } if (skip && i == 0) { for (uint16_t j = 0; j < skip; j++) { - bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0)); + busses->setPixelColor(j, BLACK); } } } @@ -263,7 +261,7 @@ void WS2812FX::show(void) { for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED { - RgbwColor c = bus->GetPixelColorRaw(i); + RgbwColor c = busses->getPixelColor(i); if(useWackyWS2815PowerModel) { @@ -292,24 +290,24 @@ void WS2812FX::show(void) { uint16_t scaleI = scale * 255; uint8_t scaleB = (scaleI > 255) ? 255 : scaleI; uint8_t newBri = scale8(_brightness, scaleB); - bus->SetBrightness(newBri); + busses->setBrightness(newBri); currentMilliamps = (powerSum0 * newBri) / puPerMilliamp; } else { currentMilliamps = powerSum / puPerMilliamp; - bus->SetBrightness(_brightness); + busses->setBrightness(_brightness); } currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate currentMilliamps += _length; //add standby power back to estimate } else { currentMilliamps = 0; - bus->SetBrightness(_brightness); + busses->setBrightness(_brightness); } // some buses send asynchronously and this method will return before // all of the data has been sent. // See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods - bus->Show(); + busses->show(); _lastShow = millis(); } @@ -318,7 +316,7 @@ void WS2812FX::show(void) { * On some hardware (ESP32), strip updates are done asynchronously. */ bool WS2812FX::isUpdating() { - return !bus->CanShow(); + return !busses->canAllShow(); } /** @@ -428,7 +426,8 @@ void WS2812FX::setBrightness(uint8_t b) { if (shouldStartBus) { shouldStartBus = false; const uint8_t ty = _useRgbw ? 2 : 1; - bus->Begin((NeoPixelType)ty, _lengthRaw); + //TODO add re-init method for any bus type that uses GPIO2 on ESP8266 here + //bus->Begin((NeoPixelType)ty, _lengthRaw); } #endif } @@ -490,7 +489,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) if (i >= _lengthRaw) return 0; - return bus->GetPixelColorRgbw(i); + return busses->getPixelColor(i); } WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { @@ -510,12 +509,13 @@ uint32_t WS2812FX::getLastShow(void) { return _lastShow; } +//TODO these need to be on a per-strip basis uint8_t WS2812FX::getColorOrder(void) { - return bus->GetColorOrder(); + return COL_ORDER_GRB; } void WS2812FX::setColorOrder(uint8_t co) { - bus->SetColorOrder(co); + //bus->SetColorOrder(co); } void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) { @@ -967,44 +967,6 @@ bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b) return true; } -#ifdef WLED_USE_ANALOG_LEDS -void WS2812FX::setRgbwPwm(void) { - uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days - if (nowUp - _analogLastShow < MIN_SHOW_DELAY) return; - - _analogLastShow = nowUp; - - RgbwColor c; - uint32_t col = bus->GetPixelColorRgbw(PWM_INDEX); - c.R = col >> 16; c.G = col >> 8; c.B = col; c.W = col >> 24; - - byte b = getBrightness(); - if (c == _analogLastColor && b == _analogLastBri) return; - - // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp - #ifdef WLED_USE_5CH_LEDS - if (c.R == 255 && c.G == 255 && c.B == 255 && c.W == 255) { - bus->SetRgbwPwm(0, 0, 0, 0, c.W * b / 255); - } else if (c.R == 127 && c.G == 127 && c.B == 127 && c.W == 255) { - bus->SetRgbwPwm(0, 0, 0, c.W * b / 512, c.W * b / 255); - } else if (c.R == 0 && c.G == 0 && c.B == 0 && c.W == 255) { - bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0); - } else if (c.R == 130 && c.G == 90 && c.B == 0 && c.W == 255) { - bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, c.W * b / 512); - } else if (c.R == 255 && c.G == 153 && c.B == 0 && c.W == 255) { - bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0); - } else { // not only white colors - bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255); - } - #else - bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255); - #endif - _analogLastColor = c; - _analogLastBri = b; -} -#else -void WS2812FX::setRgbwPwm() {} -#endif //gamma 2.8 lookup table used for color correction byte gammaT[] = { diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h deleted file mode 100644 index 8c1860b2..00000000 --- a/wled00/NpbWrapper.h +++ /dev/null @@ -1,439 +0,0 @@ -//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103 -#ifndef NpbWrapper_h -#define NpbWrapper_h - -//PIN CONFIGURATION -#ifndef LEDPIN -#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) -#endif -//#define USE_APA102 // Uncomment for using APA102 LEDs. -//#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) -//#define USE_LPD8806 // Uncomment for using LPD8806 -//#define USE_TM1814 // Uncomment for using TM1814 LEDs (make sure you have NeoPixelBus v2.5.7 or newer) -//#define USE_P9813 // Uncomment for using P9813 LEDs (make sure you have NeoPixelBus v2.5.8 or newer) -//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13) -//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well -//#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white -//#define WLED_USE_BWLT11 -//#define WLED_USE_SHOJO_PCB - -#ifndef BTNPIN -#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#endif - -#ifndef TOUCHPIN -//#define TOUCHPIN T0 //touch pin. Behaves the same as button. ESP32 only. -#endif - -#ifndef IRPIN -#define IRPIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#endif - -#ifndef RLYPIN -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... -#endif - -#ifndef AUXPIN -#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) -#endif - -#ifndef RLYMDE -#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on -#endif - -//enable color order override for a specific range of the strip -//This can be useful if you want to chain multiple strings with incompatible color order -//#define COLOR_ORDER_OVERRIDE -#define COO_MIN 0 -#define COO_MAX 35 //not inclusive, this would set the override for LEDs 0-26 -#define COO_ORDER COL_ORDER_GRB - -//END CONFIGURATION - -#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) - #ifndef CLKPIN - #define CLKPIN 0 - #endif - #ifndef DATAPIN - #define DATAPIN 2 - #endif - #if BTNPIN == CLKPIN || BTNPIN == DATAPIN - #undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins. - #endif -#endif - -#ifdef WLED_USE_ANALOG_LEDS - //PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller - #ifdef WLED_USE_H801 - #define RPIN 15 //R pin for analog LED strip - #define GPIN 13 //G pin for analog LED strip - #define BPIN 12 //B pin for analog LED strip - #define WPIN 14 //W pin for analog LED strip - #define W2PIN 04 //W2 pin for analog LED strip - #undef BTNPIN - #undef IRPIN - #define IRPIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 - #elif defined(WLED_USE_BWLT11) - //PWM pins - to use with BW-LT11 - #define RPIN 12 //R pin for analog LED strip - #define GPIN 4 //G pin for analog LED strip - #define BPIN 14 //B pin for analog LED strip - #define WPIN 5 //W pin for analog LED strip - #elif defined(WLED_USE_SHOJO_PCB) - //PWM pins - to use with Shojo PCB (https://www.bastelbunker.de/esp-rgbww-wifi-led-controller-vbs-edition/) - #define RPIN 14 //R pin for analog LED strip - #define GPIN 4 //G pin for analog LED strip - #define BPIN 5 //B pin for analog LED strip - #define WPIN 15 //W pin for analog LED strip - #define W2PIN 12 //W2 pin for analog LED strip - #elif defined(WLED_USE_PLJAKOBS_PCB) - // PWM pins - to use with esp_rgbww_controller from patrickjahns/pljakobs (https://github.com/pljakobs/esp_rgbww_controller) - #define RPIN 12 //R pin for analog LED strip - #define GPIN 13 //G pin for analog LED strip - #define BPIN 14 //B pin for analog LED strip - #define WPIN 4 //W pin for analog LED strip - #define W2PIN 5 //W2 pin for analog LED strip - #undef IRPIN - #else - //Enable override of Pins by using the platformio_override.ini file - //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - #ifndef RPIN - #define RPIN 5 //R pin for analog LED strip - #endif - #ifndef GPIN - #define GPIN 12 //G pin for analog LED strip - #endif - #ifndef BPIN - #define BPIN 15 //B pin for analog LED strip - #endif - #ifndef WPIN - #define WPIN 13 //W pin for analog LED strip - #endif - #endif - #undef RLYPIN - #define RLYPIN -1 //disable as pin 12 is used by analog LEDs -#endif - -//automatically uses the right driver method for each platform -#ifdef ARDUINO_ARCH_ESP32 - #ifdef USE_APA102 - #define PIXELMETHOD DotStarMethod - #elif defined(USE_WS2801) - #define PIXELMETHOD NeoWs2801Method - #elif defined(USE_LPD8806) - #define PIXELMETHOD Lpd8806Method - #elif defined(USE_TM1814) - #define PIXELMETHOD NeoTm1814Method - #elif defined(USE_P9813) - #define PIXELMETHOD P9813Method - #else - #define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod - #endif -#else //esp8266 - //autoselect the right method depending on strip pin - #ifdef USE_APA102 - #define PIXELMETHOD DotStarMethod - #elif defined(USE_WS2801) - #define PIXELMETHOD NeoWs2801Method - #elif defined(USE_LPD8806) - #define PIXELMETHOD Lpd8806Method - #elif defined(USE_TM1814) - #define PIXELMETHOD NeoTm1814Method - #elif defined(USE_P9813) - #define PIXELMETHOD P9813Method - #elif LEDPIN == 2 - #define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus - #elif LEDPIN == 3 - #define PIXELMETHOD NeoEsp8266Dma800KbpsMethod - #else - #define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod - #pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results." - #endif -#endif - - -//you can now change the color order in the web settings -#ifdef USE_APA102 - #define PIXELFEATURE3 DotStarBgrFeature - #define PIXELFEATURE4 DotStarLbgrFeature -#elif defined(USE_LPD8806) - #define PIXELFEATURE3 Lpd8806GrbFeature - #define PIXELFEATURE4 Lpd8806GrbFeature -#elif defined(USE_WS2801) - #define PIXELFEATURE3 NeoRbgFeature - #define PIXELFEATURE4 NeoRbgFeature -#elif defined(USE_TM1814) - #define PIXELFEATURE3 NeoWrgbTm1814Feature - #define PIXELFEATURE4 NeoWrgbTm1814Feature -#elif defined(USE_P9813) - #define PIXELFEATURE3 P9813BgrFeature - #define PIXELFEATURE4 NeoGrbwFeature -#else - #define PIXELFEATURE3 NeoGrbFeature - #define PIXELFEATURE4 NeoGrbwFeature -#endif - - -#include -#include "const.h" - -enum NeoPixelType -{ - NeoPixelType_None = 0, - NeoPixelType_Grb = 1, - NeoPixelType_Grbw = 2, - NeoPixelType_End = 3 -}; - -class NeoPixelWrapper -{ -public: - NeoPixelWrapper() : - // initialize each member to null - _pGrb(NULL), - _pGrbw(NULL), - _type(NeoPixelType_None) - { - - } - - ~NeoPixelWrapper() - { - cleanup(); - } - - void Begin(NeoPixelType type, uint16_t countPixels) - { - cleanup(); - _type = type; - - switch (_type) - { - case NeoPixelType_Grb: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) - _pGrb = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); - #else - _pGrb = new NeoPixelBrightnessBus(countPixels, LEDPIN); - #endif - _pGrb->Begin(); - break; - - case NeoPixelType_Grbw: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) - _pGrbw = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); - #else - _pGrbw = new NeoPixelBrightnessBus(countPixels, LEDPIN); - #endif - _pGrbw->Begin(); - break; - } - - #ifdef WLED_USE_ANALOG_LEDS - #ifdef ARDUINO_ARCH_ESP32 - ledcSetup(0, 5000, 8); - ledcAttachPin(RPIN, 0); - ledcSetup(1, 5000, 8); - ledcAttachPin(GPIN, 1); - ledcSetup(2, 5000, 8); - ledcAttachPin(BPIN, 2); - if(_type == NeoPixelType_Grbw) - { - ledcSetup(3, 5000, 8); - ledcAttachPin(WPIN, 3); - #ifdef WLED_USE_5CH_LEDS - ledcSetup(4, 5000, 8); - ledcAttachPin(W2PIN, 4); - #endif - } - #else // ESP8266 - //init PWM pins - pinMode(RPIN, OUTPUT); - pinMode(GPIN, OUTPUT); - pinMode(BPIN, OUTPUT); - if(_type == NeoPixelType_Grbw) - { - pinMode(WPIN, OUTPUT); - #ifdef WLED_USE_5CH_LEDS - pinMode(W2PIN, OUTPUT); - #endif - } - analogWriteRange(255); //same range as one RGB channel - analogWriteFreq(880); //PWM frequency proven as good for LEDs - #endif - #endif - } - -#ifdef WLED_USE_ANALOG_LEDS - void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0) - { - #ifdef ARDUINO_ARCH_ESP32 - ledcWrite(0, r); - ledcWrite(1, g); - ledcWrite(2, b); - switch (_type) { - case NeoPixelType_Grb: break; - #ifdef WLED_USE_5CH_LEDS - case NeoPixelType_Grbw: ledcWrite(3, w); ledcWrite(4, w2); break; - #else - case NeoPixelType_Grbw: ledcWrite(3, w); break; - #endif - } - #else // ESP8266 - analogWrite(RPIN, r); - analogWrite(GPIN, g); - analogWrite(BPIN, b); - switch (_type) { - case NeoPixelType_Grb: break; - #ifdef WLED_USE_5CH_LEDS - case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break; - #else - case NeoPixelType_Grbw: analogWrite(WPIN, w); break; - #endif - } - #endif - } -#endif - - void Show() - { - switch (_type) - { - case NeoPixelType_Grb: _pGrb->Show(); break; - case NeoPixelType_Grbw: _pGrbw->Show(); break; - } - } - - /** - * This will return true if enough time has passed since the last time Show() was called. - * This also means that calling Show() will not cause any undue waiting. If the method for - * the defined bus is hardware that sends asynchronously, then call CanShow() will let - * you know if it has finished sending the data from the last Show(). - */ - bool CanShow() - { - switch (_type) - { - case NeoPixelType_Grb: return _pGrb->CanShow(); - case NeoPixelType_Grbw: return _pGrbw->CanShow(); - default: return true; - } - } - - void SetPixelColor(uint16_t indexPixel, RgbwColor c) - { - RgbwColor col; - - uint8_t co = _colorOrder; - #ifdef COLOR_ORDER_OVERRIDE - if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; - #endif - - //reorder channels to selected order - switch (co) - { - case 0: col.G = c.G; col.R = c.R; col.B = c.B; break; //0 = GRB, default - case 1: col.G = c.R; col.R = c.G; col.B = c.B; break; //1 = RGB, common for WS2811 - case 2: col.G = c.B; col.R = c.R; col.B = c.G; break; //2 = BRG - case 3: col.G = c.R; col.R = c.B; col.B = c.G; break; //3 = RBG - case 4: col.G = c.B; col.R = c.G; col.B = c.R; break; //4 = BGR - default: col.G = c.G; col.R = c.B; col.B = c.R; break; //5 = GBR - } - col.W = c.W; - - switch (_type) { - case NeoPixelType_Grb: { - _pGrb->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B)); - } - break; - case NeoPixelType_Grbw: { - #if defined(USE_LPD8806) || defined(USE_WS2801) - _pGrbw->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B)); - #else - _pGrbw->SetPixelColor(indexPixel, col); - #endif - } - break; - } - } - - void SetBrightness(byte b) - { - switch (_type) { - case NeoPixelType_Grb: _pGrb->SetBrightness(b); break; - case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break; - } - } - - void SetColorOrder(byte colorOrder) { - _colorOrder = colorOrder; - } - - uint8_t GetColorOrder() { - return _colorOrder; - } - - RgbwColor GetPixelColorRaw(uint16_t indexPixel) const - { - switch (_type) { - case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break; - case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break; - } - return 0; - } - - // NOTE: Due to feature differences, some support RGBW but the method name - // here needs to be unique, thus GetPixeColorRgbw - uint32_t GetPixelColorRgbw(uint16_t indexPixel) const - { - RgbwColor col(0,0,0,0); - switch (_type) { - case NeoPixelType_Grb: col = _pGrb->GetPixelColor(indexPixel); break; - case NeoPixelType_Grbw: col = _pGrbw->GetPixelColor(indexPixel); break; - } - - uint8_t co = _colorOrder; - #ifdef COLOR_ORDER_OVERRIDE - if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; - #endif - - switch (co) - { - // W G R B - case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default - case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 - case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG - case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG - case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR - case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR - } - return 0; - } - - uint8_t* GetPixels(void) - { - switch (_type) { - case NeoPixelType_Grb: return _pGrb->Pixels(); break; - case NeoPixelType_Grbw: return _pGrbw->Pixels(); break; - } - return 0; - } - - -private: - NeoPixelType _type; - - // have a member for every possible type - NeoPixelBrightnessBus* _pGrb; - NeoPixelBrightnessBus* _pGrbw; - - byte _colorOrder = 0; - - void cleanup() - { - switch (_type) { - case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break; - case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break; - } - } -}; -#endif diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 4cc16f0c..bae0dd1e 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -5,58 +5,10 @@ * Class for addressing various light types */ +#include "const.h" #include "wled.h" #include "bus_wrapper.h" -class BusManager { - public: - BusManager() { - - }; - - int add(uint8_t busType, uint8_t* pins, uint16_t len = 1) { - if (numBusses >= WLED_MAX_BUSSES) return -1; - if (IS_DIGITAL(busType)) { - busses[numBusses] = new BusDigital(busType, pins, len, numBusses); - } else { - busses[numBusses] = new BusPwm(busType, pins); - } - numBusses++; - return numBusses -1; - } - - void removeAll() { - for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; - numBusses = 0; - } - //void remove(uint8_t id); - - void show() { - for (uint8_t i = 0; i < numBusses; i++) { - busses[i]->show(); - } - } - - void setPixelColor(uint16_t pix, uint32_t c) { - for (uint8_t i = 0; i < numBusses; i++) { - Bus* b = busses[i]; - uint16_t bstart = b->getStart(); - if (pix < bstart) continue; - busses[i]->setPixelColor(pix - bstart, c); - } - } - - void setBrightness(uint8_t b) { - for (uint8_t i = 0; i < numBusses; i++) { - busses[i]->setBrightness(b); - } - } - - private: - uint8_t numBusses = 0; - Bus* busses[WLED_MAX_BUSSES]; -}; - //parent class of BusDigital and BusPwm class Bus { public: @@ -65,6 +17,7 @@ class Bus { }; virtual void show() {} + virtual bool canShow() { return true; } virtual void setPixelColor(uint16_t pix, uint32_t c) {}; @@ -88,6 +41,10 @@ class Bus { return COL_ORDER_RGB; } + virtual uint16_t getLength() { + return 1; + } + virtual void setColorOrder() {} uint8_t getType() { @@ -122,14 +79,27 @@ class BusDigital : public Bus { PolyBus::show(_busPtr, _iType); } - void setPixelColor(uint16_t pix, uint32_t c) { + bool canShow() { + return PolyBus::canShow(_busPtr, _iType); + } + void setPixelColor(uint16_t pix, uint32_t c) { + //TODO color order + } + + uint32_t getPixelColor(uint16_t pix) { + //TODO + return 0; } uint8_t getColorOrder() { return _colorOrder; } + uint16_t getLength() { + return _len; + } + void setColorOrder(uint8_t colorOrder) { if (colorOrder > 5) return; _colorOrder = colorOrder; @@ -242,4 +212,69 @@ class BusPwm : public Bus { } }; +class BusManager { + public: + BusManager() { + + }; + + int add(uint8_t busType, uint8_t* pins, uint16_t len = 1) { + if (numBusses >= WLED_MAX_BUSSES) return -1; + if (IS_DIGITAL(busType)) { + busses[numBusses] = new BusDigital(busType, pins, len, numBusses); + } else { + busses[numBusses] = new BusPwm(busType, pins); + } + numBusses++; + return numBusses -1; + } + + void removeAll() { + for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; + numBusses = 0; + } + //void remove(uint8_t id); + + void show() { + for (uint8_t i = 0; i < numBusses; i++) { + busses[i]->show(); + } + } + + void setPixelColor(uint16_t pix, uint32_t c) { + for (uint8_t i = 0; i < numBusses; i++) { + Bus* b = busses[i]; + uint16_t bstart = b->getStart(); + if (pix < bstart) continue; + busses[i]->setPixelColor(pix - bstart, c); + } + } + + void setBrightness(uint8_t b) { + for (uint8_t i = 0; i < numBusses; i++) { + busses[i]->setBrightness(b); + } + } + + uint32_t getPixelColor(uint16_t pix) { + for (uint8_t i = 0; i < numBusses; i++) { + Bus* b = busses[i]; + uint16_t bstart = b->getStart(); + if (pix < bstart || pix >= bstart + b->getLength()) continue; + return b->getPixelColor(pix - bstart); + } + return 0; + } + + bool canAllShow() { + for (uint8_t i = 0; i < numBusses; i++) { + if (busses[i]->canShow()) return false; + } + return true; + } + + private: + uint8_t numBusses = 0; + Bus* busses[WLED_MAX_BUSSES]; +}; #endif diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 98b3c789..d8809690 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -2,6 +2,7 @@ #define BusWrapper_h #include "wled.h" +#include "NeoPixelBrightnessBus.h" //Hardware SPI Pins #define P_8266_HS_MOSI 13 @@ -192,7 +193,82 @@ class PolyBus { public: static void show(void* busPtr, uint8_t busType) { - (static_cast*>(busPtr))->Show(); + (static_cast(busPtr))->Show(); + + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: (static_cast(busPtr))->Show(); break; + case I_8266_U1_NEO_3: (static_cast(busPtr))->Show(); break; + case I_8266_DM_NEO_3: (static_cast(busPtr))->Show(); break; + case I_8266_BB_NEO_3: (static_cast(busPtr))->Show(); break; + case I_8266_U0_NEO_4: (static_cast(busPtr))->Show(); break; + case I_8266_U1_NEO_4: (static_cast(busPtr))->Show(); break; + case I_8266_DM_NEO_4: (static_cast(busPtr))->Show(); break; + case I_8266_BB_NEO_4: (static_cast(busPtr))->Show(); break; + case I_8266_U0_400_3: (static_cast(busPtr))->Show(); break; + case I_8266_U1_400_3: (static_cast(busPtr))->Show(); break; + case I_8266_DM_400_3: (static_cast(busPtr))->Show(); break; + case I_8266_BB_400_3: (static_cast(busPtr))->Show(); break; + case I_8266_U0_TM1_4: (static_cast(busPtr))->Show(); break; + case I_8266_U1_TM1_4: (static_cast(busPtr))->Show(); break; + case I_8266_DM_TM1_4: (static_cast(busPtr))->Show(); break; + case I_8266_BB_TM1_4: (static_cast(busPtr))->Show(); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R1_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R2_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R3_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R4_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R5_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R6_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R7_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_I0_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_I1_NEO_3: (static_cast(busPtr))->Show(); break; + case I_32_R0_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R1_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R2_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R3_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R4_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R5_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R6_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R7_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_I0_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_I1_NEO_4: (static_cast(busPtr))->Show(); break; + case I_32_R0_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R1_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R2_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R3_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R4_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R5_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R6_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R7_400_3: (static_cast(busPtr))->Show(); break; + case I_32_I0_400_3: (static_cast(busPtr))->Show(); break; + case I_32_I1_400_3: (static_cast(busPtr))->Show(); break; + case I_32_R0_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R1_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R2_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R3_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R4_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R5_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R6_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_R7_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_I0_TM1_4: (static_cast(busPtr))->Show(); break; + case I_32_I1_TM1_4: (static_cast(busPtr))->Show(); break; + #endif + case I_HS_DOT_3: (static_cast(busPtr))->Show(); break; + case I_SS_DOT_3: (static_cast(busPtr))->Show(); break; + case I_HS_LPD_3: (static_cast(busPtr))->Show(); break; + case I_SS_LPD_3: (static_cast(busPtr))->Show(); break; + case I_HS_WS1_3: (static_cast(busPtr))->Show(); break; + case I_SS_WS1_3: (static_cast(busPtr))->Show(); break; + case I_HS_P98_3: (static_cast(busPtr))->Show(); break; + case I_SS_P98_3: (static_cast(busPtr))->Show(); break; + } + }; + static bool canShow(void* busPtr, uint8_t busType) { + return (static_cast(busPtr))->CanShow(); }; //gives back the internal type index (I_XX_XXX_X above) for the input static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { From b9346341597fcb6e5fa8c2b1e513e6dff0ea6863 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 16 Jan 2021 00:50:43 +0100 Subject: [PATCH 07/29] First light from busmanager! (still not usable though) --- wled00/bus_manager.h | 15 +- wled00/bus_wrapper.h | 305 ++++++++++++++++++++++++++++++++++++++++- wled00/fcn_declare.h | 21 --- wled00/pin_manager.cpp | 9 +- wled00/pin_manager.h | 29 ++++ wled00/wled.h | 3 +- 6 files changed, 347 insertions(+), 35 deletions(-) create mode 100644 wled00/pin_manager.h diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index bae0dd1e..6d1f3635 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -6,7 +6,7 @@ */ #include "const.h" -#include "wled.h" +#include "pin_manager.h" #include "bus_wrapper.h" //parent class of BusDigital and BusPwm @@ -58,7 +58,7 @@ class Bus { protected: uint8_t _type = TYPE_NONE; uint8_t _bri = 255; - uint16_t _start; + uint16_t _start = 0; bool _valid = false; }; @@ -69,11 +69,15 @@ class BusDigital : public Bus { if (!IS_DIGITAL(type) || !len) return; _pins[0] = pins[0]; if (IS_2PIN(type)) _pins[1] = pins[1]; + //TODO allocate pins with pin manager _len = len; _iType = PolyBus::getI(type, _pins, nr); if (_iType == I_NONE) return; - _valid = true; + _busPtr = PolyBus::begin(_iType, _pins, _len); + _valid = (_busPtr != nullptr); + Serial.printf("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType); }; + //TODO clean up stuff (destructor) void show() { PolyBus::show(_busPtr, _iType); @@ -83,8 +87,13 @@ class BusDigital : public Bus { return PolyBus::canShow(_busPtr, _iType); } + void setBrightness(uint8_t b) { + PolyBus::setBrightness(_busPtr, _iType, b); + } + void setPixelColor(uint16_t pix, uint32_t c) { //TODO color order + PolyBus::setPixelColor(_busPtr, _iType, pix, c); } uint32_t getPixelColor(uint16_t pix) { diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index d8809690..77ec01e3 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -1,7 +1,6 @@ #ifndef BusWrapper_h #define BusWrapper_h -#include "wled.h" #include "NeoPixelBrightnessBus.h" //Hardware SPI Pins @@ -192,9 +191,83 @@ //handles pointer type conversion for all possible bus types class PolyBus { public: + static void* begin(uint8_t busType, uint8_t* pins, uint16_t len) { + void* busPtr; + //delete busPtr; //TODO this needs type handling or destructor isn't called + switch (busType) { + case I_NONE: busPtr = new B_8266_U0_NEO_3(len, pins[0]); break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: busPtr = new B_8266_U0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U1_NEO_3: busPtr = new B_8266_U1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_DM_NEO_3: busPtr = new B_8266_DM_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_BB_NEO_3: busPtr = new B_8266_BB_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U0_NEO_4: busPtr = new B_8266_U0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U1_NEO_4: busPtr = new B_8266_U1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_DM_NEO_4: busPtr = new B_8266_DM_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_BB_NEO_4: busPtr = new B_8266_BB_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U0_400_3: busPtr = new B_8266_U0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U1_400_3: busPtr = new B_8266_U1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_DM_400_3: busPtr = new B_8266_DM_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_BB_400_3: busPtr = new B_8266_BB_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U0_TM1_4: busPtr = new B_8266_U0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: busPtr = new B_32_R0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R1_NEO_3: busPtr = new B_32_R1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R2_NEO_3: busPtr = new B_32_R2_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R3_NEO_3: busPtr = new B_32_R3_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R4_NEO_3: busPtr = new B_32_R4_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R5_NEO_3: busPtr = new B_32_R5_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R6_NEO_3: busPtr = new B_32_R6_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R7_NEO_3: busPtr = new B_32_R7_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R0_NEO_4: busPtr = new B_32_R0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R1_NEO_4: busPtr = new B_32_R1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R2_NEO_4: busPtr = new B_32_R2_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R3_NEO_4: busPtr = new B_32_R3_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R4_NEO_4: busPtr = new B_32_R4_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R5_NEO_4: busPtr = new B_32_R5_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R6_NEO_4: busPtr = new B_32_R6_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R7_NEO_4: busPtr = new B_32_R7_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R0_400_3: busPtr = new B_32_R0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R1_400_3: busPtr = new B_32_R1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R2_400_3: busPtr = new B_32_R2_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R3_400_3: busPtr = new B_32_R3_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R4_400_3: busPtr = new B_32_R4_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R5_400_3: busPtr = new B_32_R5_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R6_400_3: busPtr = new B_32_R6_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R7_400_3: busPtr = new B_32_R7_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R0_TM1_4: busPtr = new B_32_R0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R1_TM1_4: busPtr = new B_32_R1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R2_TM1_4: busPtr = new B_32_R2_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R3_TM1_4: busPtr = new B_32_R3_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R4_TM1_4: busPtr = new B_32_R4_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R5_TM1_4: busPtr = new B_32_R5_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R6_TM1_4: busPtr = new B_32_R6_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R7_TM1_4: busPtr = new B_32_R7_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + #endif + case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_SS_WS1_3: busPtr = new B_SS_WS1_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + } + return busPtr; + }; static void show(void* busPtr, uint8_t busType) { - (static_cast(busPtr))->Show(); - switch (busType) { case I_NONE: break; #ifdef ESP8266 @@ -268,8 +341,232 @@ class PolyBus { } }; static bool canShow(void* busPtr, uint8_t busType) { - return (static_cast(busPtr))->CanShow(); + switch (busType) { + case I_NONE: return true; + #ifdef ESP8266 + case I_8266_U0_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_TM1_4: return (static_cast(busPtr))->CanShow(); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R1_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R2_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R3_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R4_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R5_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R6_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R7_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_I0_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_I1_NEO_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R0_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R1_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R2_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R3_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R4_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R5_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R6_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R7_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_I0_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_I1_NEO_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R0_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R1_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R2_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R3_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R4_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R5_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R6_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R7_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_I0_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_I1_400_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_R0_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R1_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R2_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R3_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R4_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R5_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R6_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_R7_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_I0_TM1_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_I1_TM1_4: return (static_cast(busPtr))->CanShow(); break; + #endif + case I_HS_DOT_3: return (static_cast(busPtr))->CanShow(); break; + case I_SS_DOT_3: return (static_cast(busPtr))->CanShow(); break; + case I_HS_LPD_3: return (static_cast(busPtr))->CanShow(); break; + case I_SS_LPD_3: return (static_cast(busPtr))->CanShow(); break; + case I_HS_WS1_3: return (static_cast(busPtr))->CanShow(); break; + case I_SS_WS1_3: return (static_cast(busPtr))->CanShow(); break; + case I_HS_P98_3: return (static_cast(busPtr))->CanShow(); break; + case I_SS_P98_3: return (static_cast(busPtr))->CanShow(); break; + } + return true; }; + static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c) { + uint8_t r = c >> 16; + uint8_t g = c >> 8; + uint8_t b = c >> 0; + uint8_t w = c >> 24; + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_U1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_DM_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_BB_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_U0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_U1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_DM_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_BB_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_U0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_U1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_DM_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_BB_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_8266_U0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_U1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_DM_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_BB_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R2_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R3_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R4_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R5_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R6_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R7_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_I0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_I1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R2_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R3_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R4_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R5_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R6_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R7_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_I0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_I1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R2_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R3_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R4_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R5_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R6_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R7_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_I0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_I1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_32_R0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R2_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R3_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R4_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R5_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R6_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R7_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_I0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_I1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + #endif + case I_HS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_SS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_HS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_SS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_HS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_SS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_HS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_SS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + } + }; + static void setBrightness(void* busPtr, uint8_t busType, uint8_t b) { + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U1_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_DM_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_BB_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U0_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U1_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_DM_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_BB_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U0_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U1_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_DM_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_BB_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U0_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_U1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_DM_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_8266_BB_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R1_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R2_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R3_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R4_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R5_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R6_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R7_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I0_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I1_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R0_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R1_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R2_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R3_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R4_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R5_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R6_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R7_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I0_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I1_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R0_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R1_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R2_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R3_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R4_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R5_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R6_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R7_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I0_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I1_400_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R0_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R2_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R3_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R4_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R5_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R6_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_R7_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I0_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_32_I1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + #endif + case I_HS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_SS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_HS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_SS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_HS_WS1_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_SS_WS1_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_HS_P98_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_SS_P98_3: (static_cast(busPtr))->SetBrightness(b); break; + } + }; + static uint32_t getPixelColor() { + return 0; //TODO + } //gives back the internal type index (I_XX_XXX_X above) for the input static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { if (!IS_DIGITAL(busType)) return I_NONE; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 909f04f2..d9e5b8b6 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -149,27 +149,6 @@ void setCronixie(); void _overlayCronixie(); void _drawOverlayCronixie(); -//pin_manager.cpp -class PinManagerClass { - private: - #ifdef ESP8266 - uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits - #else - uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits - uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels - #endif - - public: - void deallocatePin(byte gpio); - bool allocatePin(byte gpio, bool output = true); - bool isPinAllocated(byte gpio); - bool isPinOk(byte gpio, bool output = true); - #ifdef ARDUINO_ARCH_ESP32 - byte allocateLedc(byte channels); - void deallocateLedc(byte pos, byte channels); - #endif -}; - //playlist.cpp void loadPlaylist(JsonObject playlistObject); void handlePlaylist(); diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index 919ece0e..d260ae95 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -1,9 +1,6 @@ +#include "pin_manager.h" #include "wled.h" -/* - * Registers pins so there is no attempt for two interfaces to use the same pin - */ - void PinManagerClass::deallocatePin(byte gpio) { if (!isPinOk(gpio, false)) return; @@ -89,4 +86,6 @@ void PinManagerClass::deallocateLedc(byte pos, byte channels) bitWrite(ledcAlloc[by], bi, false); } } -#endif \ No newline at end of file +#endif + +PinManagerClass pinManager = PinManagerClass(); \ No newline at end of file diff --git a/wled00/pin_manager.h b/wled00/pin_manager.h new file mode 100644 index 00000000..601c4be3 --- /dev/null +++ b/wled00/pin_manager.h @@ -0,0 +1,29 @@ +#ifndef WLED_PIN_MANAGER_H +#define WLED_PIN_MANAGER_H +/* + * Registers pins so there is no attempt for two interfaces to use the same pin + */ +#include + +class PinManagerClass { + private: + #ifdef ESP8266 + uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits + #else + uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits + uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels + #endif + + public: + void deallocatePin(byte gpio); + bool allocatePin(byte gpio, bool output = true); + bool isPinAllocated(byte gpio); + bool isPinOk(byte gpio, bool output = true); + #ifdef ARDUINO_ARCH_ESP32 + byte allocateLedc(byte channels); + void deallocateLedc(byte pos, byte channels); + #endif +}; + +extern PinManagerClass pinManager; +#endif \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index fa30a8c5..f2fb2ad8 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -115,6 +115,7 @@ #include "FX.h" #include "ir_codes.h" #include "const.h" +#include "pin_manager.h" #ifndef CLIENT_SSID #define CLIENT_SSID DEFAULT_CLIENT_SSID @@ -531,8 +532,6 @@ WLED_GLOBAL WS2812FX strip _INIT(WS2812FX()); // Usermod manager WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager()); -WLED_GLOBAL PinManagerClass pinManager _INIT(PinManagerClass()); - // Status LED #if STATUSLED && STATUSLED != LEDPIN WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0); From 0d63dad8c2e75e3fb0df4984e1ef645f0a6fcb10 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 16 Jan 2021 17:11:23 +0100 Subject: [PATCH 08/29] Working getPixelColor() --- wled00/bus_manager.h | 6 +- wled00/bus_wrapper.h | 243 +++++++++++++++++++++++++++++++------------ 2 files changed, 177 insertions(+), 72 deletions(-) diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 6d1f3635..9bafa2c2 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -92,13 +92,11 @@ class BusDigital : public Bus { } void setPixelColor(uint16_t pix, uint32_t c) { - //TODO color order - PolyBus::setPixelColor(_busPtr, _iType, pix, c); + PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder); } uint32_t getPixelColor(uint16_t pix) { - //TODO - return 0; + return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrder); } uint8_t getColorOrder() { diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 77ec01e3..bc11e7eb 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -414,81 +414,100 @@ class PolyBus { } return true; }; - static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c) { + static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co) { uint8_t r = c >> 16; uint8_t g = c >> 8; uint8_t b = c >> 0; uint8_t w = c >> 24; + RgbwColor col; + + //TODO make color order override possible on a per-strip basis + #ifdef COLOR_ORDER_OVERRIDE + if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; + #endif + + //reorder channels to selected order + switch (co) + { + case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default + case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811 + case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG + case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG + case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR + default: col.G = g; col.R = b; col.B = r; break; //5 = GBR + } + col.W = w; + switch (busType) { case I_NONE: break; #ifdef ESP8266 - case I_8266_U0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_U1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_DM_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_BB_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_U0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_U1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_DM_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_BB_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_U0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_U1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_DM_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_BB_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_8266_U0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_U1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_DM_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_8266_BB_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_8266_U0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_U1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_DM_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_BB_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_U0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_DM_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_BB_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_U1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_DM_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_BB_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_8266_U0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_DM_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_BB_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; #endif #ifdef ARDUINO_ARCH_ESP32 - case I_32_R0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R2_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R3_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R4_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R5_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R6_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R7_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_I0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_I1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R2_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R3_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R4_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R5_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R6_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R7_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_I0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_I1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R2_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R3_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R4_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R5_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R6_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R7_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_I0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_I1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_32_R0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R2_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R3_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R4_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R5_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R6_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_R7_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_I0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; - case I_32_I1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, RgbwColor(r,g,b,w)); break; + case I_32_R0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R2_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R3_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R4_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R5_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R6_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R7_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_I0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_I1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R2_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R3_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R4_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R5_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R6_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R7_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R2_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R3_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R4_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R5_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R6_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R7_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_I0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_I1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_32_R0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R2_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R3_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R4_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R5_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R6_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_R7_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; #endif - case I_HS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_SS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_HS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_SS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_HS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_SS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_HS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; - case I_SS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(r,g,b)); break; + case I_HS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_SS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_HS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_SS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_HS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_SS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_HS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_SS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; } }; static void setBrightness(void* busPtr, uint8_t busType, uint8_t b) { @@ -564,8 +583,96 @@ class PolyBus { case I_SS_P98_3: (static_cast(busPtr))->SetBrightness(b); break; } }; - static uint32_t getPixelColor() { - return 0; //TODO + static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) { + RgbwColor col; + col = (static_cast(busPtr))->GetPixelColor(pix); + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R1_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R2_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R3_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R4_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R5_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R6_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R7_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I0_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I1_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R0_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R1_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R2_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R3_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R4_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R5_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R6_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R7_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I0_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I1_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R0_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R2_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R3_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R4_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R5_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R6_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R7_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I0_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R2_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R3_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R4_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R5_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R6_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_R7_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #endif + case I_HS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_SS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_HS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_SS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_HS_WS1_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_SS_WS1_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_HS_P98_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_SS_P98_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + } + + #ifdef COLOR_ORDER_OVERRIDE + if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; + #endif + + switch (co) + { + // W G R B + case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default + case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 + case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG + case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG + case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR + case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR + } + return 0; } //gives back the internal type index (I_XX_XXX_X above) for the input static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { @@ -576,7 +683,7 @@ class PolyBus { if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true; #else if (pins[0] == P_32_HS_MOSI && pins[1] == P_32_HS_CLK) isHSPI = true; - if (pins[0] == P_32_VS_MOSI && pins[1] == P_V2_HS_CLK) isHSPI = true; + if (pins[0] == P_32_VS_MOSI && pins[1] == P_32_VS_CLK) isHSPI = true; #endif uint8_t t = I_NONE; switch (busType) { From 99dbd9e649650eb4af87ee66d376ccfd08b0f5b6 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 16 Jan 2021 19:53:08 +0100 Subject: [PATCH 09/29] Added bus cleanup --- wled00/bus_manager.h | 67 ++++++---- wled00/bus_wrapper.h | 289 ++++++++++++++++++++++++++++++++----------- 2 files changed, 265 insertions(+), 91 deletions(-) diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 9bafa2c2..9f333e97 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -12,8 +12,9 @@ //parent class of BusDigital and BusPwm class Bus { public: - Bus(uint8_t type) { + Bus(uint8_t type, uint16_t start) { _type = type; + _start = start; }; virtual void show() {} @@ -25,8 +26,10 @@ class Bus { virtual uint32_t getPixelColor(uint16_t pix) { return 0; }; + virtual void cleanup() {}; + virtual ~Bus() { //throw the bus under the bus - + cleanup(); } uint16_t getStart() { @@ -37,16 +40,16 @@ class Bus { _start = start; } - virtual uint8_t getColorOrder() { - return COL_ORDER_RGB; - } - virtual uint16_t getLength() { return 1; } virtual void setColorOrder() {} + virtual uint8_t getColorOrder() { + return COL_ORDER_RGB; + } + uint8_t getType() { return _type; } @@ -65,19 +68,24 @@ class Bus { class BusDigital : public Bus { public: - BusDigital(uint8_t type, uint8_t* pins, uint16_t len, uint8_t nr) : Bus(type) { + BusDigital(uint8_t type, uint8_t* pins, uint16_t start, uint16_t len, uint8_t colorOrder, uint8_t nr) : Bus(type, start) { if (!IS_DIGITAL(type) || !len) return; _pins[0] = pins[0]; - if (IS_2PIN(type)) _pins[1] = pins[1]; - //TODO allocate pins with pin manager + if (!pinManager.allocatePin(_pins[0])) return; + if (IS_2PIN(type)) { + _pins[1] = pins[1]; + if (!pinManager.allocatePin(_pins[1])) { + cleanup(); return; + } + } _len = len; _iType = PolyBus::getI(type, _pins, nr); if (_iType == I_NONE) return; - _busPtr = PolyBus::begin(_iType, _pins, _len); + _busPtr = PolyBus::create(_iType, _pins, _len); _valid = (_busPtr != nullptr); + _colorOrder = colorOrder; Serial.printf("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType); }; - //TODO clean up stuff (destructor) void show() { PolyBus::show(_busPtr, _iType); @@ -112,6 +120,15 @@ class BusDigital : public Bus { _colorOrder = colorOrder; } + void cleanup() { + PolyBus::cleanup(_busPtr, _iType); + _iType = I_NONE; + _valid = false; + _busPtr = nullptr; + pinManager.deallocatePin(_pins[0]); + pinManager.deallocatePin(_pins[1]); + } + private: uint8_t _colorOrder = COL_ORDER_GRB; uint8_t _pins[2] = {255, 255}; @@ -123,7 +140,7 @@ class BusDigital : public Bus { class BusPwm : public Bus { public: - BusPwm(uint8_t type, uint8_t* pins) : Bus(type) { + BusPwm(uint8_t type, uint8_t* pins, uint16_t start) : Bus(type, start) { if (!IS_PWM(type)) return; uint8_t numPins = NUM_PWM_PINS(type); @@ -149,7 +166,6 @@ class BusPwm : public Bus { ledcAttachPin(_pins[i], _ledcStart + i); #endif } - _valid = true; }; @@ -191,12 +207,12 @@ class BusPwm : public Bus { } } - ~BusPwm() { + void cleanup() { deallocatePins(); - }; + } private: - uint8_t _pins[5]; + uint8_t _pins[5] = {255, 255, 255, 255, 255}; uint8_t _data[5] = {255, 255, 255, 255, 255}; #ifdef ARDUINO_ARCH_ESP32 uint8_t _ledcStart = 255; @@ -209,7 +225,7 @@ class BusPwm : public Bus { #ifdef ESP8266 digitalWrite(_pins[i], LOW); //turn off PWM interrupt #else - if (_ledcStart < 16) ledcDetachPin(_pins[i], _ledcStart + i); + if (_ledcStart < 16) ledcDetachPin(_pins[i]); #endif pinManager.deallocatePin(_pins[i]); } @@ -225,12 +241,12 @@ class BusManager { }; - int add(uint8_t busType, uint8_t* pins, uint16_t len = 1) { + int add(uint8_t busType, uint8_t* pins, uint16_t start, uint16_t len = 1, uint8_t colorOrder = COL_ORDER_GRB) { if (numBusses >= WLED_MAX_BUSSES) return -1; if (IS_DIGITAL(busType)) { - busses[numBusses] = new BusDigital(busType, pins, len, numBusses); + busses[numBusses] = new BusDigital(busType, pins, start, len, colorOrder, numBusses); } else { - busses[numBusses] = new BusPwm(busType, pins); + busses[numBusses] = new BusPwm(busType, pins, start); } numBusses++; return numBusses -1; @@ -280,8 +296,17 @@ class BusManager { return true; } + Bus* getBus(uint8_t busNr) { + if (busNr >= numBusses) return nullptr; + return busses[busNr]; + } + + uint8_t getNumBusses() { + return numBusses; + } + private: uint8_t numBusses = 0; Bus* busses[WLED_MAX_BUSSES]; }; -#endif +#endif \ No newline at end of file diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index bc11e7eb..1393dd71 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -191,80 +191,154 @@ //handles pointer type conversion for all possible bus types class PolyBus { public: - static void* begin(uint8_t busType, uint8_t* pins, uint16_t len) { - void* busPtr; - //delete busPtr; //TODO this needs type handling or destructor isn't called + static void begin(void* busPtr, uint8_t busType) { switch (busType) { - case I_NONE: busPtr = new B_8266_U0_NEO_3(len, pins[0]); break; + case I_NONE: break; #ifdef ESP8266 - case I_8266_U0_NEO_3: busPtr = new B_8266_U0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U1_NEO_3: busPtr = new B_8266_U1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_DM_NEO_3: busPtr = new B_8266_DM_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_BB_NEO_3: busPtr = new B_8266_BB_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U0_NEO_4: busPtr = new B_8266_U0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U1_NEO_4: busPtr = new B_8266_U1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_DM_NEO_4: busPtr = new B_8266_DM_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_BB_NEO_4: busPtr = new B_8266_BB_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U0_400_3: busPtr = new B_8266_U0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U1_400_3: busPtr = new B_8266_U1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_DM_400_3: busPtr = new B_8266_DM_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_BB_400_3: busPtr = new B_8266_BB_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U0_TM1_4: busPtr = new B_8266_U0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_8266_U0_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U1_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_8266_DM_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_8266_BB_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U0_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_8266_U1_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_8266_DM_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_8266_BB_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_8266_U0_400_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U1_400_3: (static_cast(busPtr))->Begin(); break; + case I_8266_DM_400_3: (static_cast(busPtr))->Begin(); break; + case I_8266_BB_400_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U0_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_8266_U1_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_8266_DM_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_8266_BB_TM1_4: (static_cast(busPtr))->Begin(); break; #endif #ifdef ARDUINO_ARCH_ESP32 - case I_32_R0_NEO_3: busPtr = new B_32_R0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R1_NEO_3: busPtr = new B_32_R1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R2_NEO_3: busPtr = new B_32_R2_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R3_NEO_3: busPtr = new B_32_R3_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R4_NEO_3: busPtr = new B_32_R4_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R5_NEO_3: busPtr = new B_32_R5_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R6_NEO_3: busPtr = new B_32_R6_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R7_NEO_3: busPtr = new B_32_R7_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R0_NEO_4: busPtr = new B_32_R0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R1_NEO_4: busPtr = new B_32_R1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R2_NEO_4: busPtr = new B_32_R2_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R3_NEO_4: busPtr = new B_32_R3_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R4_NEO_4: busPtr = new B_32_R4_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R5_NEO_4: busPtr = new B_32_R5_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R6_NEO_4: busPtr = new B_32_R6_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R7_NEO_4: busPtr = new B_32_R7_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R0_400_3: busPtr = new B_32_R0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R1_400_3: busPtr = new B_32_R1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R2_400_3: busPtr = new B_32_R2_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R3_400_3: busPtr = new B_32_R3_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R4_400_3: busPtr = new B_32_R4_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R5_400_3: busPtr = new B_32_R5_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R6_400_3: busPtr = new B_32_R6_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R7_400_3: busPtr = new B_32_R7_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R0_TM1_4: busPtr = new B_32_R0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R1_TM1_4: busPtr = new B_32_R1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R2_TM1_4: busPtr = new B_32_R2_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R3_TM1_4: busPtr = new B_32_R3_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R4_TM1_4: busPtr = new B_32_R4_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R5_TM1_4: busPtr = new B_32_R5_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R6_TM1_4: busPtr = new B_32_R6_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_R7_TM1_4: busPtr = new B_32_R7_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; - case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); (static_cast(busPtr))->Begin(); break; + case I_32_R0_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R1_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R2_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R3_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R4_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R5_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R6_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R7_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_I0_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_I1_NEO_3: (static_cast(busPtr))->Begin(); break; + case I_32_R0_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R1_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R2_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R3_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R4_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R5_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R6_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R7_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_I0_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_I1_NEO_4: (static_cast(busPtr))->Begin(); break; + case I_32_R0_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R1_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R2_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R3_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R4_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R5_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R6_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R7_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_I0_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_I1_400_3: (static_cast(busPtr))->Begin(); break; + case I_32_R0_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R1_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R2_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R3_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R4_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R5_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R6_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_R7_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_I0_TM1_4: (static_cast(busPtr))->Begin(); break; + case I_32_I1_TM1_4: (static_cast(busPtr))->Begin(); break; #endif - case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_SS_WS1_3: busPtr = new B_SS_WS1_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; - case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[0], pins[1]); (static_cast(busPtr))->Begin(); break; + case I_HS_DOT_3: (static_cast(busPtr))->Begin(); break; + case I_SS_DOT_3: (static_cast(busPtr))->Begin(); break; + case I_HS_LPD_3: (static_cast(busPtr))->Begin(); break; + case I_SS_LPD_3: (static_cast(busPtr))->Begin(); break; + case I_HS_WS1_3: (static_cast(busPtr))->Begin(); break; + case I_SS_WS1_3: (static_cast(busPtr))->Begin(); break; + case I_HS_P98_3: (static_cast(busPtr))->Begin(); break; + case I_SS_P98_3: (static_cast(busPtr))->Begin(); break; } + }; + static void* create(uint8_t busType, uint8_t* pins, uint16_t len) { + void* busPtr = nullptr; + //delete busPtr; //TODO this needs type handling or destructor isn't called + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: busPtr = new B_8266_U0_NEO_3(len, pins[0]); break; + case I_8266_U1_NEO_3: busPtr = new B_8266_U1_NEO_3(len, pins[0]); break; + case I_8266_DM_NEO_3: busPtr = new B_8266_DM_NEO_3(len, pins[0]); break; + case I_8266_BB_NEO_3: busPtr = new B_8266_BB_NEO_3(len, pins[0]); break; + case I_8266_U0_NEO_4: busPtr = new B_8266_U0_NEO_4(len, pins[0]); break; + case I_8266_U1_NEO_4: busPtr = new B_8266_U1_NEO_4(len, pins[0]); break; + case I_8266_DM_NEO_4: busPtr = new B_8266_DM_NEO_4(len, pins[0]); break; + case I_8266_BB_NEO_4: busPtr = new B_8266_BB_NEO_4(len, pins[0]); break; + case I_8266_U0_400_3: busPtr = new B_8266_U0_400_3(len, pins[0]); break; + case I_8266_U1_400_3: busPtr = new B_8266_U1_400_3(len, pins[0]); break; + case I_8266_DM_400_3: busPtr = new B_8266_DM_400_3(len, pins[0]); break; + case I_8266_BB_400_3: busPtr = new B_8266_BB_400_3(len, pins[0]); break; + case I_8266_U0_TM1_4: busPtr = new B_8266_U0_TM1_4(len, pins[0]); break; + case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); break; + case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); break; + case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: busPtr = new B_32_R0_NEO_3(len, pins[0]); break; + case I_32_R1_NEO_3: busPtr = new B_32_R1_NEO_3(len, pins[0]); break; + case I_32_R2_NEO_3: busPtr = new B_32_R2_NEO_3(len, pins[0]); break; + case I_32_R3_NEO_3: busPtr = new B_32_R3_NEO_3(len, pins[0]); break; + case I_32_R4_NEO_3: busPtr = new B_32_R4_NEO_3(len, pins[0]); break; + case I_32_R5_NEO_3: busPtr = new B_32_R5_NEO_3(len, pins[0]); break; + case I_32_R6_NEO_3: busPtr = new B_32_R6_NEO_3(len, pins[0]); break; + case I_32_R7_NEO_3: busPtr = new B_32_R7_NEO_3(len, pins[0]); break; + case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); break; + case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); break; + case I_32_R0_NEO_4: busPtr = new B_32_R0_NEO_4(len, pins[0]); break; + case I_32_R1_NEO_4: busPtr = new B_32_R1_NEO_4(len, pins[0]); break; + case I_32_R2_NEO_4: busPtr = new B_32_R2_NEO_4(len, pins[0]); break; + case I_32_R3_NEO_4: busPtr = new B_32_R3_NEO_4(len, pins[0]); break; + case I_32_R4_NEO_4: busPtr = new B_32_R4_NEO_4(len, pins[0]); break; + case I_32_R5_NEO_4: busPtr = new B_32_R5_NEO_4(len, pins[0]); break; + case I_32_R6_NEO_4: busPtr = new B_32_R6_NEO_4(len, pins[0]); break; + case I_32_R7_NEO_4: busPtr = new B_32_R7_NEO_4(len, pins[0]); break; + case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break; + case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); break; + case I_32_R0_400_3: busPtr = new B_32_R0_400_3(len, pins[0]); break; + case I_32_R1_400_3: busPtr = new B_32_R1_400_3(len, pins[0]); break; + case I_32_R2_400_3: busPtr = new B_32_R2_400_3(len, pins[0]); break; + case I_32_R3_400_3: busPtr = new B_32_R3_400_3(len, pins[0]); break; + case I_32_R4_400_3: busPtr = new B_32_R4_400_3(len, pins[0]); break; + case I_32_R5_400_3: busPtr = new B_32_R5_400_3(len, pins[0]); break; + case I_32_R6_400_3: busPtr = new B_32_R6_400_3(len, pins[0]); break; + case I_32_R7_400_3: busPtr = new B_32_R7_400_3(len, pins[0]); break; + case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break; + case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break; + case I_32_R0_TM1_4: busPtr = new B_32_R0_TM1_4(len, pins[0]); break; + case I_32_R1_TM1_4: busPtr = new B_32_R1_TM1_4(len, pins[0]); break; + case I_32_R2_TM1_4: busPtr = new B_32_R2_TM1_4(len, pins[0]); break; + case I_32_R3_TM1_4: busPtr = new B_32_R3_TM1_4(len, pins[0]); break; + case I_32_R4_TM1_4: busPtr = new B_32_R4_TM1_4(len, pins[0]); break; + case I_32_R5_TM1_4: busPtr = new B_32_R5_TM1_4(len, pins[0]); break; + case I_32_R6_TM1_4: busPtr = new B_32_R6_TM1_4(len, pins[0]); break; + case I_32_R7_TM1_4: busPtr = new B_32_R7_TM1_4(len, pins[0]); break; + case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); break; + case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); break; + #endif + case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[0], pins[1]); break; + case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[0], pins[1]); break; + case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[0], pins[1]); break; + case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[0], pins[1]); break; + case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[0], pins[1]); break; + case I_SS_WS1_3: busPtr = new B_SS_WS1_3(len, pins[0], pins[1]); break; + case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[0], pins[1]); break; + case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[0], pins[1]); break; + } + begin(busPtr, busType); return busPtr; }; static void show(void* busPtr, uint8_t busType) { @@ -584,8 +658,7 @@ class PolyBus { } }; static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) { - RgbwColor col; - col = (static_cast(busPtr))->GetPixelColor(pix); + RgbwColor col; switch (busType) { case I_NONE: break; #ifdef ESP8266 @@ -674,6 +747,82 @@ class PolyBus { } return 0; } + + static void cleanup(void* busPtr, uint8_t busType) { + if (busPtr == nullptr) return; + switch (busType) { + case I_NONE: break; + #ifdef ESP8266 + case I_8266_U0_NEO_3: delete (static_cast(busPtr)); break; + case I_8266_U1_NEO_3: delete (static_cast(busPtr)); break; + case I_8266_DM_NEO_3: delete (static_cast(busPtr)); break; + case I_8266_BB_NEO_3: delete (static_cast(busPtr)); break; + case I_8266_U0_NEO_4: delete (static_cast(busPtr)); break; + case I_8266_U1_NEO_4: delete (static_cast(busPtr)); break; + case I_8266_DM_NEO_4: delete (static_cast(busPtr)); break; + case I_8266_BB_NEO_4: delete (static_cast(busPtr)); break; + case I_8266_U0_400_3: delete (static_cast(busPtr)); break; + case I_8266_U1_400_3: delete (static_cast(busPtr)); break; + case I_8266_DM_400_3: delete (static_cast(busPtr)); break; + case I_8266_BB_400_3: delete (static_cast(busPtr)); break; + case I_8266_U0_TM1_4: delete (static_cast(busPtr)); break; + case I_8266_U1_TM1_4: delete (static_cast(busPtr)); break; + case I_8266_DM_TM1_4: delete (static_cast(busPtr)); break; + case I_8266_BB_TM1_4: delete (static_cast(busPtr)); break; + #endif + #ifdef ARDUINO_ARCH_ESP32 + case I_32_R0_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R1_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R2_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R3_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R4_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R5_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R6_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R7_NEO_3: delete (static_cast(busPtr)); break; + case I_32_I0_NEO_3: delete (static_cast(busPtr)); break; + case I_32_I1_NEO_3: delete (static_cast(busPtr)); break; + case I_32_R0_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R1_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R2_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R3_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R4_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R5_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R6_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R7_NEO_4: delete (static_cast(busPtr)); break; + case I_32_I0_NEO_4: delete (static_cast(busPtr)); break; + case I_32_I1_NEO_4: delete (static_cast(busPtr)); break; + case I_32_R0_400_3: delete (static_cast(busPtr)); break; + case I_32_R1_400_3: delete (static_cast(busPtr)); break; + case I_32_R2_400_3: delete (static_cast(busPtr)); break; + case I_32_R3_400_3: delete (static_cast(busPtr)); break; + case I_32_R4_400_3: delete (static_cast(busPtr)); break; + case I_32_R5_400_3: delete (static_cast(busPtr)); break; + case I_32_R6_400_3: delete (static_cast(busPtr)); break; + case I_32_R7_400_3: delete (static_cast(busPtr)); break; + case I_32_I0_400_3: delete (static_cast(busPtr)); break; + case I_32_I1_400_3: delete (static_cast(busPtr)); break; + case I_32_R0_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R1_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R2_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R3_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R4_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R5_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R6_TM1_4: delete (static_cast(busPtr)); break; + case I_32_R7_TM1_4: delete (static_cast(busPtr)); break; + case I_32_I0_TM1_4: delete (static_cast(busPtr)); break; + case I_32_I1_TM1_4: delete (static_cast(busPtr)); break; + #endif + case I_HS_DOT_3: delete (static_cast(busPtr)); break; + case I_SS_DOT_3: delete (static_cast(busPtr)); break; + case I_HS_LPD_3: delete (static_cast(busPtr)); break; + case I_SS_LPD_3: delete (static_cast(busPtr)); break; + case I_HS_WS1_3: delete (static_cast(busPtr)); break; + case I_SS_WS1_3: delete (static_cast(busPtr)); break; + case I_HS_P98_3: delete (static_cast(busPtr)); break; + case I_SS_P98_3: delete (static_cast(busPtr)); break; + } + } + //gives back the internal type index (I_XX_XXX_X above) for the input static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { if (!IS_DIGITAL(busType)) return I_NONE; From d02bf371678d67ccf651172f208f1ab46b990eae Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 16 Jan 2021 21:40:04 +0100 Subject: [PATCH 10/29] Fix a few warnings --- wled00/FX.h | 1 - wled00/FX_fcn.cpp | 14 +------------- wled00/bus_manager.h | 9 ++++++++- wled00/bus_wrapper.h | 3 +-- wled00/json.cpp | 2 +- wled00/mqtt.cpp | 2 +- 6 files changed, 12 insertions(+), 19 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index bfe0f6bc..cdab2336 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -841,7 +841,6 @@ class WS2812FX { void handle_palette(void); bool - shouldStartBus = false, _useRgbw = false, _skipFirstMode, _triggered; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 0fbd05d4..18399869 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -62,7 +62,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) } uint8_t pins[] = {2}; - busses->add(supportWhite? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, countPixels); + busses->add(supportWhite? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, countPixels, COL_ORDER_GRB); _segments[0].start = 0; _segments[0].stop = _length; @@ -418,18 +418,6 @@ void WS2812FX::setBrightness(uint8_t b) { { _segments[i].setOption(SEG_OPTION_FREEZE, false); } - #if LEDPIN == LED_BUILTIN - shouldStartBus = true; - #endif - } else { - #if LEDPIN == LED_BUILTIN - if (shouldStartBus) { - shouldStartBus = false; - const uint8_t ty = _useRgbw ? 2 : 1; - //TODO add re-init method for any bus type that uses GPIO2 on ESP8266 here - //bus->Begin((NeoPixelType)ty, _lengthRaw); - } - #endif } if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon } diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 9f333e97..f61143c9 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -22,7 +22,7 @@ class Bus { virtual void setPixelColor(uint16_t pix, uint32_t c) {}; - virtual void setBrightness(uint8_t b) { _bri = b; }; + virtual void setBrightness(uint8_t b) {}; virtual uint32_t getPixelColor(uint16_t pix) { return 0; }; @@ -96,6 +96,9 @@ class BusDigital : public Bus { } void setBrightness(uint8_t b) { + //Fix for turning off onboard LED breaking bus + if (_bri == 0 && b > 0 && (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN)) PolyBus::begin(_busPtr, _iType); + _bri = b; PolyBus::setBrightness(_busPtr, _iType, b); } @@ -207,6 +210,10 @@ class BusPwm : public Bus { } } + void setBrightness(uint8_t b) { + _bri = b; + } + void cleanup() { deallocatePins(); } diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 1393dd71..d9f0244f 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -266,7 +266,6 @@ class PolyBus { }; static void* create(uint8_t busType, uint8_t* pins, uint16_t len) { void* busPtr = nullptr; - //delete busPtr; //TODO this needs type handling or destructor isn't called switch (busType) { case I_NONE: break; #ifdef ESP8266 @@ -658,7 +657,7 @@ class PolyBus { } }; static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) { - RgbwColor col; + RgbwColor col(0,0,0,0); switch (busType) { case I_NONE: break; #ifdef ESP8266 diff --git a/wled00/json.cpp b/wled00/json.cpp index fe79eacb..ded88895 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -587,7 +587,7 @@ void serveJson(AsyncWebServerRequest* request) bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) { - AsyncWebSocketClient * wsc; + AsyncWebSocketClient * wsc = nullptr; if (!request) { //not HTTP, use Websockets #ifdef WLED_ENABLE_WEBSOCKETS wsc = ws.client(wsClient); diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index d54f7997..9aa9bf96 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -110,7 +110,7 @@ void publishMqtt() char s[10]; char subuf[38]; - sprintf(s, "%ld", bri); + sprintf(s, "%u", bri); strcpy(subuf, mqttDeviceTopic); strcat(subuf, "/g"); mqtt->publish(subuf, 0, true, s); From bb8d5ac13ffd74119e96643e5595d37ba9d6673f Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 17 Jan 2021 00:20:31 +0100 Subject: [PATCH 11/29] Dynamic allocation for bus manager. --- wled00/FX.h | 38 ++----- wled00/FX_fcn.cpp | 0 wled00/button.cpp | 53 +++++----- wled00/cfg.cpp | 162 +++++++++++++++++------------ wled00/data/settings_leds.htm | 188 +++++++++++++++++++++++++++++----- wled00/html_settings.h | 80 +++++++++------ wled00/ir.cpp | 2 +- wled00/set.cpp | 129 ++++++++++++++++++++--- wled00/wled.cpp | 61 +++++------ wled00/wled.h | 46 +++++++-- wled00/xml.cpp | 69 +++++++++++-- 11 files changed, 585 insertions(+), 243 deletions(-) mode change 100644 => 100755 wled00/FX.h mode change 100644 => 100755 wled00/FX_fcn.cpp mode change 100644 => 100755 wled00/data/settings_leds.htm mode change 100644 => 100755 wled00/wled.cpp mode change 100644 => 100755 wled00/xml.cpp diff --git a/wled00/FX.h b/wled00/FX.h old mode 100644 new mode 100755 index cdab2336..2a3c1869 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -27,36 +27,6 @@ #ifndef WS2812FX_h #define WS2812FX_h -//TEMPORARY DEFINES FOR TESTING - MAKE THESE RUNTIME CONFIGURABLE TOO! -#ifndef LEDPIN -#define LEDPIN 2 -#endif - -#ifndef BTNPIN -#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#endif - -#ifndef TOUCHPIN -//#define TOUCHPIN T0 //touch pin. Behaves the same as button. ESP32 only. -#endif - -#ifndef IRPIN -#define IRPIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#endif - -#ifndef RLYPIN -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... -#endif - -#ifndef AUXPIN -#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) -#endif - -#ifndef RLYMDE -#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on -#endif -//END OF TEMP DEFINES - #ifdef ESP32_MULTISTRIP #include "../usermods/esp32_multistrip/NpbWrapper.h" #else @@ -659,6 +629,8 @@ class WS2812FX { paletteFade = 0, paletteBlend = 0, milliampsPerLed = 55, +// getStripType(uint8_t strip=0), +// setStripType(uint8_t type, uint8_t strip=0), getBrightness(void), getMode(void), getSpeed(void), @@ -673,11 +645,17 @@ class WS2812FX { get_random_wheel_index(uint8_t); int8_t +// setStripPin(uint8_t strip, int8_t pin), +// getStripPin(uint8_t strip=0), +// setStripPinClk(uint8_t strip, int8_t pin), +// getStripPinClk(uint8_t strip=0), tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec); uint16_t ablMilliampsMax, currentMilliamps, +// setStripLen(uint8_t strip, uint16_t len), +// getStripLen(uint8_t strip=0), triwave16(uint16_t); uint32_t diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp old mode 100644 new mode 100755 diff --git a/wled00/button.cpp b/wled00/button.cpp index 7adbf68b..d774137e 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -17,9 +17,7 @@ void shortPressAction() bool isButtonPressed() { - #if defined(BTNPIN) && BTNPIN > -1 - if (digitalRead(BTNPIN) == LOW) return true; - #endif + if (btnPin>=0 && digitalRead(btnPin) == LOW) return true; #ifdef TOUCHPIN if (touchRead(TOUCHPIN) <= TOUCH_THRESHOLD) return true; #endif @@ -29,8 +27,7 @@ bool isButtonPressed() void handleButton() { -#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN) - if (!buttonEnabled) return; + if (btnPin<0 || !buttonEnabled) return; if (isButtonPressed()) //pressed { @@ -75,7 +72,6 @@ void handleButton() buttonWaitTime = 0; shortPressAction(); } -#endif } void handleIO() @@ -88,37 +84,43 @@ void handleIO() lastOnTime = millis(); if (offMode) { - #if RLYPIN >= 0 - digitalWrite(RLYPIN, RLYMDE); - #endif + if (rlyPin>=0) { + pinMode(rlyPin, OUTPUT); + digitalWrite(rlyPin, rlyMde); + } offMode = false; } } else if (millis() - lastOnTime > 600) { - if (!offMode) { - #if LEDPIN == LED_BUILTIN - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, HIGH); + if (!offMode) { + #ifdef ESP8266 + for (uint8_t s=0; s= 0 - digitalWrite(RLYPIN, !RLYMDE); - #endif - } + if (rlyPin>=0) { + pinMode(rlyPin, OUTPUT); + digitalWrite(rlyPin, !rlyMde); + } + } offMode = true; } - #if AUXPIN >= 0 //output - if (auxActive || auxActiveBefore) + if (auxPin>=1 && (auxActive || auxActiveBefore)) { if (!auxActiveBefore) { auxActiveBefore = true; switch (auxTriggeredState) { - case 0: pinMode(AUXPIN, INPUT); break; - case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break; - case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break; + case 0: pinMode(auxPin, INPUT); break; + case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; + case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; } auxStartTime = millis(); } @@ -128,11 +130,10 @@ void handleIO() auxActiveBefore = false; switch (auxDefaultState) { - case 0: pinMode(AUXPIN, INPUT); break; - case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break; - case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break; + case 0: pinMode(auxPin, INPUT); break; + case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; + case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; } } } - #endif } diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 43d2615e..940dde7b 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -89,31 +89,59 @@ void deserializeConfig() { JsonObject hw = doc[F("hw")]; + // initialize LED pins and lengths prior to other HW JsonObject hw_led = hw[F("led")]; - CJSON(ledCount, hw_led[F("total")]); - if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; +// CJSON(ledCount, hw_led[F("total")]); + ledCount = 0; CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]); CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); CJSON(strip.reverseMode, hw_led[F("rev")]); CJSON(strip.rgbwMode, hw_led[F("rgbwm")]); - JsonObject hw_led_ins_0 = hw_led[F("ins")][0]; - //bool hw_led_ins_0_en = hw_led_ins_0[F("en")]; // true - //int hw_led_ins_0_start = hw_led_ins_0[F("start")]; // 0 - //int hw_led_ins_0_len = hw_led_ins_0[F("len")]; // 1200 - - //int hw_led_ins_0_pin_0 = hw_led_ins_0[F("pin")][0]; // 2 - - strip.setColorOrder(hw_led_ins_0[F("order")]); - //bool hw_led_ins_0_rev = hw_led_ins_0[F("rev")]; // false - skipFirstLed = hw_led_ins_0[F("skip")]; // 0 - useRGBW = (hw_led_ins_0[F("type")] == TYPE_SK6812_RGBW); + JsonVariant strVar = hw_led["ins"]; + if (strVar.is()) { + // some safety measures here? + } else { + JsonArray elms = strVar.as(); + uint8_t s=0; + for ( JsonObject elm : elms ) { + if (s>=WLED_MAX_BUSSES) break; + int8_t pins[2] = {-1,-1}; + pins[0] = elm[F("pin")][0]; + if (pins[0] >= 0 && pinManager.allocatePin(pins[0])) { + if (elm[F("pin")].size()==2) { + pins[1] = elm[F("pin")][1]; + if (pins[1] >= 0) + if (!pinManager.allocatePin(pins[1])) { + pinManager.deallocatePin(pins[0]); + break; // pin not ok + } + } + } else { + break; // pin not ok + } + uint16_t length = elm[F("len")]); + if (length==0) break; + uint8_t colorOrder = (int)elm[F("order")]; + uint8_t skipFirstLed = elm[F("skip")]; // 0 + uint8_t ledType = elm[F("type")]; + uint8_t useRGBW = ((ledType == TYPE_SK6812_RGBW) || ledType == TYPE_TM1814); + ledCount += length; + busses->add(ledType? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, ledCount, colorOrder); + } + } + if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0]; - buttonEnabled = hw_btn_ins_0[F("en")] | buttonEnabled; - - //int hw_btn_ins_0_pin_0 = hw_btn_ins_0[F("pin")][0]; // 0 + CJSON(buttonEnabled, hw_btn_ins_0[F("type")]); + int hw_btn_pin = hw_btn_ins_0[F("pin")][0]; + if (pinManager.allocatePin(hw_btn_pin,false)) { + btnPin = hw_btn_pin; + pinMode(btnPin, INPUT_PULLUP); + } else { + btnPin = -1; + } JsonArray hw_btn_ins_0_macros = hw_btn_ins_0[F("macros")]; CJSON(macroButton, hw_btn_ins_0_macros[0]); @@ -122,11 +150,24 @@ void deserializeConfig() { //int hw_btn_ins_0_type = hw_btn_ins_0[F("type")]; // 0 - //int hw_ir_pin = hw[F("ir")][F("pin")]; // 4 - CJSON(irEnabled, hw[F("ir")][F("type")]); // 0 + #ifndef WLED_DISABLE_INFRARED + int hw_ir_pin = hw[F("ir")][F("pin")]; // 4 + if (pinManager.allocatePin(hw_ir_pin,false)) { + irPin = hw_ir_pin; + } else { + irPin = -1; + } + #endif + CJSON(irEnabled, hw[F("ir")][F("type")]); - //int hw_relay_pin = hw[F("relay")][F("pin")]; // 12 - //bool hw_relay_rev = hw[F("relay")][F("rev")]; // false + int hw_relay_pin = hw[F("relay")][F("pin")]; + if (pinManager.allocatePin(hw_relay_pin,true)) { + rlyPin = hw_relay_pin; + pinMode(rlyPin, OUTPUT); + } else { + rlyPin = -1; + } + CJSON(rlyMde, hw[F("relay")][F("rev")]); //int hw_status_pin = hw[F("status")][F("pin")]; // -1 @@ -404,70 +445,57 @@ void serializeConfig() { JsonArray hw_led_ins = hw_led.createNestedArray("ins"); - JsonObject hw_led_ins_0 = hw_led_ins.createNestedObject(); - hw_led_ins_0[F("en")] = true; - hw_led_ins_0[F("start")] = 0; - hw_led_ins_0[F("len")] = ledCount; - JsonArray hw_led_ins_0_pin = hw_led_ins_0.createNestedArray("pin"); - hw_led_ins_0_pin.add(LEDPIN); - #ifdef DATAPIN - hw_led_ins_0_pin.add(DATAPIN); - #endif - hw_led_ins_0[F("order")] = strip.getColorOrder(); - hw_led_ins_0[F("rev")] = false; - hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0; - - //this is very crude and temporary - byte ledType = TYPE_WS2812_RGB; - if (useRGBW) ledType = TYPE_SK6812_RGBW; - #ifdef USE_WS2801 - ledType = TYPE_WS2801; - #endif - #ifdef USE_APA102 - ledType = TYPE_APA102; - #endif - #ifdef USE_LPD8806 - ledType = TYPE_LPD8806; - #endif - #ifdef USE_P9813 - ledType = TYPE_P9813; - #endif - #ifdef USE_TM1814 - ledType = TYPE_TM1814; - #endif - - hw_led_ins_0[F("type")] = ledType; + uint16_t start = 0; + for (uint8_t s=0; sgetNumBusses(); s++) { + Bus *bus = busses->getBus(s); + if (!bus || bus->getLength()==0) break; + JsonObject hw_led_ins_0 = hw_led_ins.createNestedObject(); + hw_led_ins_0[F("en")] = true; + hw_led_ins_0[F("start")] = start; + start += bus->getLength(); + hw_led_ins_0[F("len")] = bus->getLength(); + JsonArray hw_led_ins_0_pin = hw_led_ins_0.createNestedArray("pin"); + hw_led_ins_0_pin.add(bus->getBusPins(s)[0]); + if (bus->getBusPins(s)[1]>=0) hw_led_ins_0_pin.add(bus->getBusPins(s)[1]); + hw_led_ins_0[F("order")] = bus->getColorOrder(); + hw_led_ins_0[F("rev")] = false; + hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0; + hw_led_ins_0[F("type")] = bus->getType(); + } JsonObject hw_btn = hw.createNestedObject("btn"); JsonArray hw_btn_ins = hw_btn.createNestedArray("ins"); - #if defined(BTNPIN) && BTNPIN > -1 + // button BTNPIN JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject(); hw_btn_ins_0[F("type")] = (buttonEnabled) ? BTN_TYPE_PUSH : BTN_TYPE_NONE; JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin"); - hw_btn_ins_0_pin.add(BTNPIN); + hw_btn_ins_0_pin.add(btnPin); JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros"); hw_btn_ins_0_macros.add(macroButton); hw_btn_ins_0_macros.add(macroLongPress); hw_btn_ins_0_macros.add(macroDoublePress); + + #ifndef WLED_DISABLE_INFRARED + if (irPin>=0) { + JsonObject hw_ir = hw.createNestedObject("ir"); + hw_ir[F("pin")] = irPin; + hw_ir[F("type")] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled ) + } #endif - #if defined(IRPIN) && IRPIN > -1 - JsonObject hw_ir = hw.createNestedObject("ir"); - hw_ir[F("pin")] = IRPIN; - hw_ir[F("type")] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled ) - #endif - - #if defined(RLYPIN) && RLYPIN > -1 JsonObject hw_relay = hw.createNestedObject("relay"); - hw_relay[F("pin")] = RLYPIN; - hw_relay[F("rev")] = (RLYMDE) ? false : true; - JsonObject hw_status = hw.createNestedObject("status"); - hw_status[F("pin")] = -1; - #endif + hw_relay[F("pin")] = rlyPin; + hw_relay[F("rev")] = rlyMde; + + //JsonObject hw_status = hw.createNestedObject("status"); + //hw_status[F("pin")] = -1; + + JsonObject hw_aux = hw.createNestedObject("aux"); + hw_aux[F("pin")] = auxPin; JsonObject light = doc.createNestedObject("light"); light[F("scale-bri")] = briMultiplier; diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm old mode 100644 new mode 100755 index 6a0dee0a..2b2625f0 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -52,13 +52,53 @@ myC[i].style.display = (d.getElementById('rgbw').checked) ? 'inline':'none'; } - d.getElementById('ledwarning').style.display = (d.Sf.LC.value > 1000) ? 'inline':'none'; d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none'; - if (d.Sf.LA.value == 255) laprev = 12; - else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value; - - var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2; + if (d.Sf.LA.value == 255) laprev = 12; + else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value; + + var s = d.getElementsByTagName("select"); + for (i=0; i49 && s[i].value!=54) // TYPE_xxxx values from const.h + { + o[n].style = "display:inline;"; + LK.required = true; + } else { + o[n].style = "display:none;"; + LK.required = false; + LK.value=""; + } + } + } + + var LCs = d.getElementsByTagName("input"); + var sLC = 0; + for (i=0; ie==parseInt(LCs[i].value,10))) {alert("Usermod pin clash!");LCs[i].value="";LCs[i].focus();continue;} + for (j=0; j 1000) ? 'inline':'none'; + + //var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2; + var val = Math.ceil((100 + sLC * laprev)/500)/2; val = (val > 5) ? Math.ceil(val) : val; var s = ""; var is12V = (d.Sf.LAsel.value == 30); @@ -79,11 +119,91 @@ s2 += "A is enough)
"; d.getElementById('psu').innerHTML = s; d.getElementById('psu2').innerHTML = isWS2815 ? "" : s2; - } + } + function addLEDs(n) + { + if (n>1) {d.maxST=n; d.getElementById("+").style="display:inline;"; return;} + + var o = d.getElementsByName("iST"); + var i = o.length; + + if ((n==1 && i>=d.maxST) || (n==-1 && i<=1)) return; + + var f = d.getElementById("mLC"); + if (n==1) { + var s, t = d.createElement("div"); + t.setAttribute("name","iST"); + + t.appendChild(d.createTextNode((i+1)+": ")); + + s = d.createElement("select"); + s.setAttribute("name","LTsel"+i); + s.onchange = function(){UI()} + o = d.createElement("option"); o.text = "WS281x"; o.value = "22"; s.add(o); + o = d.createElement("option"); o.text = "SK6812"; o.value = "30"; s.add(o); + o = d.createElement("option"); o.text = "WS2801"; o.value = "50"; s.add(o); + o = d.createElement("option"); o.text = "APA102"; o.value = "51"; s.add(o); + o = d.createElement("option"); o.text = "LPD8806"; o.value = "52"; s.add(o); + o = d.createElement("option"); o.text = "P9813"; o.value = "53"; s.add(o); + o = d.createElement("option"); o.text = "TM1814"; o.value = "54"; s.add(o); + t.appendChild(s); + + t.appendChild(d.createTextNode(" CO: ")); + s = d.createElement("select"); + s.setAttribute("name","CO"+i); + o = d.createElement("option"); o.text = "GRB"; o.value = "0"; s.add(o); + o = d.createElement("option"); o.text = "RGB"; o.value = "1"; s.add(o); + o = d.createElement("option"); o.text = "BRG"; o.value = "2"; s.add(o); + o = d.createElement("option"); o.text = "RBG"; o.value = "3"; s.add(o); + o = d.createElement("option"); o.text = "BGR"; o.value = "4"; s.add(o); + o = d.createElement("option"); o.text = "GBR"; o.value = "5"; s.add(o); + t.appendChild(s); + + t.appendChild(d.createTextNode(" RGBW: ")); + s = d.createElement("input"); + s.type = "checkbox"; + s.setAttribute("name","EW"+i); + t.appendChild(s); + + t.appendChild(d.createElement("br")); + + t.appendChild(d.createTextNode("pin:")); + var e = d.createElement("input"); + e.type = "number"; e.value = ""; e.name = "LP"+i; e.min=0; e.max=40; e.required=true; e.onchange=function(){UI()}; + t.appendChild(e); + + var b = d.createElement("div"); + b.setAttribute("name","iLK"); + b.appendChild(d.createTextNode(" clk:")); + e = d.createElement("input"); + e.type = "number"; e.value = ""; e.name = "LK"+i; e.min=0; e.max=40; e.onchange=function(){UI()}; + if (d.getElementsByName("LTsel")[0].value>49) e.required = true; + b.appendChild(e); + t.appendChild(b); + + t.appendChild(d.createTextNode(" count:")); + e = d.createElement("input"); + e.type = "number"; e.value = "0"; e.name = "LC"+i; e.min=0; e.max=1000; e.required=true; e.oninput = function(){UI()}; + t.appendChild(e); + + t.appendChild(d.createElement("br")); + f.appendChild(t); + } + if (n==-1) { + o[--i].remove();--i; + } + + var p = d.getElementById("+"); + var m = d.getElementById("-"); + if (i0) {m.style="display:inline";} else {m.style="display:none";} + + UI(); + } function GetV() { - //values injected by server while sending HTML - } + //values injected by server while sending HTML + }

WLED Software Update

-Installed version: 0.11.1
Download the latest binary: Download the latest binary:

diff --git a/wled00/html_settings.h b/wled00/html_settings.h index de5a0727..72398a53 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -71,7 +71,7 @@ Do not enable if WiFi is working correctly, increases power consumption.
LED Settings