Merge branch '0_15' into blending-styles

This commit is contained in:
Blaz Kristan
2024-09-15 11:05:16 +02:00
27 changed files with 1380 additions and 1177 deletions

View File

@@ -43,21 +43,16 @@
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]}
*/
//factory defaults LED setup
//#define PIXEL_COUNTS 30, 30, 30, 30
//#define DATA_PINS 16, 1, 3, 4
//#define DEFAULT_LED_TYPE TYPE_WS2812_RGB
#ifndef PIXEL_COUNTS
#define PIXEL_COUNTS DEFAULT_LED_COUNT
#endif
#ifndef DATA_PINS
#define DATA_PINS LEDPIN
#define DATA_PINS DEFAULT_LED_PIN
#endif
#ifndef DEFAULT_LED_TYPE
#define DEFAULT_LED_TYPE TYPE_WS2812_RGB
#ifndef LED_TYPES
#define LED_TYPES DEFAULT_LED_TYPE
#endif
#ifndef DEFAULT_LED_COLOR_ORDER
@@ -69,6 +64,18 @@
#error "Max segments must be at least max number of busses!"
#endif
static constexpr unsigned sumPinsRequired(const unsigned* current, size_t count) {
return (count > 0) ? (Bus::getNumberOfPins(*current) + sumPinsRequired(current+1,count-1)) : 0;
}
static constexpr bool validatePinsAndTypes(const unsigned* types, unsigned numTypes, unsigned numPins ) {
// Pins provided < pins required -> always invalid
// Pins provided = pins required -> always valid
// Pins provided > pins required -> valid if excess pins are a product of last type pins since it will be repeated
return (sumPinsRequired(types, numTypes) > numPins) ? false :
(numPins - sumPinsRequired(types, numTypes)) % Bus::getNumberOfPins(types[numTypes-1]) == 0;
}
///////////////////////////////////////////////////////////////////////////////
// Segment class implementation
@@ -206,7 +213,7 @@ void Segment::resetIfRequired() {
reset = false;
}
CRGBPalette16 IRAM_ATTR_YN &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0;
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // TODO remove strip dependency by moving customPalettes out of strip
//default palette. Differs depending on effect
@@ -425,7 +432,7 @@ uint8_t IRAM_ATTR Segment::currentBri(bool useCct) const {
return curBri;
}
uint8_t IRAM_ATTR_YN Segment::currentMode() const {
uint8_t Segment::currentMode() const {
#ifndef WLED_DISABLE_MODE_BLEND
unsigned prog = progress();
if (prog == 0xFFFFU) return mode;
@@ -1317,28 +1324,68 @@ void WS2812FX::finalizeInit() {
//if busses failed to load, add default (fresh install, FS issue, ...)
if (BusManager::getNumBusses() == 0) {
DEBUG_PRINTLN(F("No busses, init default"));
const unsigned defDataPins[] = {DATA_PINS};
const unsigned defCounts[] = {PIXEL_COUNTS};
const unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0]));
const unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0]));
// if number of pins is divisible by counts, use number of counts to determine number of buses, otherwise use pins
const unsigned defNumBusses = defNumPins > defNumCounts && defNumPins%defNumCounts == 0 ? defNumCounts : defNumPins;
const unsigned pinsPerBus = defNumPins / defNumBusses;
constexpr unsigned defDataTypes[] = {LED_TYPES};
constexpr unsigned defDataPins[] = {DATA_PINS};
constexpr unsigned defCounts[] = {PIXEL_COUNTS};
constexpr unsigned defNumTypes = ((sizeof defDataTypes) / (sizeof defDataTypes[0]));
constexpr unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0]));
constexpr unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0]));
static_assert(validatePinsAndTypes(defDataTypes, defNumTypes, defNumPins),
"The default pin list defined in DATA_PINS does not match the pin requirements for the default buses defined in LED_TYPES");
unsigned prevLen = 0;
for (unsigned i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
uint8_t defPin[5]; // max 5 pins
for (unsigned j = 0; j < pinsPerBus; j++) defPin[j] = defDataPins[i*pinsPerBus + j];
// when booting without config (1st boot) we need to make sure GPIOs defined for LED output don't clash with hardware
// i.e. DEBUG (GPIO1), DMX (2), SPI RAM/FLASH (16&17 on ESP32-WROVER/PICO), etc
if (pinManager.isPinAllocated(defPin[0])) {
defPin[0] = 1; // start with GPIO1 and work upwards
while (pinManager.isPinAllocated(defPin[0]) && defPin[0] < WLED_NUM_PINS) defPin[0]++;
unsigned pinsIndex = 0;
for (unsigned i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
uint8_t defPin[OUTPUT_MAX_PINS];
// if we have less types than requested outputs and they do not align, use last known type to set current type
unsigned dataType = defDataTypes[(i < defNumTypes) ? i : defNumTypes -1];
unsigned busPins = Bus::getNumberOfPins(dataType);
// if we need more pins than available all outputs have been configured
if (pinsIndex + busPins > defNumPins) break;
// Assign all pins first so we can check for conflicts on this bus
for (unsigned j = 0; j < busPins && j < OUTPUT_MAX_PINS; j++) defPin[j] = defDataPins[pinsIndex + j];
for (unsigned j = 0; j < busPins && j < OUTPUT_MAX_PINS; j++) {
bool validPin = true;
// When booting without config (1st boot) we need to make sure GPIOs defined for LED output don't clash with hardware
// i.e. DEBUG (GPIO1), DMX (2), SPI RAM/FLASH (16&17 on ESP32-WROVER/PICO), read/only pins, etc.
// Pin should not be already allocated, read/only or defined for current bus
while (pinManager.isPinAllocated(defPin[j]) || !pinManager.isPinOk(defPin[j],true)) {
if (validPin) {
DEBUG_PRINTLN(F("Some of the provided pins cannot be used to configure this LED output."));
defPin[j] = 1; // start with GPIO1 and work upwards
validPin = false;
} else if (defPin[j] < WLED_NUM_PINS) {
defPin[j]++;
} else {
DEBUG_PRINTLN(F("No available pins left! Can't configure output."));
return;
}
// is the newly assigned pin already defined? try next in line until there are no clashes
bool clash;
do {
clash = false;
for (const auto &pin : defDataPins) {
if (pin == defPin[j]) {
defPin[j]++;
if (defPin[j] < WLED_NUM_PINS) clash = true;
}
}
} while (clash);
}
}
pinsIndex += busPins;
unsigned start = prevLen;
// if we have less counts than pins and they do not align, use last known count to set current count
unsigned count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];
// analog always has length 1
if (Bus::isPWM(dataType)) count = 1;
prevLen += count;
BusConfig defCfg = BusConfig(DEFAULT_LED_TYPE, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0, useGlobalLedBuffer);
BusConfig defCfg = BusConfig(dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0, useGlobalLedBuffer);
if (BusManager::add(defCfg) == -1) break;
}
}
@@ -1351,12 +1398,12 @@ void WS2812FX::finalizeInit() {
//RGBW mode is enabled if at least one of the strips is RGBW
_hasWhiteChannel |= bus->hasWhite();
//refresh is required to remain off if at least one of the strips requires the refresh.
_isOffRefreshRequired |= bus->isOffRefreshRequired();
_isOffRefreshRequired |= bus->isOffRefreshRequired() && !bus->isPWM(); // use refresh bit for phase shift with analog
unsigned busEnd = bus->getStart() + bus->getLength();
if (busEnd > _length) _length = busEnd;
#ifdef ESP8266
// why do we need to reinitialise GPIO3???
//if ((!IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType()))) continue;
//if (!bus->isDigital() || bus->is2Pin()) continue;
//uint8_t pins[5];
//if (!bus->getPins(pins)) continue;
//BusDigital* bd = static_cast<BusDigital*>(bus);