diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 34e59e40f2..36c25512f0 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1870,6 +1870,7 @@ void WS2812FX::estimateCurrentAndLimitBri() { return; } + bool isFastLED = busses.hasFastLED; // if one bus is FastLED, then we can't have any NeoPixel busses (RMT driver conflict) uint16_t pLen = getLengthPhysical(); uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed; uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power @@ -1889,6 +1890,12 @@ void WS2812FX::estimateCurrentAndLimitBri() { for (uint_fast16_t i = 0; i < len; i++) { //sum up the usage of each LED uint32_t c = bus->getPixelColor(i); byte r = R(c), g = G(c), b = B(c), w = W(c); + if (isFastLED) { + r = scale8(r, _brightness); + g = scale8(g, _brightness); + b = scale8(b, _brightness); + w = 0; + } if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation busPowerSum += (max(max(r,g),b)) * 3; // WLEDMM use native min/max diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index fff5ecb384..6db0a9c2aa 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -4,6 +4,22 @@ #include #include + +// experimental - FastLED I2S driver options +//#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) // USE I2S#1 for boards with two I2S units +//#define FASTLED_ESP32_I2S true // use clockless I2S driver instead of RMT +//#define I2S_DEVICE 1 // I2S#0 needed by audioreactive +//#define FASTLED_ESP32_I2S_NUM_DMA_BUFFERS 4 // recommended for solving flicker issues in combination with interrupts triggered by other code parts. +//#endif +// experimental - FastLED RMT driver options +//#define FASTLED_RMT_BUILTIN_DRIVER true // allow other RMT applications to co-exist //WLEDMM not working on -S2 +//#define FASTLED_RMT_MAX_CHANNELS 1 // only use one RMT channel (slow) +//#define FASTLED_ESP32_FLASH_LOCK true // force flash operations to wait until the show() is done - avoids interference with the timing of pixel output + +#undef FASTLED_INTERNAL // just to be sure +#include + + #include "const.h" #include "pin_manager.h" #include "bus_wrapper.h" @@ -485,6 +501,276 @@ void BusNetwork::cleanup() { // *************************************************************************** +// Color correction +//#define FL_COLORMODE TypicalLEDStrip // FastLED recommended +#define FL_COLORMODE UncorrectedColor // no gamma color correction +// fastled global LED buffer +CRGB BusFastLED::leds[1024]; // hack - shared between buses + +BusFastLED::BusFastLED(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) { + // UGLY UGLY workaround for compile-time pin value in FastLED template + _valid = false; // don't use this driver yet + USER_PRINTF("FastLED.addLeds - pin:%d offset:%d, num:%d \n", bc.pins[0], bc.start, bc.count); + _len = bc.count; + _start = bc.start; + _type = bc.type; + _needsRefresh = true; // we need "off refresh" for dithering + reversed = false; // not yet supported + _pins[0] = bc.pins[0]; + _pins[1] = bc.pins[1]; // TODO: remove once the UI knows we don't need clock pin + // return; // emergency kill switch + switch (bc.pins[0]) { + #if CONFIG_IDF_TARGET_ESP32 + case 0: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 1: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 2: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 3: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 4: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 5: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 6: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 7: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 8: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 9: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 10: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 11: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 12: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 13: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 14: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 15: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !defined(BOARD_HAS_PSRAM) && !defined(ARDUINO_ESP32_PICO) + // 16+17 = reserved for PSRAM, or reserved for FLASH on pico-D4 + case 16: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 17: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + case 18: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 19: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 20: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 21: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 22: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 23: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 24: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 25: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 26: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 27: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 28: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 29: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 30: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 31: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 32: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 33: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // 34-39 input-only + // case 34: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 35: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 36: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 37: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 38: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 39: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif //CONFIG_IDF_TARGET_ESP32 + + #if CONFIG_IDF_TARGET_ESP32S2 + case 0: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 1: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 2: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 3: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 4: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 5: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 6: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 7: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 8: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 9: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 10: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 11: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 12: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 13: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 14: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 15: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 16: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 17: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 18: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !ARDUINO_USB_CDC_ON_BOOT + // 19 + 20 = USB HWCDC. reserved for USB port when ARDUINO_USB_CDC_ON_BOOT=1 + case 19: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 20: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + case 21: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // 22 to 32: not connected, or reserved for SPI FLASH + // case 22: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 23: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 24: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 25: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !defined(BOARD_HAS_PSRAM) + // 26-32 = reserved for PSRAM + case 26: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 27: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 28: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 29: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 30: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 31: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 32: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + case 33: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 34: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 35: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 36: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 37: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 38: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 39: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 40: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 41: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 42: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 43: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 44: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 45: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // 46 input-only + // case 46: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif //CONFIG_IDF_TARGET_ESP32S2 + + #if CONFIG_IDF_TARGET_ESP32C3 + case 0: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 1: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 2: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 3: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 4: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 5: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 6: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 7: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 8: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 9: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 10: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // 11-17 reserved for SPI FLASH + //case 11: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 12: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 13: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 14: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 15: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 16: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + //case 17: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !ARDUINO_USB_CDC_ON_BOOT + // 18 + 19 = USB HWCDC. reserved for USB port when ARDUINO_USB_CDC_ON_BOOT=1 + case 18: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 19: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + // 20+21 = Serial RX+TX --> don't use for LEDS when serial-to-USB is needed + case 20: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 21: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif //CONFIG_IDF_TARGET_ESP32S2 + + #if CONFIG_IDF_TARGET_ESP32S3 + case 0: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 1: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 2: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 3: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 4: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 5: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 6: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 7: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 8: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 9: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 10: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 11: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 12: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 13: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 14: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 15: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 16: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 17: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 18: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !ARDUINO_USB_CDC_ON_BOOT + // 19 + 20 = USB-JTAG. Not recommended for other uses. + case 19: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 20: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + case 21: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // // 22 to 32: not connected, or SPI FLASH + // case 22: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 23: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 24: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 25: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 26: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 27: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 28: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 29: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 30: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 31: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // case 32: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #if !defined(BOARD_HAS_PSRAM) + // 33 to 37: reserved if using _octal_ SPI Flash or _octal_ PSRAM + case 33: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 34: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 35: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 36: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 37: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif + case 38: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 39: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 40: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 41: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 42: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + // 43+44 = Serial RX+TX --> don't use for LEDS when serial-to-USB is needed + case 43: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 44: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 45: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 46: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 47: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + case 48: FastLED.addLeds(this->leds, bc.start, bc.count).setCorrection(FL_COLORMODE); break; + #endif //CONFIG_IDF_TARGET_ESP32S3 + + default: USER_PRINTF("FastLedPin assignment: pin not supported %d\n", bc.pins[0]); + } //switch pinNr + //FastLED.setDither(0); // disables dithering --> https://github.com/FastLED/FastLED/wiki/FastLED-Temporal-Dithering + FastLED.clear(); + _valid = true; // driver ready for use +} + +void BusFastLED::setPixelColor(uint16_t pix, uint32_t c) { + if (!_valid || pix >= _len) return; + if (reversed) pix = _len - pix -1; + pix = pix + _start; +#if 1 + // GRB = ws2812b default + this->leds[pix].r = R(c); + this->leds[pix].g = G(c); + this->leds[pix].b = B(c); +#else + // RGB + this->leds[pix] = CRGB(G(c), R(c), B(c)); +#endif +} + +uint32_t BusFastLED::getPixelColor(uint16_t pix) { + if (!_valid || pix >= _len) return 0; + if (reversed) pix = _len - pix -1; + pix = pix + _start; +#if 1 + // GRB = ws2812b default + return uint32_t(this->leds[pix]) & 0x00FFFFFF; +#else + // RGB + CRGB yeah = this->leds[pix]; + return RGBW32(yeah.g, yeah.r, yeah.b, 0); +#endif +} + +void BusFastLED::show() { + // no action as we call once for all buses +} + +uint8_t BusFastLED::getPins(uint8_t* pinArray) { + int numPins = 2; + for (uint8_t i = 0; i < numPins; i++) { + pinArray[i] = _pins[i]; + } + return numPins; +} + + +void BusFastLED::setBrightness(uint8_t b, bool immediate) { + FastLED.setBrightness(b); + _bri = b; // needed for brightness limiter +} + +// *************************************************************************** + #ifdef WLED_ENABLE_HUB75MATRIX #warning "HUB75 driver enabled (experimental)" @@ -743,6 +1029,9 @@ int BusManager::add(BusConfig &bc) { DEBUG_PRINTLN("BusManager::add - Adding BusHub75Matrix"); busses[numBusses] = new BusHub75Matrix(bc); #endif + } else if (bc.type == TYPE_FASTLED) { + busses[numBusses] = new BusFastLED(bc); + hasFastLED = true; } else if (IS_DIGITAL(bc.type)) { busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap); } else if (bc.type == TYPE_ONOFF) { @@ -774,6 +1063,9 @@ void BusManager::show() { for (uint8_t i = 0; i < numBusses; i++) { busses[i]->show(); } + if(hasFastLED) { + FastLED.show(); + } } void BusManager::setStatusPixel(uint32_t c) { diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 0bfd3e04de..7af77c5c70 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -333,6 +333,38 @@ class BusNetwork : public Bus { byte *_data; }; + +class BusFastLED : public Bus { + public: + BusFastLED(BusConfig &bc); + + uint16_t getMaxPixels() override { return 1024; }; + bool hasRGB() { return true; } + bool hasWhite() { return false; } + + void setPixelColor(uint16_t pix, uint32_t c); + void setBrightness(uint8_t b, bool immediate); + + uint32_t getPixelColor(uint16_t pix); + + void show(); + + void cleanup() { + // TODO + } + + uint8_t getPins(uint8_t* pinArray); + + uint16_t getLength() { + return _len; + } + + private: + static CRGB leds[1024]; + uint8_t _pins[4] = {0, 0}; + +}; + #ifdef WLED_ENABLE_HUB75MATRIX class BusHub75Matrix : public Bus { public: @@ -425,6 +457,8 @@ class BusManager { return numBusses; } + bool hasFastLED = false; // can be used to check if FastLED driver is used + private: uint8_t numBusses = 0; Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES] = {nullptr}; // WLEDMM init array diff --git a/wled00/const.h b/wled00/const.h index 7857a1d33d..230b9d3677 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -245,6 +245,8 @@ #define TYPE_P9813 53 #define TYPE_LPD6803 54 +#define TYPE_FASTLED 60 + #define TYPE_HUB75MATRIX 100 // 100 - 110 //Network types (master broadcast) (80-95) @@ -253,7 +255,7 @@ #define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused) #define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus) -#define IS_DIGITAL(t) (((t) & 0x10) || ((t)==TYPE_HUB75MATRIX)) //digital are 16-31 and 48-63 // WLEDMM added HUB75 +#define IS_DIGITAL(t) (((t) & 0x10) || ((t)==TYPE_HUB75MATRIX) || ((t)==TYPE_FASTLED)) //digital are 16-31 and 48-63 // WLEDMM added HUB75 and fastLED #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) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index e1979fdcaf..16e1e66d9b 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -375,6 +375,7 @@ \ \ \ +\ '} diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 32420fcc88..70eb3a38ed 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -265,6 +265,7 @@ static bool sendLiveLedsWs(uint32_t wsClient) // WLEDMM added "static" #endif uint8_t stripBrightness = strip.getBrightness(); + bool isFastLED = busses.hasFastLED; // if one bus is FastLED, then we can't have any NeoPixel busses (RMT driver conflict) for (size_t i = 0; pos < bufSize -2; i += n) { //WLEDMM skipping lines done right @@ -273,7 +274,8 @@ static bool sendLiveLedsWs(uint32_t wsClient) // WLEDMM added "static" if ((i/Segment::maxWidth)%(n)) i += Segment::maxWidth * (n-1); } #endif - uint32_t c = restoreColorLossy(strip.getPixelColor(i), stripBrightness); // WLEDMM full bright preview - does _not_ recover ABL reductions + uint32_t c = strip.getPixelColor(i); + if (!isFastLED) c = restoreColorLossy(c, stripBrightness); // WLEDMM full bright preview - does _not_ recover ABL reductions // WLEDMM begin: preview with color gamma correction if (gammaCorrectPreview) { uint8_t w = W(c); // not sure why, but it looks better if using "white" without corrections