mirror of
https://github.com/wled/WLED.git
synced 2025-04-19 12:27:17 +00:00
Merge pull request #4484 from blazoncek/parallel-I2S
WWA strip support & parallel I2S for S2/S3 (bumping outputs from 5/4 to 12)
This commit is contained in:
commit
a0c55c6406
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,6 +15,7 @@ wled-update.sh
|
||||
|
||||
/build_output/
|
||||
/node_modules/
|
||||
/logs/
|
||||
|
||||
/wled00/extLibs
|
||||
/wled00/LittleFS
|
||||
|
@ -138,7 +138,7 @@ lib_compat_mode = strict
|
||||
lib_deps =
|
||||
fastled/FastLED @ 3.6.0
|
||||
IRremoteESP8266 @ 2.8.2
|
||||
makuna/NeoPixelBus @ 2.8.0
|
||||
makuna/NeoPixelBus @ 2.8.3
|
||||
#https://github.com/makuna/NeoPixelBus.git#CoreShaderBeta
|
||||
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.0
|
||||
# for I2C interface
|
||||
|
22
wled00/FX.h
22
wled00/FX.h
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
/*
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
Harm Aldick - 2016
|
||||
@ -8,12 +9,15 @@
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified for WLED
|
||||
|
||||
Segment class/struct (c) 2022 Blaz Kristan (@blazoncek)
|
||||
*/
|
||||
|
||||
#ifndef WS2812FX_h
|
||||
#define WS2812FX_h
|
||||
|
||||
#include <vector>
|
||||
#include "wled.h"
|
||||
|
||||
#include "const.h"
|
||||
#include "bus_manager.h"
|
||||
@ -71,18 +75,15 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
|
||||
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#ifdef ESP8266
|
||||
#define MAX_NUM_SEGMENTS 16
|
||||
#define MAX_NUM_SEGMENTS 16
|
||||
/* How much data bytes all segments combined may allocate */
|
||||
#define MAX_SEGMENT_DATA 5120
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define MAX_NUM_SEGMENTS 20
|
||||
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*512) // 10k by default (S2 is short on free RAM)
|
||||
#else
|
||||
#ifndef MAX_NUM_SEGMENTS
|
||||
#define MAX_NUM_SEGMENTS 32
|
||||
#endif
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*768) // 24k by default (S2 is short on free RAM)
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*1280) // 40k by default
|
||||
#endif
|
||||
#define MAX_NUM_SEGMENTS 32 // warning: going beyond 32 may consume too much RAM for stable operation
|
||||
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*1280) // 40k by default
|
||||
#endif
|
||||
|
||||
/* How much data bytes each segment should max allocate to leave enough space for other segments,
|
||||
@ -571,6 +572,8 @@ typedef struct Segment {
|
||||
inline uint16_t groupLength() const { return grouping + spacing; }
|
||||
inline uint8_t getLightCapabilities() const { return _capabilities; }
|
||||
inline void deactivate() { setGeometry(0,0); }
|
||||
inline Segment &clearName() { if (name) free(name); name = nullptr; return *this; }
|
||||
inline Segment &setName(const String &name) { return setName(name.c_str()); }
|
||||
|
||||
inline static unsigned getUsedSegmentData() { return Segment::_usedSegmentData; }
|
||||
inline static void addUsedSegmentData(int len) { Segment::_usedSegmentData += len; }
|
||||
@ -593,6 +596,7 @@ typedef struct Segment {
|
||||
Segment &setOption(uint8_t n, bool val);
|
||||
Segment &setMode(uint8_t fx, bool loadDefaults = false);
|
||||
Segment &setPalette(uint8_t pal);
|
||||
Segment &setName(const char* name);
|
||||
uint8_t differs(const Segment& b) const;
|
||||
void refreshLightCapabilities();
|
||||
|
||||
|
@ -649,6 +649,20 @@ Segment &Segment::setPalette(uint8_t pal) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Segment &Segment::setName(const char *newName) {
|
||||
if (newName) {
|
||||
const int newLen = min(strlen(newName), (size_t)WLED_MAX_SEGNAME_LEN);
|
||||
if (newLen) {
|
||||
if (name) name = static_cast<char*>(realloc(name, newLen+1));
|
||||
else name = static_cast<char*>(malloc(newLen+1));
|
||||
if (name) strlcpy(name, newName, newLen+1);
|
||||
name[newLen] = 0;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
return clearName();
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
unsigned Segment::virtualWidth() const {
|
||||
unsigned groupLen = groupLength();
|
||||
@ -1311,6 +1325,34 @@ void WS2812FX::finalizeInit() {
|
||||
|
||||
_hasWhiteChannel = _isOffRefreshRequired = false;
|
||||
|
||||
unsigned digitalCount = 0;
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
// determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
|
||||
unsigned maxLedsOnBus = 0;
|
||||
for (const auto &bus : busConfigs) {
|
||||
if (Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type)) {
|
||||
digitalCount++;
|
||||
if (bus.count > maxLedsOnBus) maxLedsOnBus = bus.count;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("Maximum LEDs on a bus: %u\nDigital buses: %u\n"), maxLedsOnBus, digitalCount);
|
||||
// we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
|
||||
if (maxLedsOnBus <= 300 && useParallelI2S) BusManager::useParallelOutput(); // must call before creating buses
|
||||
else useParallelI2S = false; // enforce single I2S
|
||||
#endif
|
||||
|
||||
// create buses/outputs
|
||||
unsigned mem = 0;
|
||||
digitalCount = 0;
|
||||
for (const auto &bus : busConfigs) {
|
||||
mem += bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount++ : 0); // includes global buffer
|
||||
if (mem <= MAX_LED_MEMORY) {
|
||||
if (BusManager::add(bus) == -1) break;
|
||||
} else DEBUG_PRINTF_P(PSTR("Out of LED memory! Bus %d (%d) #%u not created."), (int)bus.type, (int)bus.count, digitalCount);
|
||||
}
|
||||
busConfigs.clear();
|
||||
busConfigs.shrink_to_fit();
|
||||
|
||||
//if busses failed to load, add default (fresh install, FS issue, ...)
|
||||
if (BusManager::getNumBusses() == 0) {
|
||||
DEBUG_PRINTLN(F("No busses, init default"));
|
||||
@ -1326,6 +1368,7 @@ void WS2812FX::finalizeInit() {
|
||||
|
||||
unsigned prevLen = 0;
|
||||
unsigned pinsIndex = 0;
|
||||
digitalCount = 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
|
||||
@ -1390,9 +1433,11 @@ void WS2812FX::finalizeInit() {
|
||||
if (Bus::isPWM(dataType) || Bus::isOnOff(dataType)) count = 1;
|
||||
prevLen += count;
|
||||
BusConfig defCfg = BusConfig(dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0, useGlobalLedBuffer);
|
||||
mem += defCfg.memUsage(Bus::isDigital(dataType) && !Bus::is2Pin(dataType) ? digitalCount++ : 0);
|
||||
if (BusManager::add(defCfg) == -1) break;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("LED buffer size: %uB/%uB\n"), mem, BusManager::memUsage());
|
||||
|
||||
_length = 0;
|
||||
for (int i=0; i<BusManager::getNumBusses(); i++) {
|
||||
@ -1409,6 +1454,7 @@ void WS2812FX::finalizeInit() {
|
||||
// This must be done after all buses have been created, as some kinds (parallel I2S) interact
|
||||
bus->begin();
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("Heap after buses: %d\n"), ESP.getFreeHeap());
|
||||
|
||||
Segment::maxWidth = _length;
|
||||
Segment::maxHeight = 1;
|
||||
|
@ -21,10 +21,12 @@
|
||||
#endif
|
||||
#include "const.h"
|
||||
#include "pin_manager.h"
|
||||
#include "bus_wrapper.h"
|
||||
#include "bus_manager.h"
|
||||
#include "bus_wrapper.h"
|
||||
#include <bits/unique_ptr.h>
|
||||
|
||||
extern bool cctICused;
|
||||
extern bool useParallelI2S;
|
||||
|
||||
//colors.cpp
|
||||
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
||||
@ -32,28 +34,6 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
||||
//udp.cpp
|
||||
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, const uint8_t* buffer, uint8_t bri=255, bool isRGBW=false);
|
||||
|
||||
// enable additional debug output
|
||||
#if defined(WLED_DEBUG_HOST)
|
||||
#include "net_debug.h"
|
||||
#define DEBUGOUT NetDebug
|
||||
#else
|
||||
#define DEBUGOUT Serial
|
||||
#endif
|
||||
|
||||
#ifdef WLED_DEBUG
|
||||
#ifndef ESP8266
|
||||
#include <rom/rtc.h>
|
||||
#endif
|
||||
#define DEBUG_PRINT(x) DEBUGOUT.print(x)
|
||||
#define DEBUG_PRINTLN(x) DEBUGOUT.println(x)
|
||||
#define DEBUG_PRINTF(x...) DEBUGOUT.printf(x)
|
||||
#define DEBUG_PRINTF_P(x...) DEBUGOUT.printf_P(x)
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x...)
|
||||
#define DEBUG_PRINTF_P(x...)
|
||||
#endif
|
||||
|
||||
//color mangling macros
|
||||
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
|
||||
@ -66,6 +46,7 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, const
|
||||
bool ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) {
|
||||
if (count() >= WLED_MAX_COLOR_ORDER_MAPPINGS || len == 0 || (colorOrder & 0x0F) > COL_ORDER_MAX) return false; // upper nibble contains W swap information
|
||||
_mappings.push_back({start,len,colorOrder});
|
||||
DEBUGBUS_PRINTF_P(PSTR("Bus: Add COM (%d,%d,%d)\n"), (int)start, (int)len, (int)colorOrder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,10 +100,14 @@ uint32_t Bus::autoWhiteCalc(uint32_t c) const {
|
||||
}
|
||||
|
||||
uint8_t *Bus::allocateData(size_t size) {
|
||||
if (_data) free(_data); // should not happen, but for safety
|
||||
freeData(); // should not happen, but for safety
|
||||
return _data = (uint8_t *)(size>0 ? calloc(size, sizeof(uint8_t)) : nullptr);
|
||||
}
|
||||
|
||||
void Bus::freeData() {
|
||||
if (_data) free(_data);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
BusDigital::BusDigital(const BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||
: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814))
|
||||
@ -132,30 +117,41 @@ BusDigital::BusDigital(const BusConfig &bc, uint8_t nr, const ColorOrderMap &com
|
||||
, _milliAmpsMax(bc.milliAmpsMax)
|
||||
, _colorOrderMap(com)
|
||||
{
|
||||
if (!isDigital(bc.type) || !bc.count) return;
|
||||
if (!PinManager::allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
||||
DEBUGBUS_PRINTLN(F("Bus: Creating digital bus."));
|
||||
if (!isDigital(bc.type) || !bc.count) { DEBUGBUS_PRINTLN(F("Not digial or empty bus!")); return; }
|
||||
if (!PinManager::allocatePin(bc.pins[0], true, PinOwner::BusDigital)) { DEBUGBUS_PRINTLN(F("Pin 0 allocated!")); return; }
|
||||
_frequencykHz = 0U;
|
||||
_pins[0] = bc.pins[0];
|
||||
if (is2Pin(bc.type)) {
|
||||
if (!PinManager::allocatePin(bc.pins[1], true, PinOwner::BusDigital)) {
|
||||
cleanup();
|
||||
DEBUGBUS_PRINTLN(F("Pin 1 allocated!"));
|
||||
return;
|
||||
}
|
||||
_pins[1] = bc.pins[1];
|
||||
_frequencykHz = bc.frequency ? bc.frequency : 2000U; // 2MHz clock if undefined
|
||||
}
|
||||
_iType = PolyBus::getI(bc.type, _pins, nr);
|
||||
if (_iType == I_NONE) return;
|
||||
if (_iType == I_NONE) { DEBUGBUS_PRINTLN(F("Incorrect iType!")); return; }
|
||||
_hasRgb = hasRGB(bc.type);
|
||||
_hasWhite = hasWhite(bc.type);
|
||||
_hasCCT = hasCCT(bc.type);
|
||||
if (bc.doubleBuffer && !allocateData(bc.count * Bus::getNumberOfChannels(bc.type))) return;
|
||||
if (bc.doubleBuffer && !allocateData(bc.count * Bus::getNumberOfChannels(bc.type))) { DEBUGBUS_PRINTLN(F("Buffer allocation failed!")); return; }
|
||||
//_buffering = bc.doubleBuffer;
|
||||
uint16_t lenToCreate = bc.count;
|
||||
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr);
|
||||
_valid = (_busPtr != nullptr);
|
||||
DEBUG_PRINTF_P(PSTR("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n"), _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], is2Pin(bc.type)?_pins[1]:255, _iType, _milliAmpsPerLed, _milliAmpsMax);
|
||||
DEBUGBUS_PRINTF_P(PSTR("Bus: %successfully inited #%u (len:%u, type:%u (RGB:%d, W:%d, CCT:%d), pins:%u,%u [itype:%u] mA=%d/%d)\n"),
|
||||
_valid?"S":"Uns",
|
||||
(int)nr,
|
||||
(int)bc.count,
|
||||
(int)bc.type,
|
||||
(int)_hasRgb, (int)_hasWhite, (int)_hasCCT,
|
||||
(unsigned)_pins[0], is2Pin(bc.type)?(unsigned)_pins[1]:255U,
|
||||
(unsigned)_iType,
|
||||
(int)_milliAmpsPerLed, (int)_milliAmpsMax
|
||||
);
|
||||
}
|
||||
|
||||
//DISCLAIMER
|
||||
@ -166,7 +162,7 @@ BusDigital::BusDigital(const BusConfig &bc, uint8_t nr, const ColorOrderMap &com
|
||||
//I am NOT to be held liable for burned down garages or houses!
|
||||
|
||||
// To disable brightness limiter we either set output max current to 0 or single LED current to 0
|
||||
uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
uint8_t BusDigital::estimateCurrentAndLimitBri() const {
|
||||
bool useWackyWS2815PowerModel = false;
|
||||
byte actualMilliampsPerLed = _milliAmpsPerLed;
|
||||
|
||||
@ -179,7 +175,7 @@ uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
actualMilliampsPerLed = 12; // from testing an actual strip
|
||||
}
|
||||
|
||||
size_t powerBudget = (_milliAmpsMax - MA_FOR_ESP/BusManager::getNumBusses()); //80/120mA for ESP power
|
||||
unsigned powerBudget = (_milliAmpsMax - MA_FOR_ESP/BusManager::getNumBusses()); //80/120mA for ESP power
|
||||
if (powerBudget > getLength()) { //each LED uses about 1mA in standby, exclude that from power budget
|
||||
powerBudget -= getLength();
|
||||
} else {
|
||||
@ -204,26 +200,25 @@ uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
}
|
||||
|
||||
// powerSum has all the values of channels summed (max would be getLength()*765 as white is excluded) so convert to milliAmps
|
||||
busPowerSum = (busPowerSum * actualMilliampsPerLed) / 765;
|
||||
_milliAmpsTotal = busPowerSum * _bri / 255;
|
||||
BusDigital::_milliAmpsTotal = (busPowerSum * actualMilliampsPerLed * _bri) / (765*255);
|
||||
|
||||
uint8_t newBri = _bri;
|
||||
if (busPowerSum * _bri / 255 > powerBudget) { //scale brightness down to stay in current limit
|
||||
float scale = (float)(powerBudget * 255) / (float)(busPowerSum * _bri);
|
||||
if (scale >= 1.0f) return _bri;
|
||||
_milliAmpsTotal = ceilf((float)_milliAmpsTotal * scale);
|
||||
uint8_t scaleB = min((int)(scale * 255), 255);
|
||||
newBri = unsigned(_bri * scaleB) / 256 + 1;
|
||||
if (BusDigital::_milliAmpsTotal > powerBudget) {
|
||||
//scale brightness down to stay in current limit
|
||||
unsigned scaleB = powerBudget * 255 / BusDigital::_milliAmpsTotal;
|
||||
newBri = (_bri * scaleB) / 256 + 1;
|
||||
BusDigital::_milliAmpsTotal = powerBudget;
|
||||
//_milliAmpsTotal = (busPowerSum * actualMilliampsPerLed * newBri) / (765*255);
|
||||
}
|
||||
return newBri;
|
||||
}
|
||||
|
||||
void BusDigital::show() {
|
||||
_milliAmpsTotal = 0;
|
||||
BusDigital::_milliAmpsTotal = 0;
|
||||
if (!_valid) return;
|
||||
|
||||
uint8_t cctWW = 0, cctCW = 0;
|
||||
unsigned newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal
|
||||
unsigned newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal (TODO: could use PolyBus::CalcTotalMilliAmpere())
|
||||
if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits
|
||||
|
||||
if (_data) {
|
||||
@ -249,6 +244,7 @@ void BusDigital::show() {
|
||||
// TODO: there is an issue if CCT is calculated from RGB value (_cct==-1), we cannot do that with double buffer
|
||||
Bus::_cct = _data[offset+channels-1];
|
||||
Bus::calculateCCT(c, cctWW, cctCW);
|
||||
if (_type == TYPE_WS2812_WWA) c = RGBW32(cctWW, cctCW, 0, W(c)); // may need swapping
|
||||
}
|
||||
unsigned pix = i;
|
||||
if (_reversed) pix = _len - pix -1;
|
||||
@ -334,8 +330,8 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
|
||||
uint8_t cctWW = 0, cctCW = 0;
|
||||
Bus::calculateCCT(c, cctWW, cctCW);
|
||||
wwcw = (cctCW<<8) | cctWW;
|
||||
if (_type == TYPE_WS2812_WWA) c = RGBW32(cctWW, cctCW, 0, W(c)); // may need swapping
|
||||
}
|
||||
|
||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, wwcw);
|
||||
}
|
||||
}
|
||||
@ -367,16 +363,24 @@ uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
|
||||
case 2: c = RGBW32(b, b, b, b); break;
|
||||
}
|
||||
}
|
||||
if (_type == TYPE_WS2812_WWA) {
|
||||
uint8_t w = R(c) | G(c);
|
||||
c = RGBW32(w, w, 0, w);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t BusDigital::getPins(uint8_t* pinArray) const {
|
||||
unsigned BusDigital::getPins(uint8_t* pinArray) const {
|
||||
unsigned numPins = is2Pin(_type) + 1;
|
||||
if (pinArray) for (unsigned i = 0; i < numPins; i++) pinArray[i] = _pins[i];
|
||||
return numPins;
|
||||
}
|
||||
|
||||
unsigned BusDigital::getBusSize() const {
|
||||
return sizeof(BusDigital) + (isOk() ? PolyBus::getDataSize(_busPtr, _iType) + (_data ? _len * getNumberOfChannels() : 0) : 0);
|
||||
}
|
||||
|
||||
void BusDigital::setColorOrder(uint8_t colorOrder) {
|
||||
// upper nibble contains W swap information
|
||||
if ((colorOrder & 0x0F) > 5) return;
|
||||
@ -399,8 +403,8 @@ std::vector<LEDType> BusDigital::getLEDTypes() {
|
||||
{TYPE_WS2805, "D", PSTR("WS2805 RGBCW")},
|
||||
{TYPE_SM16825, "D", PSTR("SM16825 RGBCW")},
|
||||
{TYPE_WS2812_1CH_X3, "D", PSTR("WS2811 White")},
|
||||
//{TYPE_WS2812_2CH_X3, "D", PSTR("WS2811 CCT")}, // not implemented
|
||||
//{TYPE_WS2812_WWA, "D", PSTR("WS2811 WWA")}, // not implemented
|
||||
//{TYPE_WS2812_2CH_X3, "D", PSTR("WS281x CCT")}, // not implemented
|
||||
{TYPE_WS2812_WWA, "D", PSTR("WS281x WWA")}, // amber ignored
|
||||
{TYPE_WS2801, "2P", PSTR("WS2801")},
|
||||
{TYPE_APA102, "2P", PSTR("APA102")},
|
||||
{TYPE_LPD8806, "2P", PSTR("LPD8806")},
|
||||
@ -415,12 +419,13 @@ void BusDigital::begin() {
|
||||
}
|
||||
|
||||
void BusDigital::cleanup() {
|
||||
DEBUG_PRINTLN(F("Digital Cleanup."));
|
||||
DEBUGBUS_PRINTLN(F("Digital Cleanup."));
|
||||
PolyBus::cleanup(_busPtr, _iType);
|
||||
_iType = I_NONE;
|
||||
_valid = false;
|
||||
_busPtr = nullptr;
|
||||
if (_data != nullptr) freeData();
|
||||
freeData();
|
||||
//PinManager::deallocateMultiplePins(_pins, 2, PinOwner::BusDigital);
|
||||
PinManager::deallocatePin(_pins[1], PinOwner::BusDigital);
|
||||
PinManager::deallocatePin(_pins[0], PinOwner::BusDigital);
|
||||
}
|
||||
@ -492,9 +497,9 @@ BusPwm::BusPwm(const BusConfig &bc)
|
||||
_hasRgb = hasRGB(bc.type);
|
||||
_hasWhite = hasWhite(bc.type);
|
||||
_hasCCT = hasCCT(bc.type);
|
||||
_data = _pwmdata; // avoid malloc() and use stack
|
||||
_data = _pwmdata; // avoid malloc() and use already allocated memory
|
||||
_valid = true;
|
||||
DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]);
|
||||
DEBUGBUS_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]);
|
||||
}
|
||||
|
||||
void BusPwm::setPixelColor(unsigned pix, uint32_t c) {
|
||||
@ -623,7 +628,7 @@ void BusPwm::show() {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t BusPwm::getPins(uint8_t* pinArray) const {
|
||||
unsigned BusPwm::getPins(uint8_t* pinArray) const {
|
||||
if (!_valid) return 0;
|
||||
unsigned numPins = numPWMPins(_type);
|
||||
if (pinArray) for (unsigned i = 0; i < numPins; i++) pinArray[i] = _pins[i];
|
||||
@ -676,7 +681,7 @@ BusOnOff::BusOnOff(const BusConfig &bc)
|
||||
_hasCCT = false;
|
||||
_data = &_onoffdata; // avoid malloc() and use stack
|
||||
_valid = true;
|
||||
DEBUG_PRINTF_P(PSTR("%successfully inited On/Off strip with pin %u\n"), _valid?"S":"Uns", _pin);
|
||||
DEBUGBUS_PRINTF_P(PSTR("%successfully inited On/Off strip with pin %u\n"), _valid?"S":"Uns", _pin);
|
||||
}
|
||||
|
||||
void BusOnOff::setPixelColor(unsigned pix, uint32_t c) {
|
||||
@ -699,7 +704,7 @@ void BusOnOff::show() {
|
||||
digitalWrite(_pin, _reversed ? !(bool)_data[0] : (bool)_data[0]);
|
||||
}
|
||||
|
||||
uint8_t BusOnOff::getPins(uint8_t* pinArray) const {
|
||||
unsigned BusOnOff::getPins(uint8_t* pinArray) const {
|
||||
if (!_valid) return 0;
|
||||
if (pinArray) pinArray[0] = _pin;
|
||||
return 1;
|
||||
@ -736,7 +741,7 @@ BusNetwork::BusNetwork(const BusConfig &bc)
|
||||
_UDPchannels = _hasWhite + 3;
|
||||
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
||||
_valid = (allocateData(_len * _UDPchannels) != nullptr);
|
||||
DEBUG_PRINTF_P(PSTR("%successfully inited virtual strip with type %u and IP %u.%u.%u.%u\n"), _valid?"S":"Uns", bc.type, bc.pins[0], bc.pins[1], bc.pins[2], bc.pins[3]);
|
||||
DEBUGBUS_PRINTF_P(PSTR("%successfully inited virtual strip with type %u and IP %u.%u.%u.%u\n"), _valid?"S":"Uns", bc.type, bc.pins[0], bc.pins[1], bc.pins[2], bc.pins[3]);
|
||||
}
|
||||
|
||||
void BusNetwork::setPixelColor(unsigned pix, uint32_t c) {
|
||||
@ -763,7 +768,7 @@ void BusNetwork::show() {
|
||||
_broadcastLock = false;
|
||||
}
|
||||
|
||||
uint8_t BusNetwork::getPins(uint8_t* pinArray) const {
|
||||
unsigned BusNetwork::getPins(uint8_t* pinArray) const {
|
||||
if (pinArray) for (unsigned i = 0; i < 4; i++) pinArray[i] = _client[i];
|
||||
return 4;
|
||||
}
|
||||
@ -784,6 +789,7 @@ std::vector<LEDType> BusNetwork::getLEDTypes() {
|
||||
}
|
||||
|
||||
void BusNetwork::cleanup() {
|
||||
DEBUGBUS_PRINTLN(F("Virtual Cleanup."));
|
||||
_type = I_NONE;
|
||||
_valid = false;
|
||||
freeData();
|
||||
@ -791,43 +797,66 @@ void BusNetwork::cleanup() {
|
||||
|
||||
|
||||
//utility to get the approx. memory usage of a given BusConfig
|
||||
uint32_t BusManager::memUsage(const BusConfig &bc) {
|
||||
if (Bus::isOnOff(bc.type) || Bus::isPWM(bc.type)) return OUTPUT_MAX_PINS;
|
||||
|
||||
unsigned len = bc.count + bc.skipAmount;
|
||||
unsigned channels = Bus::getNumberOfChannels(bc.type);
|
||||
unsigned multiplier = 1;
|
||||
if (Bus::isDigital(bc.type)) { // digital types
|
||||
if (Bus::is16bit(bc.type)) len *= 2; // 16-bit LEDs
|
||||
#ifdef ESP8266
|
||||
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
|
||||
multiplier = 5;
|
||||
}
|
||||
#else //ESP32 RMT uses double buffer, parallel I2S uses 8x buffer (3 times)
|
||||
multiplier = PolyBus::isParallelI2S1Output() ? 24 : 2;
|
||||
#endif
|
||||
unsigned BusConfig::memUsage(unsigned nr) const {
|
||||
if (Bus::isVirtual(type)) {
|
||||
return sizeof(BusNetwork) + (count * Bus::getNumberOfChannels(type));
|
||||
} else if (Bus::isDigital(type)) {
|
||||
return sizeof(BusDigital) + PolyBus::memUsage(count + skipAmount, PolyBus::getI(type, pins, nr)) + doubleBuffer * (count + skipAmount) * Bus::getNumberOfChannels(type);
|
||||
} else if (Bus::isOnOff(type)) {
|
||||
return sizeof(BusOnOff);
|
||||
} else {
|
||||
return sizeof(BusPwm);
|
||||
}
|
||||
return (len * multiplier + bc.doubleBuffer * (bc.count + bc.skipAmount)) * channels;
|
||||
}
|
||||
|
||||
uint32_t BusManager::memUsage(unsigned maxChannels, unsigned maxCount, unsigned minBuses) {
|
||||
//ESP32 RMT uses double buffer, parallel I2S uses 8x buffer (3 times)
|
||||
unsigned multiplier = PolyBus::isParallelI2S1Output() ? 3 : 2;
|
||||
return (maxChannels * maxCount * minBuses * multiplier);
|
||||
|
||||
unsigned BusManager::memUsage() {
|
||||
// when ESP32, S2 & S3 use parallel I2S only the largest bus determines the total memory requirements for back buffers
|
||||
// front buffers are always allocated per bus
|
||||
unsigned size = 0;
|
||||
unsigned maxI2S = 0;
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
|
||||
unsigned digitalCount = 0;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#define MAX_RMT 4
|
||||
#else
|
||||
#define MAX_RMT 8
|
||||
#endif
|
||||
#endif
|
||||
for (const auto &bus : busses) {
|
||||
unsigned busSize = bus->getBusSize();
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
|
||||
if (bus->isDigital() && !bus->is2Pin()) digitalCount++;
|
||||
if (PolyBus::isParallelI2S1Output() && digitalCount > MAX_RMT) {
|
||||
unsigned i2sCommonSize = 3 * bus->getLength() * bus->getNumberOfChannels() * (bus->is16bit()+1);
|
||||
if (i2sCommonSize > maxI2S) maxI2S = i2sCommonSize;
|
||||
busSize -= i2sCommonSize;
|
||||
}
|
||||
#endif
|
||||
size += busSize;
|
||||
}
|
||||
return size + maxI2S;
|
||||
}
|
||||
|
||||
int BusManager::add(const BusConfig &bc) {
|
||||
DEBUGBUS_PRINTF_P(PSTR("Bus: Adding bus (%d - %d >= %d)\n"), getNumBusses(), getNumVirtualBusses(), WLED_MAX_BUSSES);
|
||||
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
|
||||
unsigned numDigital = 0;
|
||||
for (const auto &bus : busses) if (bus->isDigital() && !bus->is2Pin()) numDigital++;
|
||||
if (Bus::isVirtual(bc.type)) {
|
||||
busses[numBusses] = new BusNetwork(bc);
|
||||
//busses.push_back(std::make_unique<BusNetwork>(bc)); // when C++ >11
|
||||
busses.push_back(new BusNetwork(bc));
|
||||
} else if (Bus::isDigital(bc.type)) {
|
||||
busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap);
|
||||
//busses.push_back(std::make_unique<BusDigital>(bc, numDigital, colorOrderMap));
|
||||
busses.push_back(new BusDigital(bc, numDigital, colorOrderMap));
|
||||
} else if (Bus::isOnOff(bc.type)) {
|
||||
busses[numBusses] = new BusOnOff(bc);
|
||||
//busses.push_back(std::make_unique<BusOnOff>(bc));
|
||||
busses.push_back(new BusOnOff(bc));
|
||||
} else {
|
||||
busses[numBusses] = new BusPwm(bc);
|
||||
//busses.push_back(std::make_unique<BusPwm>(bc));
|
||||
busses.push_back(new BusPwm(bc));
|
||||
}
|
||||
return numBusses++;
|
||||
return busses.size();
|
||||
}
|
||||
|
||||
// credit @willmmiles
|
||||
@ -856,18 +885,21 @@ String BusManager::getLEDTypesJSONString() {
|
||||
}
|
||||
|
||||
void BusManager::useParallelOutput() {
|
||||
_parallelOutputs = 8; // hardcoded since we use NPB I2S x8 methods
|
||||
DEBUGBUS_PRINTLN(F("Bus: Enabling parallel I2S."));
|
||||
PolyBus::setParallelI2S1Output();
|
||||
}
|
||||
|
||||
bool BusManager::hasParallelOutput() {
|
||||
return PolyBus::isParallelI2S1Output();
|
||||
}
|
||||
|
||||
//do not call this method from system context (network callback)
|
||||
void BusManager::removeAll() {
|
||||
DEBUG_PRINTLN(F("Removing all."));
|
||||
DEBUGBUS_PRINTLN(F("Removing all."));
|
||||
//prevents crashes due to deleting busses while in use.
|
||||
while (!canAllShow()) yield();
|
||||
for (unsigned i = 0; i < numBusses; i++) delete busses[i];
|
||||
numBusses = 0;
|
||||
_parallelOutputs = 1;
|
||||
for (auto &bus : busses) delete bus; // needed when not using std::unique_ptr C++ >11
|
||||
busses.clear();
|
||||
PolyBus::setParallelI2S1Output(false);
|
||||
}
|
||||
|
||||
@ -878,7 +910,9 @@ void BusManager::removeAll() {
|
||||
void BusManager::esp32RMTInvertIdle() {
|
||||
bool idle_out;
|
||||
unsigned rmt = 0;
|
||||
for (unsigned u = 0; u < numBusses(); u++) {
|
||||
unsigned u = 0;
|
||||
for (auto &bus : busses) {
|
||||
if (bus->getLength()==0 || !bus->isDigital() || bus->is2Pin()) continue;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, only has 1 I2S but NPB does not support it ATM
|
||||
if (u > 1) return;
|
||||
rmt = u;
|
||||
@ -889,11 +923,11 @@ void BusManager::esp32RMTInvertIdle() {
|
||||
if (u > 3) return;
|
||||
rmt = u;
|
||||
#else
|
||||
if (u < _parallelOutputs) continue;
|
||||
if (u >= _parallelOutputs + 8) return; // only 8 RMT channels
|
||||
rmt = u - _parallelOutputs;
|
||||
unsigned numI2S = !PolyBus::isParallelI2S1Output(); // if using parallel I2S, RMT is used 1st
|
||||
if (numI2S > u) continue;
|
||||
if (u > 7 + numI2S) return;
|
||||
rmt = u - numI2S;
|
||||
#endif
|
||||
if (busses[u]->getLength()==0 || !busses[u]->isDigital() || busses[u]->is2Pin()) continue;
|
||||
//assumes that bus number to rmt channel mapping stays 1:1
|
||||
rmt_channel_t ch = static_cast<rmt_channel_t>(rmt);
|
||||
rmt_idle_level_t lvl;
|
||||
@ -902,6 +936,7 @@ void BusManager::esp32RMTInvertIdle() {
|
||||
else if (lvl == RMT_IDLE_LEVEL_LOW) lvl = RMT_IDLE_LEVEL_HIGH;
|
||||
else continue;
|
||||
rmt_set_idle_level(ch, idle_out, lvl);
|
||||
u++
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -910,12 +945,12 @@ void BusManager::on() {
|
||||
#ifdef ESP8266
|
||||
//Fix for turning off onboard LED breaking bus
|
||||
if (PinManager::getPinOwner(LED_BUILTIN) == PinOwner::BusDigital) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
for (auto &bus : busses) {
|
||||
uint8_t pins[2] = {255,255};
|
||||
if (busses[i]->isDigital() && busses[i]->getPins(pins)) {
|
||||
if (bus->isDigital() && bus->getPins(pins)) {
|
||||
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
|
||||
BusDigital *bus = static_cast<BusDigital*>(busses[i]);
|
||||
bus->begin();
|
||||
BusDigital *b = static_cast<BusDigital*>(bus);
|
||||
b->begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -932,7 +967,7 @@ void BusManager::off() {
|
||||
// turn off built-in LED if strip is turned off
|
||||
// this will break digital bus so will need to be re-initialised on On
|
||||
if (PinManager::getPinOwner(LED_BUILTIN) == PinOwner::BusDigital) {
|
||||
for (unsigned i = 0; i < numBusses; i++) if (busses[i]->isOffRefreshRequired()) return;
|
||||
for (const auto &bus : busses) if (bus->isOffRefreshRequired()) return;
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
}
|
||||
@ -944,30 +979,26 @@ void BusManager::off() {
|
||||
|
||||
void BusManager::show() {
|
||||
_milliAmpsUsed = 0;
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->show();
|
||||
_milliAmpsUsed += busses[i]->getUsedCurrent();
|
||||
for (auto &bus : busses) {
|
||||
bus->show();
|
||||
_milliAmpsUsed += bus->getUsedCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void BusManager::setStatusPixel(uint32_t c) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->setStatusPixel(c);
|
||||
}
|
||||
for (auto &bus : busses) bus->setStatusPixel(c);
|
||||
}
|
||||
|
||||
void IRAM_ATTR BusManager::setPixelColor(unsigned pix, uint32_t c) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
unsigned bstart = busses[i]->getStart();
|
||||
if (pix < bstart || pix >= bstart + busses[i]->getLength()) continue;
|
||||
busses[i]->setPixelColor(pix - bstart, c);
|
||||
for (auto &bus : busses) {
|
||||
unsigned bstart = bus->getStart();
|
||||
if (pix < bstart || pix >= bstart + bus->getLength()) continue;
|
||||
bus->setPixelColor(pix - bstart, c);
|
||||
}
|
||||
}
|
||||
|
||||
void BusManager::setBrightness(uint8_t b) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->setBrightness(b);
|
||||
}
|
||||
for (auto &bus : busses) bus->setBrightness(b);
|
||||
}
|
||||
|
||||
void BusManager::setSegmentCCT(int16_t cct, bool allowWBCorrection) {
|
||||
@ -980,34 +1011,32 @@ void BusManager::setSegmentCCT(int16_t cct, bool allowWBCorrection) {
|
||||
}
|
||||
|
||||
uint32_t BusManager::getPixelColor(unsigned pix) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
unsigned bstart = busses[i]->getStart();
|
||||
if (!busses[i]->containsPixel(pix)) continue;
|
||||
return busses[i]->getPixelColor(pix - bstart);
|
||||
for (auto &bus : busses) {
|
||||
unsigned bstart = bus->getStart();
|
||||
if (!bus->containsPixel(pix)) continue;
|
||||
return bus->getPixelColor(pix - bstart);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BusManager::canAllShow() {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
if (!busses[i]->canShow()) return false;
|
||||
}
|
||||
for (const auto &bus : busses) if (!bus->canShow()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Bus* BusManager::getBus(uint8_t busNr) {
|
||||
if (busNr >= numBusses) return nullptr;
|
||||
if (busNr >= busses.size()) return nullptr;
|
||||
return busses[busNr];
|
||||
}
|
||||
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
uint16_t BusManager::getTotalLength() {
|
||||
unsigned len = 0;
|
||||
for (unsigned i=0; i<numBusses; i++) len += busses[i]->getLength();
|
||||
for (const auto &bus : busses) len += bus->getLength();
|
||||
return len;
|
||||
}
|
||||
|
||||
bool PolyBus::useParallelI2S = false;
|
||||
bool PolyBus::_useParallelI2S = false;
|
||||
|
||||
// Bus static member definition
|
||||
int16_t Bus::_cct = -1;
|
||||
@ -1016,9 +1045,8 @@ uint8_t Bus::_gAWM = 255;
|
||||
|
||||
uint16_t BusDigital::_milliAmpsTotal = 0;
|
||||
|
||||
uint8_t BusManager::numBusses = 0;
|
||||
Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
//std::vector<std::unique_ptr<Bus>> BusManager::busses;
|
||||
std::vector<Bus*> BusManager::busses;
|
||||
ColorOrderMap BusManager::colorOrderMap = {};
|
||||
uint16_t BusManager::_milliAmpsUsed = 0;
|
||||
uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
uint8_t BusManager::_parallelOutputs = 1;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef BusManager_h
|
||||
#define BusManager_h
|
||||
|
||||
@ -8,6 +9,30 @@
|
||||
#include "const.h"
|
||||
#include "pin_manager.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
// enable additional debug output
|
||||
#if defined(WLED_DEBUG_HOST)
|
||||
#include "net_debug.h"
|
||||
#define DEBUGOUT NetDebug
|
||||
#else
|
||||
#define DEBUGOUT Serial
|
||||
#endif
|
||||
|
||||
#ifdef WLED_DEBUG_BUS
|
||||
#ifndef ESP8266
|
||||
#include <rom/rtc.h>
|
||||
#endif
|
||||
#define DEBUGBUS_PRINT(x) DEBUGOUT.print(x)
|
||||
#define DEBUGBUS_PRINTLN(x) DEBUGOUT.println(x)
|
||||
#define DEBUGBUS_PRINTF(x...) DEBUGOUT.printf(x)
|
||||
#define DEBUGBUS_PRINTF_P(x...) DEBUGOUT.printf_P(x)
|
||||
#else
|
||||
#define DEBUGBUS_PRINT(x)
|
||||
#define DEBUGBUS_PRINTLN(x)
|
||||
#define DEBUGBUS_PRINTF(x...)
|
||||
#define DEBUGBUS_PRINTF_P(x...)
|
||||
#endif
|
||||
|
||||
//colors.cpp
|
||||
uint16_t approximateKelvinFromRGB(uint32_t rgb);
|
||||
@ -78,50 +103,51 @@ class Bus {
|
||||
_autoWhiteMode = Bus::hasWhite(type) ? aw : RGBW_MODE_MANUAL_ONLY;
|
||||
};
|
||||
|
||||
virtual ~Bus() {} //throw the bus under the bus
|
||||
virtual ~Bus() {} //throw the bus under the bus (derived class needs to freeData())
|
||||
|
||||
virtual void begin() {};
|
||||
virtual void begin() {};
|
||||
virtual void show() = 0;
|
||||
virtual bool canShow() const { return true; }
|
||||
virtual void setStatusPixel(uint32_t c) {}
|
||||
virtual bool canShow() const { return true; }
|
||||
virtual void setStatusPixel(uint32_t c) {}
|
||||
virtual void setPixelColor(unsigned pix, uint32_t c) = 0;
|
||||
virtual void setBrightness(uint8_t b) { _bri = b; };
|
||||
virtual void setColorOrder(uint8_t co) {}
|
||||
virtual uint32_t getPixelColor(unsigned pix) const { return 0; }
|
||||
virtual uint8_t getPins(uint8_t* pinArray = nullptr) const { return 0; }
|
||||
virtual uint16_t getLength() const { return isOk() ? _len : 0; }
|
||||
virtual uint8_t getColorOrder() const { return COL_ORDER_RGB; }
|
||||
virtual uint8_t skippedLeds() const { return 0; }
|
||||
virtual uint16_t getFrequency() const { return 0U; }
|
||||
virtual uint16_t getLEDCurrent() const { return 0; }
|
||||
virtual uint16_t getUsedCurrent() const { return 0; }
|
||||
virtual uint16_t getMaxCurrent() const { return 0; }
|
||||
virtual void setBrightness(uint8_t b) { _bri = b; };
|
||||
virtual void setColorOrder(uint8_t co) {}
|
||||
virtual uint32_t getPixelColor(unsigned pix) const { return 0; }
|
||||
virtual unsigned getPins(uint8_t* pinArray = nullptr) const { return 0; }
|
||||
virtual uint16_t getLength() const { return isOk() ? _len : 0; }
|
||||
virtual uint8_t getColorOrder() const { return COL_ORDER_RGB; }
|
||||
virtual unsigned skippedLeds() const { return 0; }
|
||||
virtual uint16_t getFrequency() const { return 0U; }
|
||||
virtual uint16_t getLEDCurrent() const { return 0; }
|
||||
virtual uint16_t getUsedCurrent() const { return 0; }
|
||||
virtual uint16_t getMaxCurrent() const { return 0; }
|
||||
virtual unsigned getBusSize() const { return sizeof(Bus); }
|
||||
|
||||
inline bool hasRGB() const { return _hasRgb; }
|
||||
inline bool hasWhite() const { return _hasWhite; }
|
||||
inline bool hasCCT() const { return _hasCCT; }
|
||||
inline bool isDigital() const { return isDigital(_type); }
|
||||
inline bool is2Pin() const { return is2Pin(_type); }
|
||||
inline bool isOnOff() const { return isOnOff(_type); }
|
||||
inline bool isPWM() const { return isPWM(_type); }
|
||||
inline bool isVirtual() const { return isVirtual(_type); }
|
||||
inline bool is16bit() const { return is16bit(_type); }
|
||||
inline bool mustRefresh() const { return mustRefresh(_type); }
|
||||
inline void setReversed(bool reversed) { _reversed = reversed; }
|
||||
inline void setStart(uint16_t start) { _start = start; }
|
||||
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
||||
inline uint8_t getAutoWhiteMode() const { return _autoWhiteMode; }
|
||||
inline uint32_t getNumberOfChannels() const { return hasWhite() + 3*hasRGB() + hasCCT(); }
|
||||
inline uint16_t getStart() const { return _start; }
|
||||
inline uint8_t getType() const { return _type; }
|
||||
inline bool isOk() const { return _valid; }
|
||||
inline bool isReversed() const { return _reversed; }
|
||||
inline bool isOffRefreshRequired() const { return _needsRefresh; }
|
||||
inline bool containsPixel(uint16_t pix) const { return pix >= _start && pix < _start + _len; }
|
||||
inline bool hasRGB() const { return _hasRgb; }
|
||||
inline bool hasWhite() const { return _hasWhite; }
|
||||
inline bool hasCCT() const { return _hasCCT; }
|
||||
inline bool isDigital() const { return isDigital(_type); }
|
||||
inline bool is2Pin() const { return is2Pin(_type); }
|
||||
inline bool isOnOff() const { return isOnOff(_type); }
|
||||
inline bool isPWM() const { return isPWM(_type); }
|
||||
inline bool isVirtual() const { return isVirtual(_type); }
|
||||
inline bool is16bit() const { return is16bit(_type); }
|
||||
inline bool mustRefresh() const { return mustRefresh(_type); }
|
||||
inline void setReversed(bool reversed) { _reversed = reversed; }
|
||||
inline void setStart(uint16_t start) { _start = start; }
|
||||
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
||||
inline uint8_t getAutoWhiteMode() const { return _autoWhiteMode; }
|
||||
inline unsigned getNumberOfChannels() const { return hasWhite() + 3*hasRGB() + hasCCT(); }
|
||||
inline uint16_t getStart() const { return _start; }
|
||||
inline uint8_t getType() const { return _type; }
|
||||
inline bool isOk() const { return _valid; }
|
||||
inline bool isReversed() const { return _reversed; }
|
||||
inline bool isOffRefreshRequired() const { return _needsRefresh; }
|
||||
inline bool containsPixel(uint16_t pix) const { return pix >= _start && pix < _start + _len; }
|
||||
|
||||
static inline std::vector<LEDType> getLEDTypes() { return {{TYPE_NONE, "", PSTR("None")}}; } // not used. just for reference for derived classes
|
||||
static constexpr uint32_t getNumberOfPins(uint8_t type) { return isVirtual(type) ? 4 : isPWM(type) ? numPWMPins(type) : is2Pin(type) + 1; } // credit @PaoloTK
|
||||
static constexpr uint32_t getNumberOfChannels(uint8_t type) { return hasWhite(type) + 3*hasRGB(type) + hasCCT(type); }
|
||||
static inline std::vector<LEDType> getLEDTypes() { return {{TYPE_NONE, "", PSTR("None")}}; } // not used. just for reference for derived classes
|
||||
static constexpr unsigned getNumberOfPins(uint8_t type) { return isVirtual(type) ? 4 : isPWM(type) ? numPWMPins(type) : is2Pin(type) + 1; } // credit @PaoloTK
|
||||
static constexpr unsigned getNumberOfChannels(uint8_t type) { return hasWhite(type) + 3*hasRGB(type) + hasCCT(type); }
|
||||
static constexpr bool hasRGB(uint8_t type) {
|
||||
return !((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_ANALOG_1CH || type == TYPE_ANALOG_2CH || type == TYPE_ONOFF);
|
||||
}
|
||||
@ -153,7 +179,7 @@ class Bus {
|
||||
static inline uint8_t getGlobalAWMode() { return _gAWM; }
|
||||
static inline void setCCT(int16_t cct) { _cct = cct; }
|
||||
static inline uint8_t getCCTBlend() { return _cctBlend; }
|
||||
static inline void setCCTBlend(uint8_t b) {
|
||||
static inline void setCCTBlend(uint8_t b) {
|
||||
_cctBlend = (std::min((int)b,100) * 127) / 100;
|
||||
//compile-time limiter for hardware that can't power both white channels at max
|
||||
#ifdef WLED_MAX_CCT_BLEND
|
||||
@ -192,7 +218,7 @@ class Bus {
|
||||
|
||||
uint32_t autoWhiteCalc(uint32_t c) const;
|
||||
uint8_t *allocateData(size_t size = 1);
|
||||
void freeData() { if (_data != nullptr) free(_data); _data = nullptr; }
|
||||
void freeData();
|
||||
};
|
||||
|
||||
|
||||
@ -209,12 +235,13 @@ class BusDigital : public Bus {
|
||||
void setColorOrder(uint8_t colorOrder) override;
|
||||
[[gnu::hot]] uint32_t getPixelColor(unsigned pix) const override;
|
||||
uint8_t getColorOrder() const override { return _colorOrder; }
|
||||
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
|
||||
uint8_t skippedLeds() const override { return _skip; }
|
||||
unsigned getPins(uint8_t* pinArray = nullptr) const override;
|
||||
unsigned skippedLeds() const override { return _skip; }
|
||||
uint16_t getFrequency() const override { return _frequencykHz; }
|
||||
uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; }
|
||||
uint16_t getUsedCurrent() const override { return _milliAmpsTotal; }
|
||||
uint16_t getMaxCurrent() const override { return _milliAmpsMax; }
|
||||
unsigned getBusSize() const override;
|
||||
void begin() override;
|
||||
void cleanup();
|
||||
|
||||
@ -244,7 +271,7 @@ class BusDigital : public Bus {
|
||||
return c;
|
||||
}
|
||||
|
||||
uint8_t estimateCurrentAndLimitBri();
|
||||
uint8_t estimateCurrentAndLimitBri() const;
|
||||
};
|
||||
|
||||
|
||||
@ -255,10 +282,11 @@ class BusPwm : public Bus {
|
||||
|
||||
void setPixelColor(unsigned pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(unsigned pix) const override; //does no index check
|
||||
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
|
||||
unsigned getPins(uint8_t* pinArray = nullptr) const override;
|
||||
uint16_t getFrequency() const override { return _frequency; }
|
||||
unsigned getBusSize() const override { return sizeof(BusPwm); }
|
||||
void show() override;
|
||||
void cleanup() { deallocatePins(); }
|
||||
inline void cleanup() { deallocatePins(); _data = nullptr; }
|
||||
|
||||
static std::vector<LEDType> getLEDTypes();
|
||||
|
||||
@ -282,9 +310,10 @@ class BusOnOff : public Bus {
|
||||
|
||||
void setPixelColor(unsigned pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(unsigned pix) const override;
|
||||
uint8_t getPins(uint8_t* pinArray) const override;
|
||||
unsigned getPins(uint8_t* pinArray) const override;
|
||||
unsigned getBusSize() const override { return sizeof(BusOnOff); }
|
||||
void show() override;
|
||||
void cleanup() { PinManager::deallocatePin(_pin, PinOwner::BusOnOff); }
|
||||
inline void cleanup() { PinManager::deallocatePin(_pin, PinOwner::BusOnOff); _data = nullptr; }
|
||||
|
||||
static std::vector<LEDType> getLEDTypes();
|
||||
|
||||
@ -300,9 +329,10 @@ class BusNetwork : public Bus {
|
||||
~BusNetwork() { cleanup(); }
|
||||
|
||||
bool canShow() const override { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out
|
||||
void setPixelColor(unsigned pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(unsigned pix) const override;
|
||||
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
|
||||
[[gnu::hot]] void setPixelColor(unsigned pix, uint32_t c) override;
|
||||
[[gnu::hot]] uint32_t getPixelColor(unsigned pix) const override;
|
||||
unsigned getPins(uint8_t* pinArray = nullptr) const override;
|
||||
unsigned getBusSize() const override { return sizeof(BusNetwork) + (isOk() ? _len * _UDPchannels : 0); }
|
||||
void show() override;
|
||||
void cleanup();
|
||||
|
||||
@ -348,6 +378,16 @@ struct BusConfig {
|
||||
type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh)
|
||||
size_t nPins = Bus::getNumberOfPins(type);
|
||||
for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
||||
DEBUGBUS_PRINTF_P(PSTR("Bus: Config (%d-%d, type:%d, CO:%d, rev:%d, skip:%d, AW:%d kHz:%d, mA:%d/%d)\n"),
|
||||
(int)start, (int)(start+len),
|
||||
(int)type,
|
||||
(int)colorOrder,
|
||||
(int)reversed,
|
||||
(int)skipAmount,
|
||||
(int)autoWhite,
|
||||
(int)frequency,
|
||||
(int)milliAmpsPerLed, (int)milliAmpsMax
|
||||
);
|
||||
}
|
||||
|
||||
//validates start and length and extends total if needed
|
||||
@ -361,6 +401,8 @@ struct BusConfig {
|
||||
if (start + count > total) total = start + count;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned memUsage(unsigned nr = 0) const;
|
||||
};
|
||||
|
||||
|
||||
@ -378,14 +420,13 @@ class BusManager {
|
||||
public:
|
||||
BusManager() {};
|
||||
|
||||
//utility to get the approx. memory usage of a given BusConfig
|
||||
static uint32_t memUsage(const BusConfig &bc);
|
||||
static uint32_t memUsage(unsigned channels, unsigned count, unsigned buses = 1);
|
||||
static unsigned memUsage();
|
||||
static uint16_t currentMilliamps() { return _milliAmpsUsed + MA_FOR_ESP; }
|
||||
static uint16_t ablMilliampsMax() { return _milliAmpsMax; }
|
||||
|
||||
static int add(const BusConfig &bc);
|
||||
static void useParallelOutput(); // workaround for inaccessible PolyBus
|
||||
static bool hasParallelOutput(); // workaround for inaccessible PolyBus
|
||||
|
||||
//do not call this method from system context (network callback)
|
||||
static void removeAll();
|
||||
@ -409,25 +450,24 @@ class BusManager {
|
||||
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
static uint16_t getTotalLength();
|
||||
static inline uint8_t getNumBusses() { return numBusses; }
|
||||
static inline uint8_t getNumBusses() { return busses.size(); }
|
||||
static String getLEDTypesJSONString();
|
||||
|
||||
static inline ColorOrderMap& getColorOrderMap() { return colorOrderMap; }
|
||||
|
||||
private:
|
||||
static uint8_t numBusses;
|
||||
static Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
//static std::vector<std::unique_ptr<Bus>> busses; // we'd need C++ >11
|
||||
static std::vector<Bus*> busses;
|
||||
static ColorOrderMap colorOrderMap;
|
||||
static uint16_t _milliAmpsUsed;
|
||||
static uint16_t _milliAmpsMax;
|
||||
static uint8_t _parallelOutputs;
|
||||
|
||||
#ifdef ESP32_DATA_IDLE_HIGH
|
||||
static void esp32RMTInvertIdle() ;
|
||||
#endif
|
||||
static uint8_t getNumVirtualBusses() {
|
||||
int j = 0;
|
||||
for (int i=0; i<numBusses; i++) if (busses[i]->isVirtual()) j++;
|
||||
for (const auto &bus : busses) j += bus->isVirtual();
|
||||
return j;
|
||||
}
|
||||
};
|
||||
|
@ -1,23 +1,9 @@
|
||||
#pragma once
|
||||
#ifndef BusWrapper_h
|
||||
#define BusWrapper_h
|
||||
|
||||
//#define NPB_CONF_4STEP_CADENCE
|
||||
#include "NeoPixelBusLg.h"
|
||||
#include "bus_manager.h"
|
||||
|
||||
// temporary - these defines should actually be set in platformio.ini
|
||||
// C3: I2S0 and I2S1 methods not supported (has one I2S bus)
|
||||
// S2: I2S1 methods not supported (has one I2S bus)
|
||||
// S3: I2S0 and I2S1 methods not supported yet (has two I2S buses)
|
||||
// https://github.com/Makuna/NeoPixelBus/blob/b32f719e95ef3c35c46da5c99538017ef925c026/src/internal/Esp32_i2s.h#L4
|
||||
// https://github.com/Makuna/NeoPixelBus/blob/b32f719e95ef3c35c46da5c99538017ef925c026/src/internal/NeoEsp32RmtMethod.h#L857
|
||||
|
||||
#if !defined(WLED_NO_I2S0_PIXELBUS) && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
|
||||
#define WLED_NO_I2S0_PIXELBUS
|
||||
#endif
|
||||
#if !defined(WLED_NO_I2S1_PIXELBUS) && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2))
|
||||
#define WLED_NO_I2S1_PIXELBUS
|
||||
#endif
|
||||
// temporary end
|
||||
|
||||
//Hardware SPI Pins
|
||||
#define P_8266_HS_MOSI 13
|
||||
@ -55,110 +41,98 @@
|
||||
#define I_8266_DM_TM2_3 19
|
||||
#define I_8266_BB_TM2_3 20
|
||||
//UCS8903 (RGB)
|
||||
#define I_8266_U0_UCS_3 49
|
||||
#define I_8266_U1_UCS_3 50
|
||||
#define I_8266_DM_UCS_3 51
|
||||
#define I_8266_BB_UCS_3 52
|
||||
#define I_8266_U0_UCS_3 21
|
||||
#define I_8266_U1_UCS_3 22
|
||||
#define I_8266_DM_UCS_3 23
|
||||
#define I_8266_BB_UCS_3 24
|
||||
//UCS8904 (RGBW)
|
||||
#define I_8266_U0_UCS_4 53
|
||||
#define I_8266_U1_UCS_4 54
|
||||
#define I_8266_DM_UCS_4 55
|
||||
#define I_8266_BB_UCS_4 56
|
||||
#define I_8266_U0_UCS_4 25
|
||||
#define I_8266_U1_UCS_4 26
|
||||
#define I_8266_DM_UCS_4 27
|
||||
#define I_8266_BB_UCS_4 28
|
||||
//FW1906 GRBCW
|
||||
#define I_8266_U0_FW6_5 66
|
||||
#define I_8266_U1_FW6_5 67
|
||||
#define I_8266_DM_FW6_5 68
|
||||
#define I_8266_BB_FW6_5 69
|
||||
#define I_8266_U0_FW6_5 29
|
||||
#define I_8266_U1_FW6_5 30
|
||||
#define I_8266_DM_FW6_5 31
|
||||
#define I_8266_BB_FW6_5 32
|
||||
//ESP8266 APA106
|
||||
#define I_8266_U0_APA106_3 81
|
||||
#define I_8266_U1_APA106_3 82
|
||||
#define I_8266_DM_APA106_3 83
|
||||
#define I_8266_BB_APA106_3 84
|
||||
#define I_8266_U0_APA106_3 33
|
||||
#define I_8266_U1_APA106_3 34
|
||||
#define I_8266_DM_APA106_3 35
|
||||
#define I_8266_BB_APA106_3 36
|
||||
//WS2805 (RGBCW)
|
||||
#define I_8266_U0_2805_5 89
|
||||
#define I_8266_U1_2805_5 90
|
||||
#define I_8266_DM_2805_5 91
|
||||
#define I_8266_BB_2805_5 92
|
||||
#define I_8266_U0_2805_5 37
|
||||
#define I_8266_U1_2805_5 38
|
||||
#define I_8266_DM_2805_5 39
|
||||
#define I_8266_BB_2805_5 40
|
||||
//TM1914 (RGB)
|
||||
#define I_8266_U0_TM1914_3 99
|
||||
#define I_8266_U1_TM1914_3 100
|
||||
#define I_8266_DM_TM1914_3 101
|
||||
#define I_8266_BB_TM1914_3 102
|
||||
#define I_8266_U0_TM1914_3 41
|
||||
#define I_8266_U1_TM1914_3 42
|
||||
#define I_8266_DM_TM1914_3 43
|
||||
#define I_8266_BB_TM1914_3 44
|
||||
//SM16825 (RGBCW)
|
||||
#define I_8266_U0_SM16825_5 103
|
||||
#define I_8266_U1_SM16825_5 104
|
||||
#define I_8266_DM_SM16825_5 105
|
||||
#define I_8266_BB_SM16825_5 106
|
||||
#define I_8266_U0_SM16825_5 45
|
||||
#define I_8266_U1_SM16825_5 46
|
||||
#define I_8266_DM_SM16825_5 47
|
||||
#define I_8266_BB_SM16825_5 48
|
||||
|
||||
/*** ESP32 Neopixel methods ***/
|
||||
//RGB
|
||||
#define I_32_RN_NEO_3 21
|
||||
#define I_32_I0_NEO_3 22
|
||||
#define I_32_I1_NEO_3 23
|
||||
#define I_32_RN_NEO_3 1
|
||||
#define I_32_I2_NEO_3 2
|
||||
//RGBW
|
||||
#define I_32_RN_NEO_4 25
|
||||
#define I_32_I0_NEO_4 26
|
||||
#define I_32_I1_NEO_4 27
|
||||
#define I_32_RN_NEO_4 5
|
||||
#define I_32_I2_NEO_4 6
|
||||
//400Kbps
|
||||
#define I_32_RN_400_3 29
|
||||
#define I_32_I0_400_3 30
|
||||
#define I_32_I1_400_3 31
|
||||
#define I_32_RN_400_3 9
|
||||
#define I_32_I2_400_3 10
|
||||
//TM1814 (RGBW)
|
||||
#define I_32_RN_TM1_4 33
|
||||
#define I_32_I0_TM1_4 34
|
||||
#define I_32_I1_TM1_4 35
|
||||
#define I_32_RN_TM1_4 13
|
||||
#define I_32_I2_TM1_4 14
|
||||
//TM1829 (RGB)
|
||||
#define I_32_RN_TM2_3 36
|
||||
#define I_32_I0_TM2_3 37
|
||||
#define I_32_I1_TM2_3 38
|
||||
#define I_32_RN_TM2_3 17
|
||||
#define I_32_I2_TM2_3 18
|
||||
//UCS8903 (RGB)
|
||||
#define I_32_RN_UCS_3 57
|
||||
#define I_32_I0_UCS_3 58
|
||||
#define I_32_I1_UCS_3 59
|
||||
#define I_32_RN_UCS_3 21
|
||||
#define I_32_I2_UCS_3 22
|
||||
//UCS8904 (RGBW)
|
||||
#define I_32_RN_UCS_4 60
|
||||
#define I_32_I0_UCS_4 61
|
||||
#define I_32_I1_UCS_4 62
|
||||
#define I_32_RN_UCS_4 25
|
||||
#define I_32_I2_UCS_4 26
|
||||
//FW1906 GRBCW
|
||||
#define I_32_RN_FW6_5 63
|
||||
#define I_32_I0_FW6_5 64
|
||||
#define I_32_I1_FW6_5 65
|
||||
#define I_32_RN_FW6_5 29
|
||||
#define I_32_I2_FW6_5 30
|
||||
//APA106
|
||||
#define I_32_RN_APA106_3 85
|
||||
#define I_32_I0_APA106_3 86
|
||||
#define I_32_I1_APA106_3 87
|
||||
#define I_32_RN_APA106_3 33
|
||||
#define I_32_I2_APA106_3 34
|
||||
//WS2805 (RGBCW)
|
||||
#define I_32_RN_2805_5 93
|
||||
#define I_32_I0_2805_5 94
|
||||
#define I_32_I1_2805_5 95
|
||||
#define I_32_RN_2805_5 37
|
||||
#define I_32_I2_2805_5 38
|
||||
//TM1914 (RGB)
|
||||
#define I_32_RN_TM1914_3 96
|
||||
#define I_32_I0_TM1914_3 97
|
||||
#define I_32_I1_TM1914_3 98
|
||||
#define I_32_RN_TM1914_3 41
|
||||
#define I_32_I2_TM1914_3 42
|
||||
//SM16825 (RGBCW)
|
||||
#define I_32_RN_SM16825_5 107
|
||||
#define I_32_I0_SM16825_5 108
|
||||
#define I_32_I1_SM16825_5 109
|
||||
#define I_32_RN_SM16825_5 45
|
||||
#define I_32_I2_SM16825_5 46
|
||||
|
||||
//APA102
|
||||
#define I_HS_DOT_3 39 //hardware SPI
|
||||
#define I_SS_DOT_3 40 //soft SPI
|
||||
#define I_HS_DOT_3 101 //hardware SPI
|
||||
#define I_SS_DOT_3 102 //soft SPI
|
||||
|
||||
//LPD8806
|
||||
#define I_HS_LPD_3 41
|
||||
#define I_SS_LPD_3 42
|
||||
#define I_HS_LPD_3 103
|
||||
#define I_SS_LPD_3 104
|
||||
|
||||
//WS2801
|
||||
#define I_HS_WS1_3 43
|
||||
#define I_SS_WS1_3 44
|
||||
#define I_HS_WS1_3 105
|
||||
#define I_SS_WS1_3 106
|
||||
|
||||
//P9813
|
||||
#define I_HS_P98_3 45
|
||||
#define I_SS_P98_3 46
|
||||
#define I_HS_P98_3 107
|
||||
#define I_SS_P98_3 108
|
||||
|
||||
//LPD6803
|
||||
#define I_HS_LPO_3 47
|
||||
#define I_SS_LPO_3 48
|
||||
#define I_HS_LPO_3 109
|
||||
#define I_SS_LPO_3 110
|
||||
|
||||
|
||||
// In the following NeoGammaNullMethod can be replaced with NeoGammaWLEDMethod to perform Gamma correction implicitly
|
||||
@ -230,66 +204,95 @@
|
||||
|
||||
/*** ESP32 Neopixel methods ***/
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// C3: I2S0 and I2S1 methods not supported (has one I2S bus)
|
||||
// S2: I2S0 methods supported (single & parallel), I2S1 methods not supported (has one I2S bus)
|
||||
// S3: I2S0 methods not supported, I2S1 supports LCD parallel methods (has two I2S buses)
|
||||
// https://github.com/Makuna/NeoPixelBus/blob/b32f719e95ef3c35c46da5c99538017ef925c026/src/internal/Esp32_i2s.h#L4
|
||||
// https://github.com/Makuna/NeoPixelBus/blob/b32f719e95ef3c35c46da5c99538017ef925c026/src/internal/NeoEsp32RmtMethod.h#L857
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
// S3 will always use LCD parallel output
|
||||
typedef X8Ws2812xMethod X1Ws2812xMethod;
|
||||
typedef X8Sk6812Method X1Sk6812Method;
|
||||
typedef X8400KbpsMethod X1400KbpsMethod;
|
||||
typedef X8800KbpsMethod X1800KbpsMethod;
|
||||
typedef X8Tm1814Method X1Tm1814Method;
|
||||
typedef X8Tm1829Method X1Tm1829Method;
|
||||
typedef X8Apa106Method X1Apa106Method;
|
||||
typedef X8Ws2805Method X1Ws2805Method;
|
||||
typedef X8Tm1914Method X1Tm1914Method;
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
// S2 will use I2S0
|
||||
typedef NeoEsp32I2s0Ws2812xMethod X1Ws2812xMethod;
|
||||
typedef NeoEsp32I2s0Sk6812Method X1Sk6812Method;
|
||||
typedef NeoEsp32I2s0400KbpsMethod X1400KbpsMethod;
|
||||
typedef NeoEsp32I2s0800KbpsMethod X1800KbpsMethod;
|
||||
typedef NeoEsp32I2s0Tm1814Method X1Tm1814Method;
|
||||
typedef NeoEsp32I2s0Tm1829Method X1Tm1829Method;
|
||||
typedef NeoEsp32I2s0Apa106Method X1Apa106Method;
|
||||
typedef NeoEsp32I2s0Ws2805Method X1Ws2805Method;
|
||||
typedef NeoEsp32I2s0Tm1914Method X1Tm1914Method;
|
||||
#elif !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
// regular ESP32 will use I2S1
|
||||
typedef NeoEsp32I2s1Ws2812xMethod X1Ws2812xMethod;
|
||||
typedef NeoEsp32I2s1Sk6812Method X1Sk6812Method;
|
||||
typedef NeoEsp32I2s1400KbpsMethod X1400KbpsMethod;
|
||||
typedef NeoEsp32I2s1800KbpsMethod X1800KbpsMethod;
|
||||
typedef NeoEsp32I2s1Tm1814Method X1Tm1814Method;
|
||||
typedef NeoEsp32I2s1Tm1829Method X1Tm1829Method;
|
||||
typedef NeoEsp32I2s1Apa106Method X1Apa106Method;
|
||||
typedef NeoEsp32I2s1Ws2805Method X1Ws2805Method;
|
||||
typedef NeoEsp32I2s1Tm1914Method X1Tm1914Method;
|
||||
#endif
|
||||
|
||||
//RGB
|
||||
#define B_32_RN_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0Ws2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1Ws2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_NEO_3P NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_RN_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod> // ESP32, S2, S3, C3
|
||||
//#define B_32_IN_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2sNWs2812xMethod, NeoGammaNullMethod> // ESP32 (dynamic I2S selection)
|
||||
#define B_32_I2_NEO_3 NeoPixelBusLg<NeoGrbFeature, X1Ws2812xMethod, NeoGammaNullMethod> // ESP32, S2, S3 (automatic I2S selection, see typedef above)
|
||||
#define B_32_IP_NEO_3 NeoPixelBusLg<NeoGrbFeature, X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S (ESP32, S2, S3)
|
||||
//RGBW
|
||||
#define B_32_RN_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32RmtNSk6812Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s0Sk6812Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s1Sk6812Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_NEO_4P NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s1X8Sk6812Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_NEO_4 NeoPixelBusLg<NeoGrbwFeature, X1Sk6812Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_NEO_4 NeoPixelBusLg<NeoGrbwFeature, X8Sk6812Method, NeoGammaNullMethod> // parallel I2S
|
||||
//400Kbps
|
||||
#define B_32_RN_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtN400KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0400KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1400KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_400_3P NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8400KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_400_3 NeoPixelBusLg<NeoGrbFeature, X1400KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_IP_400_3 NeoPixelBusLg<NeoGrbFeature, X8400KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
//TM1814 (RGBW)
|
||||
#define B_32_RN_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32RmtNTm1814Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s0Tm1814Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s1Tm1814Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM1_4P NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s1X8Tm1814Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, X1Tm1814Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, X8Tm1814Method, NeoGammaNullMethod> // parallel I2S
|
||||
//TM1829 (RGB)
|
||||
#define B_32_RN_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32RmtNTm1829Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s0Tm1829Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s1Tm1829Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM2_3P NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s1X8Tm1829Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_TM2_3 NeoPixelBusLg<NeoBrgFeature, X1Tm1829Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_TM2_3 NeoPixelBusLg<NeoBrgFeature, X8Tm1829Method, NeoGammaNullMethod> // parallel I2S
|
||||
//UCS8903
|
||||
#define B_32_RN_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_UCS_3P NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, X1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_IP_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
//UCS8904
|
||||
#define B_32_RN_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_UCS_4P NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod>// parallel I2S
|
||||
#define B_32_I2_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, X1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_IP_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, X8800KbpsMethod, NeoGammaNullMethod>// parallel I2S
|
||||
//APA106
|
||||
#define B_32_RN_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNApa106Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0Apa106Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1Apa106Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_APA106_3P NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8Apa106Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_APA106_3 NeoPixelBusLg<NeoGrbFeature, X1Apa106Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_APA106_3 NeoPixelBusLg<NeoGrbFeature, X8Apa106Method, NeoGammaNullMethod> // parallel I2S
|
||||
//FW1906 GRBCW
|
||||
#define B_32_RN_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_FW6_5P NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, X1800KbpsMethod, NeoGammaNullMethod>
|
||||
#define B_32_IP_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||
//WS2805 RGBWC
|
||||
#define B_32_RN_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32RmtNWs2805Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s0Ws2805Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s1Ws2805Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_2805_5P NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s1X8Ws2805Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_2805_5 NeoPixelBusLg<NeoGrbwwFeature, X1Ws2805Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_2805_5 NeoPixelBusLg<NeoGrbwwFeature, X8Ws2805Method, NeoGammaNullMethod> // parallel I2S
|
||||
//TM1914 (RGB)
|
||||
#define B_32_RN_TM1914_3 NeoPixelBusLg<NeoGrbTm1914Feature, NeoEsp32RmtNTm1914Method, NeoGammaNullMethod>
|
||||
#define B_32_I0_TM1914_3 NeoPixelBusLg<NeoGrbTm1914Feature, NeoEsp32I2s0Tm1914Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM1914_3 NeoPixelBusLg<NeoGrbTm1914Feature, NeoEsp32I2s1Tm1914Method, NeoGammaNullMethod>
|
||||
#define B_32_I1_TM1914_3P NeoPixelBusLg<NeoGrbTm1914Feature, NeoEsp32I2s1X8Tm1914Method, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_TM1914_3 NeoPixelBusLg<NeoGrbTm1914Feature, X1Tm1914Method, NeoGammaNullMethod>
|
||||
#define B_32_IP_TM1914_3 NeoPixelBusLg<NeoGrbTm1914Feature, X8Tm1914Method, NeoGammaNullMethod> // parallel I2S
|
||||
//Sm16825 (RGBWC)
|
||||
#define B_32_RN_SM16825_5 NeoPixelBusLg<NeoRgbcwSm16825eFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I0_SM16825_5 NeoPixelBusLg<NeoRgbcwSm16825eFeature, NeoEsp32I2s0Ws2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_SM16825_5 NeoPixelBusLg<NeoRgbcwSm16825eFeature, NeoEsp32I2s1Ws2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_I1_SM16825_5P NeoPixelBusLg<NeoRgbcwSm16825eFeature, NeoEsp32I2s1X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#define B_32_I2_SM16825_5 NeoPixelBusLg<NeoRgbcwSm16825eFeature, X1Ws2812xMethod, NeoGammaNullMethod>
|
||||
#define B_32_IP_SM16825_5 NeoPixelBusLg<NeoRgbcwSm16825eFeature, X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S
|
||||
#endif
|
||||
|
||||
//APA102
|
||||
@ -328,11 +331,11 @@
|
||||
//handles pointer type conversion for all possible bus types
|
||||
class PolyBus {
|
||||
private:
|
||||
static bool useParallelI2S;
|
||||
static bool _useParallelI2S;
|
||||
|
||||
public:
|
||||
static inline void setParallelI2S1Output(bool b = true) { useParallelI2S = b; }
|
||||
static inline bool isParallelI2S1Output(void) { return useParallelI2S; }
|
||||
static inline void setParallelI2S1Output(bool b = true) { _useParallelI2S = b; }
|
||||
static inline bool isParallelI2S1Output(void) { return _useParallelI2S; }
|
||||
|
||||
// initialize SPI bus speed for DotStar methods
|
||||
template <class T>
|
||||
@ -436,34 +439,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: beginTM1914<B_32_RN_TM1914_3*>(busPtr); break;
|
||||
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->Begin(); break;
|
||||
// I2S1 bus or parellel buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) (static_cast<B_32_I1_NEO_3P*>(busPtr))->Begin(); else (static_cast<B_32_I1_NEO_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) (static_cast<B_32_I1_NEO_4P*>(busPtr))->Begin(); else (static_cast<B_32_I1_NEO_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) (static_cast<B_32_I1_400_3P*>(busPtr))->Begin(); else (static_cast<B_32_I1_400_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) beginTM1814<B_32_I1_TM1_4P*>(busPtr); else beginTM1814<B_32_I1_TM1_4*>(busPtr); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) (static_cast<B_32_I1_TM2_3P*>(busPtr))->Begin(); else (static_cast<B_32_I1_TM2_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) (static_cast<B_32_I1_UCS_3P*>(busPtr))->Begin(); else (static_cast<B_32_I1_UCS_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) (static_cast<B_32_I1_UCS_4P*>(busPtr))->Begin(); else (static_cast<B_32_I1_UCS_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) (static_cast<B_32_I1_FW6_5P*>(busPtr))->Begin(); else (static_cast<B_32_I1_FW6_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) (static_cast<B_32_I1_APA106_3P*>(busPtr))->Begin(); else (static_cast<B_32_I1_APA106_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) (static_cast<B_32_I1_2805_5P*>(busPtr))->Begin(); else (static_cast<B_32_I1_2805_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) beginTM1914<B_32_I1_TM1914_3P*>(busPtr); else beginTM1914<B_32_I1_TM1914_3*>(busPtr); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->Begin(); else (static_cast<B_32_I1_SM16825_5*>(busPtr))->Begin(); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_TM1_4: beginTM1814<B_32_I0_TM1_4*>(busPtr); break;
|
||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I0_TM1914_3: beginTM1914<B_32_I0_TM1914_3*>(busPtr); break;
|
||||
case I_32_I0_SM16825_5: (static_cast<B_32_I0_SM16825_5*>(busPtr))->Begin(); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_NEO_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->Begin(); else (static_cast<B_32_I2_NEO_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_400_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) beginTM1814<B_32_IP_TM1_4*>(busPtr); else beginTM1814<B_32_I2_TM1_4*>(busPtr); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast<B_32_IP_TM2_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_TM2_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast<B_32_IP_UCS_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_UCS_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast<B_32_IP_UCS_4*>(busPtr))->Begin(); else (static_cast<B_32_I2_UCS_4*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) (static_cast<B_32_IP_FW6_5*>(busPtr))->Begin(); else (static_cast<B_32_I2_FW6_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast<B_32_IP_APA106_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_APA106_3*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) (static_cast<B_32_IP_2805_5*>(busPtr))->Begin(); else (static_cast<B_32_I2_2805_5*>(busPtr))->Begin(); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) beginTM1914<B_32_IP_TM1914_3*>(busPtr); else beginTM1914<B_32_I2_TM1914_3*>(busPtr); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) (static_cast<B_32_IP_SM16825_5*>(busPtr))->Begin(); else (static_cast<B_32_I2_SM16825_5*>(busPtr))->Begin(); break;
|
||||
#endif
|
||||
// ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin()
|
||||
case I_HS_DOT_3: beginDotStar<B_HS_DOT_3*>(busPtr, pins[1], -1, pins[0], -1, clock_kHz); break;
|
||||
@ -484,8 +472,8 @@ class PolyBus {
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
|
||||
// NOTE: "channel" is only used on ESP32 (and its variants) for RMT channel allocation
|
||||
// since 0.15.0-b3 I2S1 is favoured for classic ESP32 and moved to position 0 (channel 0) so we need to subtract 1 for correct RMT allocation
|
||||
if (useParallelI2S && channel > 7) channel -= 8; // accommodate parallel I2S1 which is used 1st on classic ESP32
|
||||
else if (channel > 0) channel--; // accommodate I2S1 which is used as 1st bus on classic ESP32
|
||||
if (!_useParallelI2S && channel > 0) channel--; // accommodate I2S1 which is used as 1st bus on classic ESP32
|
||||
// if user selected parallel I2S, RMT is used 1st (8 channels) followed by parallel I2S (8 channels)
|
||||
#endif
|
||||
void* busPtr = nullptr;
|
||||
switch (busType) {
|
||||
@ -555,34 +543,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: busPtr = new B_32_RN_TM1914_3(len, pins[0], (NeoBusChannel)channel); break;
|
||||
case I_32_RN_SM16825_5: busPtr = new B_32_RN_SM16825_5(len, pins[0], (NeoBusChannel)channel); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) busPtr = new B_32_I1_NEO_3P(len, pins[0]); else busPtr = new B_32_I1_NEO_3(len, pins[0]); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) busPtr = new B_32_I1_NEO_4P(len, pins[0]); else busPtr = new B_32_I1_NEO_4(len, pins[0]); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) busPtr = new B_32_I1_400_3P(len, pins[0]); else busPtr = new B_32_I1_400_3(len, pins[0]); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) busPtr = new B_32_I1_TM1_4P(len, pins[0]); else busPtr = new B_32_I1_TM1_4(len, pins[0]); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) busPtr = new B_32_I1_TM2_3P(len, pins[0]); else busPtr = new B_32_I1_TM2_3(len, pins[0]); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) busPtr = new B_32_I1_UCS_3P(len, pins[0]); else busPtr = new B_32_I1_UCS_3(len, pins[0]); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) busPtr = new B_32_I1_UCS_4P(len, pins[0]); else busPtr = new B_32_I1_UCS_4(len, pins[0]); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) busPtr = new B_32_I1_APA106_3P(len, pins[0]); else busPtr = new B_32_I1_APA106_3(len, pins[0]); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) busPtr = new B_32_I1_FW6_5P(len, pins[0]); else busPtr = new B_32_I1_FW6_5(len, pins[0]); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) busPtr = new B_32_I1_2805_5P(len, pins[0]); else busPtr = new B_32_I1_2805_5(len, pins[0]); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) busPtr = new B_32_I1_TM1914_3P(len, pins[0]); else busPtr = new B_32_I1_TM1914_3(len, pins[0]); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) busPtr = new B_32_I1_SM16825_5P(len, pins[0]); else busPtr = new B_32_I1_SM16825_5(len, pins[0]); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); break;
|
||||
case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break;
|
||||
case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break;
|
||||
case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); break;
|
||||
case I_32_I0_TM2_3: busPtr = new B_32_I0_TM2_3(len, pins[0]); break;
|
||||
case I_32_I0_UCS_3: busPtr = new B_32_I0_UCS_3(len, pins[0]); break;
|
||||
case I_32_I0_UCS_4: busPtr = new B_32_I0_UCS_4(len, pins[0]); break;
|
||||
case I_32_I0_APA106_3: busPtr = new B_32_I0_APA106_3(len, pins[0]); break;
|
||||
case I_32_I0_FW6_5: busPtr = new B_32_I0_FW6_5(len, pins[0]); break;
|
||||
case I_32_I0_2805_5: busPtr = new B_32_I0_2805_5(len, pins[0]); break;
|
||||
case I_32_I0_TM1914_3: busPtr = new B_32_I0_TM1914_3(len, pins[0]); break;
|
||||
case I_32_I0_SM16825_5: busPtr = new B_32_I0_SM16825_5(len, pins[0]); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) busPtr = new B_32_IP_NEO_3(len, pins[0]); else busPtr = new B_32_I2_NEO_3(len, pins[0]); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) busPtr = new B_32_IP_NEO_4(len, pins[0]); else busPtr = new B_32_I2_NEO_4(len, pins[0]); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) busPtr = new B_32_IP_400_3(len, pins[0]); else busPtr = new B_32_I2_400_3(len, pins[0]); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) busPtr = new B_32_IP_TM1_4(len, pins[0]); else busPtr = new B_32_I2_TM1_4(len, pins[0]); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) busPtr = new B_32_IP_TM2_3(len, pins[0]); else busPtr = new B_32_I2_TM2_3(len, pins[0]); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) busPtr = new B_32_IP_UCS_3(len, pins[0]); else busPtr = new B_32_I2_UCS_3(len, pins[0]); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) busPtr = new B_32_IP_UCS_4(len, pins[0]); else busPtr = new B_32_I2_UCS_4(len, pins[0]); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) busPtr = new B_32_IP_APA106_3(len, pins[0]); else busPtr = new B_32_I2_APA106_3(len, pins[0]); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) busPtr = new B_32_IP_FW6_5(len, pins[0]); else busPtr = new B_32_I2_FW6_5(len, pins[0]); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) busPtr = new B_32_IP_2805_5(len, pins[0]); else busPtr = new B_32_I2_2805_5(len, pins[0]); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) busPtr = new B_32_IP_TM1914_3(len, pins[0]); else busPtr = new B_32_I2_TM1914_3(len, pins[0]); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) busPtr = new B_32_IP_SM16825_5(len, pins[0]); else busPtr = new B_32_I2_SM16825_5(len, pins[0]); break;
|
||||
#endif
|
||||
#endif
|
||||
// for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat)
|
||||
@ -669,34 +642,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->Show(consistent); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) (static_cast<B_32_I1_NEO_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_NEO_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) (static_cast<B_32_I1_NEO_4P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_NEO_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) (static_cast<B_32_I1_400_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_400_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) (static_cast<B_32_I1_TM1_4P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_TM1_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) (static_cast<B_32_I1_TM2_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_TM2_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) (static_cast<B_32_I1_UCS_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_UCS_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) (static_cast<B_32_I1_UCS_4P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_UCS_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) (static_cast<B_32_I1_APA106_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_APA106_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) (static_cast<B_32_I1_FW6_5P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_FW6_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) (static_cast<B_32_I1_2805_5P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_2805_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) (static_cast<B_32_I1_TM1914_3P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_TM1914_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->Show(consistent); else (static_cast<B_32_I1_SM16825_5*>(busPtr))->Show(consistent); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_TM1914_3: (static_cast<B_32_I0_TM1914_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I0_SM16825_5: (static_cast<B_32_I0_SM16825_5*>(busPtr))->Show(consistent); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_NEO_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_NEO_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_400_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) (static_cast<B_32_IP_TM1_4*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_TM1_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast<B_32_IP_TM2_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_TM2_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast<B_32_IP_UCS_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_UCS_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast<B_32_IP_UCS_4*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_UCS_4*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast<B_32_IP_APA106_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_APA106_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) (static_cast<B_32_IP_FW6_5*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_FW6_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) (static_cast<B_32_IP_2805_5*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_2805_5*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) (static_cast<B_32_IP_TM1914_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_TM1914_3*>(busPtr))->Show(consistent); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) (static_cast<B_32_IP_SM16825_5*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_SM16825_5*>(busPtr))->Show(consistent); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Show(consistent); break;
|
||||
@ -743,6 +701,7 @@ class PolyBus {
|
||||
case I_8266_U0_UCS_4: return (static_cast<B_8266_U0_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_8266_U1_UCS_4: return (static_cast<B_8266_U1_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_8266_DM_UCS_4: return (static_cast<B_8266_DM_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_8266_BB_UCS_4: return (static_cast<B_8266_BB_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_8266_U0_APA106_3: return (static_cast<B_8266_U0_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_8266_U1_APA106_3: return (static_cast<B_8266_U1_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_8266_DM_APA106_3: return (static_cast<B_8266_DM_APA106_3*>(busPtr))->CanShow(); break;
|
||||
@ -779,34 +738,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: return (static_cast<B_32_RN_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_SM16825_5: return (static_cast<B_32_RN_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) return (static_cast<B_32_I1_NEO_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) return (static_cast<B_32_I1_NEO_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) return (static_cast<B_32_I1_400_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) return (static_cast<B_32_I1_TM1_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) return (static_cast<B_32_I1_TM2_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) return (static_cast<B_32_I1_UCS_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) return (static_cast<B_32_I1_UCS_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) return (static_cast<B_32_I1_APA106_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) return (static_cast<B_32_I1_FW6_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) return (static_cast<B_32_I1_2805_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) return (static_cast<B_32_I1_TM1914_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) return (static_cast<B_32_I1_SM16825_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: return (static_cast<B_32_I0_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_NEO_4: return (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_400_3: return (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1_4: return (static_cast<B_32_I0_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM2_3: return (static_cast<B_32_I0_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_3: return (static_cast<B_32_I0_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_4: return (static_cast<B_32_I0_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_APA106_3: return (static_cast<B_32_I0_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_FW6_5: return (static_cast<B_32_I0_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_2805_5: return (static_cast<B_32_I0_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1914_3: return (static_cast<B_32_I0_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_SM16825_5: return (static_cast<B_32_I0_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) return (static_cast<B_32_IP_NEO_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) return (static_cast<B_32_IP_NEO_4*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) return (static_cast<B_32_IP_400_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) return (static_cast<B_32_IP_TM1_4*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) return (static_cast<B_32_IP_TM2_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) return (static_cast<B_32_IP_UCS_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) return (static_cast<B_32_IP_UCS_4*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) return (static_cast<B_32_IP_APA106_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) return (static_cast<B_32_IP_FW6_5*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) return (static_cast<B_32_IP_2805_5*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) return (static_cast<B_32_IP_TM1914_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) return (static_cast<B_32_IP_SM16825_5*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
||||
@ -823,7 +767,7 @@ class PolyBus {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co, uint16_t wwcw = 0) {
|
||||
[[gnu::hot]] static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co, uint16_t wwcw = 0) {
|
||||
uint8_t r = c >> 16;
|
||||
uint8_t g = c >> 8;
|
||||
uint8_t b = c >> 0;
|
||||
@ -916,34 +860,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) (static_cast<B_32_I1_NEO_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) (static_cast<B_32_I1_NEO_4P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) (static_cast<B_32_I1_400_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) (static_cast<B_32_I1_TM1_4P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) (static_cast<B_32_I1_TM2_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) (static_cast<B_32_I1_UCS_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) (static_cast<B_32_I1_UCS_4P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) (static_cast<B_32_I1_APA106_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) (static_cast<B_32_I1_FW6_5P*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); else (static_cast<B_32_I1_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) (static_cast<B_32_I1_2805_5P*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); else (static_cast<B_32_I1_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) (static_cast<B_32_I1_TM1914_3P*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I1_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); else (static_cast<B_32_I1_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I0_TM1914_3: (static_cast<B_32_I0_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I0_SM16825_5: (static_cast<B_32_I0_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) (static_cast<B_32_IP_TM1_4*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast<B_32_IP_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast<B_32_IP_UCS_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast<B_32_IP_UCS_4*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast<B_32_IP_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) (static_cast<B_32_IP_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); else (static_cast<B_32_I2_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) (static_cast<B_32_IP_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); else (static_cast<B_32_I2_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) (static_cast<B_32_IP_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) (static_cast<B_32_IP_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); else (static_cast<B_32_I2_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||
@ -1027,34 +956,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->SetLuminance(b); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) (static_cast<B_32_I1_NEO_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) (static_cast<B_32_I1_NEO_4P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) (static_cast<B_32_I1_400_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_400_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) (static_cast<B_32_I1_TM1_4P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) (static_cast<B_32_I1_TM2_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) (static_cast<B_32_I1_UCS_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) (static_cast<B_32_I1_UCS_4P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) (static_cast<B_32_I1_APA106_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) (static_cast<B_32_I1_FW6_5P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) (static_cast<B_32_I1_2805_5P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) (static_cast<B_32_I1_TM1914_3P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_TM1914_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I1_SM16825_5*>(busPtr))->SetLuminance(b); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_TM1914_3: (static_cast<B_32_I0_TM1914_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I0_SM16825_5: (static_cast<B_32_I0_SM16825_5*>(busPtr))->SetLuminance(b); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_400_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) (static_cast<B_32_IP_TM1_4*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast<B_32_IP_TM2_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast<B_32_IP_UCS_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast<B_32_IP_UCS_4*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast<B_32_IP_APA106_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) (static_cast<B_32_IP_FW6_5*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) (static_cast<B_32_IP_2805_5*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) (static_cast<B_32_IP_TM1914_3*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_TM1914_3*>(busPtr))->SetLuminance(b); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) (static_cast<B_32_IP_SM16825_5*>(busPtr))->SetLuminance(b); else (static_cast<B_32_I2_SM16825_5*>(busPtr))->SetLuminance(b); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetLuminance(b); break;
|
||||
@ -1070,7 +984,7 @@ class PolyBus {
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) {
|
||||
[[gnu::hot]] static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) {
|
||||
RgbwColor col(0,0,0,0);
|
||||
switch (busType) {
|
||||
case I_NONE: break;
|
||||
@ -1139,34 +1053,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: col = (static_cast<B_32_RN_TM1914_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_RN_SM16825_5: { Rgbww80Color c = (static_cast<B_32_RN_SM16825_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,max(c.WW,c.CW)/257); } break; // will not return original W
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: col = (useParallelI2S) ? (static_cast<B_32_I1_NEO_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_NEO_4: col = (useParallelI2S) ? (static_cast<B_32_I1_NEO_4P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_400_3: col = (useParallelI2S) ? (static_cast<B_32_I1_400_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_TM1_4: col = (useParallelI2S) ? (static_cast<B_32_I1_TM1_4P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_TM2_3: col = (useParallelI2S) ? (static_cast<B_32_I1_TM2_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_TM2_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_UCS_3: { Rgb48Color c = (useParallelI2S) ? (static_cast<B_32_I1_UCS_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_UCS_3*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,0); } break;
|
||||
case I_32_I1_UCS_4: { Rgbw64Color c = (useParallelI2S) ? (static_cast<B_32_I1_UCS_4P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,c.W/257); } break;
|
||||
case I_32_I1_APA106_3: col = (useParallelI2S) ? (static_cast<B_32_I1_APA106_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_FW6_5: { RgbwwColor c = (useParallelI2S) ? (static_cast<B_32_I1_FW6_5P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I1_2805_5: { RgbwwColor c = (useParallelI2S) ? (static_cast<B_32_I1_2805_5P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I1_TM1914_3: col = (useParallelI2S) ? (static_cast<B_32_I1_TM1914_3P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_TM1914_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I1_SM16825_5: { Rgbww80Color c = (useParallelI2S) ? (static_cast<B_32_I1_SM16825_5P*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I1_SM16825_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,max(c.WW,c.CW)/257); } break; // will not return original W
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: col = (static_cast<B_32_I0_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_NEO_4: col = (static_cast<B_32_I0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_400_3: col = (static_cast<B_32_I0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_TM1_4: col = (static_cast<B_32_I0_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_TM2_3: col = (static_cast<B_32_I0_TM2_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_UCS_3: { Rgb48Color c = (static_cast<B_32_I0_UCS_3*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,0); } break;
|
||||
case I_32_I0_UCS_4: { Rgbw64Color c = (static_cast<B_32_I0_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,c.W/257); } break;
|
||||
case I_32_I0_APA106_3: col = (static_cast<B_32_I0_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_FW6_5: { RgbwwColor c = (static_cast<B_32_I0_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I0_2805_5: { RgbwwColor c = (static_cast<B_32_I0_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I0_TM1914_3: col = (static_cast<B_32_I0_TM1914_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I0_SM16825_5: { Rgbww80Color c = (static_cast<B_32_I0_SM16825_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,max(c.WW,c.CW)/257); } break; // will not return original W
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_NEO_4: col = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_4*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_400_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_400_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_TM1_4: col = (_useParallelI2S) ? (static_cast<B_32_IP_TM1_4*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_TM2_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_TM2_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_TM2_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_UCS_3: { Rgb48Color c = (_useParallelI2S) ? (static_cast<B_32_IP_UCS_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_UCS_3*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,0); } break;
|
||||
case I_32_I2_UCS_4: { Rgbw64Color c = (_useParallelI2S) ? (static_cast<B_32_IP_UCS_4*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,c.W/257); } break;
|
||||
case I_32_I2_APA106_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_APA106_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_FW6_5: { RgbwwColor c = (_useParallelI2S) ? (static_cast<B_32_IP_FW6_5*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I2_2805_5: { RgbwwColor c = (_useParallelI2S) ? (static_cast<B_32_IP_2805_5*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||
case I_32_I2_TM1914_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_TM1914_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_TM1914_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
case I_32_I2_SM16825_5: { Rgbww80Color c = (_useParallelI2S) ? (static_cast<B_32_IP_SM16825_5*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_SM16825_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,max(c.WW,c.CW)/257); } break; // will not return original W
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: col = (static_cast<B_HS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
||||
@ -1269,34 +1168,19 @@ class PolyBus {
|
||||
case I_32_RN_TM1914_3: delete (static_cast<B_32_RN_TM1914_3*>(busPtr)); break;
|
||||
case I_32_RN_SM16825_5: delete (static_cast<B_32_RN_SM16825_5*>(busPtr)); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) delete (static_cast<B_32_I1_NEO_3P*>(busPtr)); else delete (static_cast<B_32_I1_NEO_3*>(busPtr)); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) delete (static_cast<B_32_I1_NEO_4P*>(busPtr)); else delete (static_cast<B_32_I1_NEO_4*>(busPtr)); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) delete (static_cast<B_32_I1_400_3P*>(busPtr)); else delete (static_cast<B_32_I1_400_3*>(busPtr)); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) delete (static_cast<B_32_I1_TM1_4P*>(busPtr)); else delete (static_cast<B_32_I1_TM1_4*>(busPtr)); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) delete (static_cast<B_32_I1_TM2_3P*>(busPtr)); else delete (static_cast<B_32_I1_TM2_3*>(busPtr)); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) delete (static_cast<B_32_I1_UCS_3P*>(busPtr)); else delete (static_cast<B_32_I1_UCS_3*>(busPtr)); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) delete (static_cast<B_32_I1_UCS_4P*>(busPtr)); else delete (static_cast<B_32_I1_UCS_4*>(busPtr)); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) delete (static_cast<B_32_I1_APA106_3P*>(busPtr)); else delete (static_cast<B_32_I1_APA106_3*>(busPtr)); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) delete (static_cast<B_32_I1_FW6_5P*>(busPtr)); else delete (static_cast<B_32_I1_FW6_5*>(busPtr)); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) delete (static_cast<B_32_I1_2805_5P*>(busPtr)); else delete (static_cast<B_32_I1_2805_5*>(busPtr)); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) delete (static_cast<B_32_I1_TM1914_3P*>(busPtr)); else delete (static_cast<B_32_I1_TM1914_3*>(busPtr)); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) delete (static_cast<B_32_I1_SM16825_5P*>(busPtr)); else delete (static_cast<B_32_I1_SM16825_5*>(busPtr)); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: delete (static_cast<B_32_I0_NEO_3*>(busPtr)); break;
|
||||
case I_32_I0_NEO_4: delete (static_cast<B_32_I0_NEO_4*>(busPtr)); break;
|
||||
case I_32_I0_400_3: delete (static_cast<B_32_I0_400_3*>(busPtr)); break;
|
||||
case I_32_I0_TM1_4: delete (static_cast<B_32_I0_TM1_4*>(busPtr)); break;
|
||||
case I_32_I0_TM2_3: delete (static_cast<B_32_I0_TM2_3*>(busPtr)); break;
|
||||
case I_32_I0_UCS_3: delete (static_cast<B_32_I0_UCS_3*>(busPtr)); break;
|
||||
case I_32_I0_UCS_4: delete (static_cast<B_32_I0_UCS_4*>(busPtr)); break;
|
||||
case I_32_I0_APA106_3: delete (static_cast<B_32_I0_APA106_3*>(busPtr)); break;
|
||||
case I_32_I0_FW6_5: delete (static_cast<B_32_I0_FW6_5*>(busPtr)); break;
|
||||
case I_32_I0_2805_5: delete (static_cast<B_32_I0_2805_5*>(busPtr)); break;
|
||||
case I_32_I0_TM1914_3: delete (static_cast<B_32_I0_TM1914_3*>(busPtr)); break;
|
||||
case I_32_I0_SM16825_5: delete (static_cast<B_32_I0_SM16825_5*>(busPtr)); break;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: if (_useParallelI2S) delete (static_cast<B_32_IP_NEO_3*>(busPtr)); else delete (static_cast<B_32_I2_NEO_3*>(busPtr)); break;
|
||||
case I_32_I2_NEO_4: if (_useParallelI2S) delete (static_cast<B_32_IP_NEO_4*>(busPtr)); else delete (static_cast<B_32_I2_NEO_4*>(busPtr)); break;
|
||||
case I_32_I2_400_3: if (_useParallelI2S) delete (static_cast<B_32_IP_400_3*>(busPtr)); else delete (static_cast<B_32_I2_400_3*>(busPtr)); break;
|
||||
case I_32_I2_TM1_4: if (_useParallelI2S) delete (static_cast<B_32_IP_TM1_4*>(busPtr)); else delete (static_cast<B_32_I2_TM1_4*>(busPtr)); break;
|
||||
case I_32_I2_TM2_3: if (_useParallelI2S) delete (static_cast<B_32_IP_TM2_3*>(busPtr)); else delete (static_cast<B_32_I2_TM2_3*>(busPtr)); break;
|
||||
case I_32_I2_UCS_3: if (_useParallelI2S) delete (static_cast<B_32_IP_UCS_3*>(busPtr)); else delete (static_cast<B_32_I2_UCS_3*>(busPtr)); break;
|
||||
case I_32_I2_UCS_4: if (_useParallelI2S) delete (static_cast<B_32_IP_UCS_4*>(busPtr)); else delete (static_cast<B_32_I2_UCS_4*>(busPtr)); break;
|
||||
case I_32_I2_APA106_3: if (_useParallelI2S) delete (static_cast<B_32_IP_APA106_3*>(busPtr)); else delete (static_cast<B_32_I2_APA106_3*>(busPtr)); break;
|
||||
case I_32_I2_FW6_5: if (_useParallelI2S) delete (static_cast<B_32_IP_FW6_5*>(busPtr)); else delete (static_cast<B_32_I2_FW6_5*>(busPtr)); break;
|
||||
case I_32_I2_2805_5: if (_useParallelI2S) delete (static_cast<B_32_IP_2805_5*>(busPtr)); else delete (static_cast<B_32_I2_2805_5*>(busPtr)); break;
|
||||
case I_32_I2_TM1914_3: if (_useParallelI2S) delete (static_cast<B_32_IP_TM1914_3*>(busPtr)); else delete (static_cast<B_32_I2_TM1914_3*>(busPtr)); break;
|
||||
case I_32_I2_SM16825_5: if (_useParallelI2S) delete (static_cast<B_32_IP_SM16825_5*>(busPtr)); else delete (static_cast<B_32_I2_SM16825_5*>(busPtr)); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: delete (static_cast<B_HS_DOT_3*>(busPtr)); break;
|
||||
@ -1312,8 +1196,178 @@ class PolyBus {
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned getDataSize(void* busPtr, uint8_t busType) {
|
||||
unsigned size = 0;
|
||||
switch (busType) {
|
||||
case I_NONE: break;
|
||||
#ifdef ESP8266
|
||||
case I_8266_U0_NEO_3: size = (static_cast<B_8266_U0_NEO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_NEO_3: size = (static_cast<B_8266_U1_NEO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_NEO_3: size = (static_cast<B_8266_DM_NEO_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_NEO_3: size = (static_cast<B_8266_BB_NEO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_NEO_4: size = (static_cast<B_8266_U0_NEO_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_NEO_4: size = (static_cast<B_8266_U1_NEO_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_NEO_4: size = (static_cast<B_8266_DM_NEO_4*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_NEO_4: size = (static_cast<B_8266_BB_NEO_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_400_3: size = (static_cast<B_8266_U0_400_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_400_3: size = (static_cast<B_8266_U1_400_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_400_3: size = (static_cast<B_8266_DM_400_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_400_3: size = (static_cast<B_8266_BB_400_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_TM1_4: size = (static_cast<B_8266_U0_TM1_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_TM1_4: size = (static_cast<B_8266_U1_TM1_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_TM1_4: size = (static_cast<B_8266_DM_TM1_4*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_TM1_4: size = (static_cast<B_8266_BB_TM1_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_TM2_3: size = (static_cast<B_8266_U0_TM2_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_TM2_3: size = (static_cast<B_8266_U1_TM2_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_TM2_3: size = (static_cast<B_8266_DM_TM2_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_TM2_3: size = (static_cast<B_8266_BB_TM2_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_UCS_3: size = (static_cast<B_8266_U0_UCS_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_UCS_3: size = (static_cast<B_8266_U1_UCS_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_UCS_3: size = (static_cast<B_8266_DM_UCS_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_UCS_3: size = (static_cast<B_8266_BB_UCS_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_UCS_4: size = (static_cast<B_8266_U0_UCS_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_UCS_4: size = (static_cast<B_8266_U1_UCS_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_UCS_4: size = (static_cast<B_8266_DM_UCS_4*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_UCS_4: size = (static_cast<B_8266_BB_UCS_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_APA106_3: size = (static_cast<B_8266_U0_APA106_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_APA106_3: size = (static_cast<B_8266_U1_APA106_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_APA106_3: size = (static_cast<B_8266_DM_APA106_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_APA106_3: size = (static_cast<B_8266_BB_APA106_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_FW6_5: size = (static_cast<B_8266_U0_FW6_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_FW6_5: size = (static_cast<B_8266_U1_FW6_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_FW6_5: size = (static_cast<B_8266_DM_FW6_5*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_FW6_5: size = (static_cast<B_8266_BB_FW6_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_2805_5: size = (static_cast<B_8266_U0_2805_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_2805_5: size = (static_cast<B_8266_U1_2805_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_2805_5: size = (static_cast<B_8266_DM_2805_5*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_2805_5: size = (static_cast<B_8266_BB_2805_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_TM1914_3: size = (static_cast<B_8266_U0_TM1914_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_TM1914_3: size = (static_cast<B_8266_U1_TM1914_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_TM1914_3: size = (static_cast<B_8266_DM_TM1914_3*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_TM1914_3: size = (static_cast<B_8266_BB_TM1914_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U0_SM16825_5: size = (static_cast<B_8266_U0_SM16825_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_U1_SM16825_5: size = (static_cast<B_8266_U1_SM16825_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_8266_DM_SM16825_5: size = (static_cast<B_8266_DM_SM16825_5*>(busPtr))->PixelsSize()*5; break;
|
||||
case I_8266_BB_SM16825_5: size = (static_cast<B_8266_BB_SM16825_5*>(busPtr))->PixelsSize()*2; break;
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// RMT buses (front + back + small system managed RMT)
|
||||
case I_32_RN_NEO_3: size = (static_cast<B_32_RN_NEO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_NEO_4: size = (static_cast<B_32_RN_NEO_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_400_3: size = (static_cast<B_32_RN_400_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_TM1_4: size = (static_cast<B_32_RN_TM1_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_TM2_3: size = (static_cast<B_32_RN_TM2_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_UCS_3: size = (static_cast<B_32_RN_UCS_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_UCS_4: size = (static_cast<B_32_RN_UCS_4*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_APA106_3: size = (static_cast<B_32_RN_APA106_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_FW6_5: size = (static_cast<B_32_RN_FW6_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_2805_5: size = (static_cast<B_32_RN_2805_5*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_TM1914_3: size = (static_cast<B_32_RN_TM1914_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_32_RN_SM16825_5: size = (static_cast<B_32_RN_SM16825_5*>(busPtr))->PixelsSize()*2; break;
|
||||
// I2S1 bus or paralell buses (front + DMA; DMA = front * cadence, aligned to 4 bytes)
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_NEO_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_NEO_4: size = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_4*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_NEO_4*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_400_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_400_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_400_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_TM1_4: size = (_useParallelI2S) ? (static_cast<B_32_IP_TM1_4*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_TM1_4*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_TM2_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_TM2_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_TM2_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_UCS_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_UCS_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_UCS_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_UCS_4: size = (_useParallelI2S) ? (static_cast<B_32_IP_UCS_4*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_UCS_4*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_APA106_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_APA106_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_APA106_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_FW6_5: size = (_useParallelI2S) ? (static_cast<B_32_IP_FW6_5*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_FW6_5*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_2805_5: size = (_useParallelI2S) ? (static_cast<B_32_IP_2805_5*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_2805_5*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_TM1914_3: size = (_useParallelI2S) ? (static_cast<B_32_IP_TM1914_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_TM1914_3*>(busPtr))->PixelsSize()*4; break;
|
||||
case I_32_I2_SM16825_5: size = (_useParallelI2S) ? (static_cast<B_32_IP_SM16825_5*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_SM16825_5*>(busPtr))->PixelsSize()*4; break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: size = (static_cast<B_HS_DOT_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_SS_DOT_3: size = (static_cast<B_SS_DOT_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_HS_LPD_3: size = (static_cast<B_HS_LPD_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_SS_LPD_3: size = (static_cast<B_SS_LPD_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_HS_LPO_3: size = (static_cast<B_HS_LPO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_SS_LPO_3: size = (static_cast<B_SS_LPO_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_HS_WS1_3: size = (static_cast<B_HS_WS1_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_SS_WS1_3: size = (static_cast<B_SS_WS1_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_HS_P98_3: size = (static_cast<B_HS_P98_3*>(busPtr))->PixelsSize()*2; break;
|
||||
case I_SS_P98_3: size = (static_cast<B_SS_P98_3*>(busPtr))->PixelsSize()*2; break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static unsigned memUsage(unsigned count, unsigned busType) {
|
||||
unsigned size = count*3; // let's assume 3 channels, we will add count or 2*count below for 4 channels or 5 channels
|
||||
switch (busType) {
|
||||
case I_NONE: size = 0; break;
|
||||
#ifdef ESP8266
|
||||
// UART methods have front + back buffers + small UART
|
||||
case I_8266_U0_NEO_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_U1_NEO_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_BB_NEO_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_U0_TM1_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_U1_TM1_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_BB_TM1_4: size = (size + count)*2; break; // 4 channels
|
||||
case I_8266_U0_UCS_3: size *= 4; break; // 16 bit
|
||||
case I_8266_U1_UCS_3: size *= 4; break; // 16 bit
|
||||
case I_8266_BB_UCS_3: size *= 4; break; // 16 bit
|
||||
case I_8266_U0_UCS_4: size = (size + count)*2*2; break; // 16 bit 4 channels
|
||||
case I_8266_U1_UCS_4: size = (size + count)*2*2; break; // 16 bit 4 channels
|
||||
case I_8266_BB_UCS_4: size = (size + count)*2*2; break; // 16 bit 4 channels
|
||||
case I_8266_U0_FW6_5: size = (size + 2*count)*2; break; // 5 channels
|
||||
case I_8266_U1_FW6_5: size = (size + 2*count)*2; break; // 5channels
|
||||
case I_8266_BB_FW6_5: size = (size + 2*count)*2; break; // 5 channels
|
||||
case I_8266_U0_2805_5: size = (size + 2*count)*2; break; // 5 channels
|
||||
case I_8266_U1_2805_5: size = (size + 2*count)*2; break; // 5 channels
|
||||
case I_8266_BB_2805_5: size = (size + 2*count)*2; break; // 5 channels
|
||||
case I_8266_U0_SM16825_5: size = (size + 2*count)*2*2; break; // 16 bit 5 channels
|
||||
case I_8266_U1_SM16825_5: size = (size + 2*count)*2*2; break; // 16 bit 5 channels
|
||||
case I_8266_BB_SM16825_5: size = (size + 2*count)*2*2; break; // 16 bit 5 channels
|
||||
// DMA methods have front + DMA buffer = ((1+(3+1)) * channels)
|
||||
case I_8266_DM_NEO_3: size *= 5; break;
|
||||
case I_8266_DM_NEO_4: size = (size + count)*5; break;
|
||||
case I_8266_DM_400_3: size *= 5; break;
|
||||
case I_8266_DM_TM1_4: size = (size + count)*5; break;
|
||||
case I_8266_DM_TM2_3: size *= 5; break;
|
||||
case I_8266_DM_UCS_3: size *= 2*5; break;
|
||||
case I_8266_DM_UCS_4: size = (size + count)*2*5; break;
|
||||
case I_8266_DM_APA106_3: size *= 5; break;
|
||||
case I_8266_DM_FW6_5: size = (size + 2*count)*5; break;
|
||||
case I_8266_DM_2805_5: size = (size + 2*count)*5; break;
|
||||
case I_8266_DM_TM1914_3: size *= 5; break;
|
||||
case I_8266_DM_SM16825_5: size = (size + 2*count)*2*5; break;
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// RMT buses (1x front and 1x back buffer)
|
||||
case I_32_RN_NEO_4: size = (size + count)*2; break;
|
||||
case I_32_RN_TM1_4: size = (size + count)*2; break;
|
||||
case I_32_RN_UCS_3: size *= 2*2; break;
|
||||
case I_32_RN_UCS_4: size = (size + count)*2*2; break;
|
||||
case I_32_RN_FW6_5: size = (size + 2*count)*2; break;
|
||||
case I_32_RN_2805_5: size = (size + 2*count)*2; break;
|
||||
case I_32_RN_SM16825_5: size = (size + 2*count)*2*2; break;
|
||||
// I2S1 bus or paralell buses (individual 1x front and 1 DMA (3x or 4x pixel count) or common back DMA buffers)
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
case I_32_I2_NEO_3: size *= 4; break;
|
||||
case I_32_I2_NEO_4: size = (size + count)*4; break;
|
||||
case I_32_I2_400_3: size *= 4; break;
|
||||
case I_32_I2_TM1_4: size = (size + count)*4; break;
|
||||
case I_32_I2_TM2_3: size *= 4; break;
|
||||
case I_32_I2_UCS_3: size *= 2*4; break;
|
||||
case I_32_I2_UCS_4: size = (size + count)*2*4; break;
|
||||
case I_32_I2_APA106_3: size *= 4; break;
|
||||
case I_32_I2_FW6_5: size = (size + 2*count)*4; break;
|
||||
case I_32_I2_2805_5: size = (size + 2*count)*4; break;
|
||||
case I_32_I2_TM1914_3: size *= 4; break;
|
||||
case I_32_I2_SM16825_5: size = (size + 2*count)*2*4; break;
|
||||
#endif
|
||||
#endif
|
||||
// everything else uses 2 buffers
|
||||
default: size *= 2; break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
//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) {
|
||||
static uint8_t getI(uint8_t busType, const uint8_t* pins, uint8_t num = 0) {
|
||||
if (!Bus::isDigital(busType)) return I_NONE;
|
||||
if (Bus::is2Pin(busType)) { //SPI LED chips
|
||||
bool isHSPI = false;
|
||||
@ -1372,26 +1426,33 @@ class PolyBus {
|
||||
uint8_t offset = 0; // 0 = RMT (num 1-8), 1 = I2S0 (used by Audioreactive), 2 = I2S1
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
// ESP32-S2 only has 4 RMT channels
|
||||
if (num > 4) return I_NONE;
|
||||
if (num > 3) offset = 1; // only one I2S (use last to allow Audioreactive)
|
||||
if (_useParallelI2S) {
|
||||
if (num > 11) return I_NONE;
|
||||
if (num > 3) offset = 1; // use x8 parallel I2S0 channels (use last to allow Audioreactive)
|
||||
} else {
|
||||
if (num > 4) return I_NONE;
|
||||
if (num > 3) offset = 1; // only one I2S0 (use last to allow Audioreactive)
|
||||
}
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
// On ESP32-C3 only the first 2 RMT channels are usable for transmitting
|
||||
if (num > 1) return I_NONE;
|
||||
//if (num > 1) offset = 1; // I2S not supported yet (only 1 I2S)
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
// On ESP32-S3 only the first 4 RMT channels are usable for transmitting
|
||||
if (num > 3) return I_NONE;
|
||||
//if (num > 3) offset = num -4; // I2S not supported yet
|
||||
if (_useParallelI2S) {
|
||||
if (num > 11) return I_NONE;
|
||||
if (num > 3) offset = 1; // use x8 parallel I2S LCD channels
|
||||
} else {
|
||||
if (num > 3) return I_NONE; // do not use single I2S (as it is not supported)
|
||||
}
|
||||
#else
|
||||
// standard ESP32 has 8 RMT and 2 I2S channels
|
||||
if (useParallelI2S) {
|
||||
if (num > 16) return I_NONE;
|
||||
if (num < 8) offset = 2; // prefer 8 parallel I2S1 channels
|
||||
if (num == 16) offset = 1;
|
||||
// standard ESP32 has 8 RMT and x1/x8 I2S1 channels
|
||||
if (_useParallelI2S) {
|
||||
if (num > 15) return I_NONE;
|
||||
if (num > 7) offset = 1; // 8 RMT followed by 8 I2S
|
||||
} else {
|
||||
if (num > 9) return I_NONE;
|
||||
if (num > 8) offset = 1;
|
||||
if (num == 0) offset = 2; // prefer I2S1 for 1st bus (less flickering but more RAM needed)
|
||||
if (num == 0) offset = 1; // prefer I2S1 for 1st bus (less flickering but more RAM needed)
|
||||
}
|
||||
#endif
|
||||
switch (busType) {
|
||||
|
@ -118,6 +118,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
Bus::setCCTBlend(cctBlending);
|
||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||
CJSON(useGlobalLedBuffer, hw_led[F("ld")]);
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
CJSON(useParallelI2S, hw_led[F("prl")]);
|
||||
#endif
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// 2D Matrix Settings
|
||||
@ -162,34 +165,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
DEBUG_PRINTF_P(PSTR("Heap before buses: %d\n"), ESP.getFreeHeap());
|
||||
int s = 0; // bus iterator
|
||||
if (fromFS) BusManager::removeAll(); // can't safely manipulate busses directly in network callback
|
||||
unsigned mem = 0;
|
||||
|
||||
// determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
|
||||
bool useParallel = false;
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP32S2) && !defined(ARDUINO_ARCH_ESP32S3) && !defined(ARDUINO_ARCH_ESP32C3)
|
||||
unsigned digitalCount = 0;
|
||||
unsigned maxLedsOnBus = 0;
|
||||
unsigned maxChannels = 0;
|
||||
for (JsonObject elm : ins) {
|
||||
unsigned type = elm["type"] | TYPE_WS2812_RGB;
|
||||
unsigned len = elm["len"] | DEFAULT_LED_COUNT;
|
||||
if (!Bus::isDigital(type)) continue;
|
||||
if (!Bus::is2Pin(type)) {
|
||||
digitalCount++;
|
||||
unsigned channels = Bus::getNumberOfChannels(type);
|
||||
if (len > maxLedsOnBus) maxLedsOnBus = len;
|
||||
if (channels > maxChannels) maxChannels = channels;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("Maximum LEDs on a bus: %u\nDigital buses: %u\n"), maxLedsOnBus, digitalCount);
|
||||
// we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
|
||||
if (maxLedsOnBus <= 300 && digitalCount > 5) {
|
||||
DEBUG_PRINTLN(F("Switching to parallel I2S."));
|
||||
useParallel = true;
|
||||
BusManager::useParallelOutput();
|
||||
mem = BusManager::memUsage(maxChannels, maxLedsOnBus, 8); // use alternate memory calculation
|
||||
}
|
||||
#endif
|
||||
|
||||
for (JsonObject elm : ins) {
|
||||
if (s >= WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES) break;
|
||||
@ -220,24 +195,11 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
maMax = 0;
|
||||
}
|
||||
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
||||
if (fromFS) {
|
||||
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
|
||||
if (useParallel && s < 8) {
|
||||
// if for some unexplained reason the above pre-calculation was wrong, update
|
||||
unsigned memT = BusManager::memUsage(bc); // includes x8 memory allocation for parallel I2S
|
||||
if (memT > mem) mem = memT; // if we have unequal LED count use the largest
|
||||
} else
|
||||
mem += BusManager::memUsage(bc); // includes global buffer
|
||||
if (mem <= MAX_LED_MEMORY) if (BusManager::add(bc) == -1) break; // finalization will be done in WLED::beginStrip()
|
||||
} else {
|
||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||
busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
|
||||
doInitBusses = true; // finalization done in beginStrip()
|
||||
}
|
||||
|
||||
busConfigs.push_back(std::move(BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax)));
|
||||
doInitBusses = true; // finalization done in beginStrip()
|
||||
s++;
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("LED buffer size: %uB\n"), mem);
|
||||
DEBUG_PRINTF_P(PSTR("Heap after buses: %d\n"), ESP.getFreeHeap());
|
||||
}
|
||||
if (hw_led["rev"]) BusManager::getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus
|
||||
|
||||
@ -828,6 +790,9 @@ void serializeConfig() {
|
||||
hw_led["fps"] = strip.getTargetFps();
|
||||
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
||||
hw_led[F("ld")] = useGlobalLedBuffer;
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
hw_led[F("prl")] = BusManager::hasParallelOutput();
|
||||
#endif
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// 2D Matrix Settings
|
||||
@ -852,8 +817,19 @@ void serializeConfig() {
|
||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||
|
||||
for (size_t s = 0; s < BusManager::getNumBusses(); s++) {
|
||||
DEBUG_PRINTF_P(PSTR("Cfg: Saving bus #%u\n"), s);
|
||||
Bus *bus = BusManager::getBus(s);
|
||||
if (!bus || bus->getLength()==0) break;
|
||||
DEBUG_PRINTF_P(PSTR(" (%d-%d, type:%d, CO:%d, rev:%d, skip:%d, AW:%d kHz:%d, mA:%d/%d)\n"),
|
||||
(int)bus->getStart(), (int)(bus->getStart()+bus->getLength()),
|
||||
(int)(bus->getType() & 0x7F),
|
||||
(int)bus->getColorOrder(),
|
||||
(int)bus->isReversed(),
|
||||
(int)bus->skippedLeds(),
|
||||
(int)bus->getAutoWhiteMode(),
|
||||
(int)bus->getFrequency(),
|
||||
(int)bus->getLEDCurrent(), (int)bus->getMaxCurrent()
|
||||
);
|
||||
JsonObject ins = hw_led_ins.createNestedObject();
|
||||
ins["start"] = bus->getStart();
|
||||
ins["len"] = bus->getLength();
|
||||
|
@ -37,7 +37,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef WLED_MAX_USERMODS
|
||||
#ifdef ESP8266
|
||||
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define WLED_MAX_USERMODS 4
|
||||
#else
|
||||
#define WLED_MAX_USERMODS 6
|
||||
@ -49,31 +49,31 @@
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 3
|
||||
#define WLED_MAX_ANALOG_CHANNELS 5
|
||||
#define WLED_MAX_BUSSES 4 // will allow 3 digital & 1 analog RGB
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 2
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||
#else
|
||||
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, 6 LEDC, only has 1 I2S but NPB does not support it ATM
|
||||
#define WLED_MAX_BUSSES 6 // will allow 2 digital & 2 analog RGB or 6 PWM white
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 2
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 6
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 4
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2) // 4 RMT, 8 LEDC, only has 1 I2S bus, supported in NPB
|
||||
// the 5th bus (I2S) will prevent Audioreactive usermod from functioning (it is last used though)
|
||||
#define WLED_MAX_BUSSES 7 // will allow 5 digital & 2 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 5
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 8
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3) // 4 RMT, 8 LEDC, has 2 I2S but NPB does not support them ATM
|
||||
#define WLED_MAX_BUSSES 6 // will allow 4 digital & 2 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 4
|
||||
#define WLED_MAX_BUSSES 14 // will allow 12 digital & 2 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 12 // x4 RMT + x1/x8 I2S0
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 8
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 4
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3) // 4 RMT, 8 LEDC, has 2 I2S but NPB supports parallel x8 LCD on I2S1
|
||||
#define WLED_MAX_BUSSES 14 // will allow 12 digital & 2 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 12 // x4 RMT + x8 I2S-LCD
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 8
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 6
|
||||
#else
|
||||
// the last digital bus (I2S0) will prevent Audioreactive usermod from functioning
|
||||
#define WLED_MAX_BUSSES 20 // will allow 17 digital & 3 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 17
|
||||
#define WLED_MAX_BUSSES 19 // will allow 16 digital & 3 analog RGB
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 16 // x1/x8 I2S1 + x8 RMT
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 16
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 4
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 6
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
@ -115,7 +115,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define WLED_MAX_COLOR_ORDER_MAPPINGS 5
|
||||
#else
|
||||
#define WLED_MAX_COLOR_ORDER_MAPPINGS 10
|
||||
@ -125,7 +125,7 @@
|
||||
#undef WLED_MAX_LEDMAPS
|
||||
#endif
|
||||
#ifndef WLED_MAX_LEDMAPS
|
||||
#ifdef ESP8266
|
||||
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define WLED_MAX_LEDMAPS 10
|
||||
#else
|
||||
#define WLED_MAX_LEDMAPS 16
|
||||
@ -477,6 +477,8 @@
|
||||
#ifndef MAX_LEDS
|
||||
#ifdef ESP8266
|
||||
#define MAX_LEDS 1664 //can't rely on memory limit to limit this to 1600 LEDs
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define MAX_LEDS 2048 //due to memory constraints
|
||||
#else
|
||||
#define MAX_LEDS 8192
|
||||
#endif
|
||||
@ -486,7 +488,9 @@
|
||||
#ifdef ESP8266
|
||||
#define MAX_LED_MEMORY 4000
|
||||
#else
|
||||
#if defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32C3)
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#define MAX_LED_MEMORY 16000
|
||||
#elif defined(ARDUINO_ARCH_ESP32C3)
|
||||
#define MAX_LED_MEMORY 32000
|
||||
#else
|
||||
#define MAX_LED_MEMORY 64000
|
||||
|
@ -42,10 +42,10 @@
|
||||
if (loc) d.Sf.action = getURL('/settings/leds');
|
||||
}
|
||||
function bLimits(b,v,p,m,l,o=5,d=2,a=6) {
|
||||
oMaxB = maxB = b; // maxB - max buses (can be changed if using ESP32 parallel I2S)
|
||||
maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S)
|
||||
maxA = a; // maxA - max analog channels
|
||||
maxV = v; // maxV - min virtual buses
|
||||
oMaxB = maxB = b; // maxB - max buses (can be changed if using ESP32 parallel I2S): 19 - ESP32, 14 - S3/S2, 6 - C3, 4 - 8266
|
||||
maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S): 16 - ESP32, 12 - S3/S2, 2 - C3, 3 - 8266
|
||||
maxA = a; // maxA - max analog channels: 16 - ESP32, 8 - S3/S2, 6 - C3, 5 - 8266
|
||||
maxV = v; // maxV - min virtual buses: 4 - ESP32/S3, 3 - S2/C3, 2 - ESP8266
|
||||
maxPB = p; // maxPB - max LEDs per bus
|
||||
maxM = m; // maxM - max LED memory
|
||||
maxL = l; // maxL - max LEDs (will serve to determine ESP >1664 == ESP32)
|
||||
@ -250,6 +250,7 @@
|
||||
}
|
||||
|
||||
// enable/disable LED fields
|
||||
let dC = 0; // count of digital buses (for parallel I2S)
|
||||
let LTs = d.Sf.querySelectorAll("#mLC select[name^=LT]");
|
||||
LTs.forEach((s,i)=>{
|
||||
if (i < LTs.length-1) s.disabled = true; // prevent changing type (as we can't update options)
|
||||
@ -257,6 +258,7 @@
|
||||
var n = s.name.substring(2);
|
||||
var t = parseInt(s.value);
|
||||
memu += getMem(t, n); // calc memory
|
||||
dC += (isDig(t) && !isD2P(t));
|
||||
setPinConfig(n,t);
|
||||
gId("abl"+n).style.display = (!abl || !isDig(t)) ? "none" : "inline"; // show/hide individual ABL settings
|
||||
if (change) { // did we change LED type?
|
||||
@ -295,8 +297,7 @@
|
||||
// do we have a led count field
|
||||
if (nm=="LC") {
|
||||
let c = parseInt(LC.value,10); //get LED count
|
||||
if (c > 300 && i < 8) maxB = oMaxB - Math.max(maxD-7,0); //TODO: hard limit for buses when using ESP32 parallel I2S
|
||||
if (!customStarts || !startsDirty[n]) gId("ls"+n).value=sLC; //update start value
|
||||
if (!customStarts || !startsDirty[n]) gId("ls"+n).value = sLC; //update start value
|
||||
gId("ls"+n).disabled = !customStarts; //enable/disable field editing
|
||||
if (c) {
|
||||
let s = parseInt(gId("ls"+n).value); //start value
|
||||
@ -350,6 +351,17 @@
|
||||
else LC.style.color = d.ro_gpio.some((e)=>e==parseInt(LC.value)) ? "orange" : "#fff";
|
||||
}
|
||||
});
|
||||
const S2 = (oMaxB == 14) && (maxV == 4);
|
||||
const S3 = (oMaxB == 14) && (maxV == 6);
|
||||
if (oMaxB == 19 || S2 || S3) { // TODO: crude ESP32 & S2/S3 detection
|
||||
if (maxLC > 300 || dC <= 2) {
|
||||
d.Sf["PR"].checked = false;
|
||||
gId("prl").classList.add("hide");
|
||||
} else
|
||||
gId("prl").classList.remove("hide");
|
||||
maxD = (S2 || S3 ? 4 : 8) + (d.Sf["PR"].checked ? 8 : S2); // TODO: use bLimits() : 4/8RMT + (x1/x8 parallel) I2S1
|
||||
maxB = oMaxB - (d.Sf["PR"].checked ? 0 : 7 + S3); // S2 (maxV==3) does support single I2S
|
||||
}
|
||||
// distribute ABL current if not using PPL
|
||||
enPPL(sDI);
|
||||
|
||||
@ -470,14 +482,13 @@ mA/LED: <select name="LAsel${s}" onchange="enLA(this,'${s}');UI();">
|
||||
}
|
||||
}
|
||||
});
|
||||
enLA(d.Sf["LAsel"+s],s); // update LED mA
|
||||
// disable inappropriate LED types
|
||||
let sel = d.getElementsByName("LT"+s)[0]
|
||||
if (i >= maxB || digitalB >= maxD) disable(sel,'option[data-type="D"]'); // NOTE: see isDig()
|
||||
if (i >= maxB || twopinB >= 1) disable(sel,'option[data-type="2P"]'); // NOTE: see isD2P()
|
||||
disable(sel,`option[data-type^="${'A'.repeat(maxA-analogB+1)}"]`); // NOTE: see isPWM()
|
||||
sel.selectedIndex = sel.querySelector('option:not(:disabled)').index;
|
||||
// initialize current limiter
|
||||
enLA(d.Sf["LAsel"+s],s);
|
||||
}
|
||||
if (n==-1) {
|
||||
o[--i].remove();--i;
|
||||
@ -789,6 +800,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
||||
Use less than <span id="wreason">800 LEDs per output</span> for the best experience!<br>
|
||||
</div>
|
||||
<hr class="sml">
|
||||
<div id="prl" class="hide">Use parallel I2S: <input type="checkbox" name="PR"><br></div>
|
||||
Make a segment for each output: <input type="checkbox" name="MS"><br>
|
||||
Custom bus start indices: <input type="checkbox" onchange="tglSi(this.checked)" id="si"><br>
|
||||
Use global LED buffer: <input type="checkbox" name="LD" onchange="UI()"><br>
|
||||
|
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef WLED_FCN_DECLARE_H
|
||||
#define WLED_FCN_DECLARE_H
|
||||
|
||||
|
@ -134,11 +134,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
strip.correctWB = request->hasArg(F("CCT"));
|
||||
strip.cctFromRgb = request->hasArg(F("CR"));
|
||||
cctICused = request->hasArg(F("IC"));
|
||||
uint8_t cctBlending = request->arg(F("CB")).toInt();
|
||||
Bus::setCCTBlend(cctBlending);
|
||||
Bus::setCCTBlend(request->arg(F("CB")).toInt());
|
||||
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
||||
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||
useGlobalLedBuffer = request->hasArg(F("LD"));
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
useParallelI2S = request->hasArg(F("PR"));
|
||||
#endif
|
||||
|
||||
bool busesChanged = false;
|
||||
for (int s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
||||
@ -208,8 +210,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
type |= request->hasArg(rf) << 7; // off refresh override
|
||||
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
||||
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
|
||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||
busConfigs[s] = new(std::nothrow) BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax);
|
||||
busConfigs.push_back(std::move(BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax)));
|
||||
busesChanged = true;
|
||||
}
|
||||
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
||||
|
@ -185,46 +185,7 @@ void WLED::loop()
|
||||
DEBUG_PRINTLN(F("Re-init busses."));
|
||||
bool aligned = strip.checkSegmentAlignment(); //see if old segments match old bus(ses)
|
||||
BusManager::removeAll();
|
||||
unsigned mem = 0;
|
||||
// determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
|
||||
bool useParallel = false;
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP32S2) && !defined(ARDUINO_ARCH_ESP32S3) && !defined(ARDUINO_ARCH_ESP32C3)
|
||||
unsigned digitalCount = 0;
|
||||
unsigned maxLedsOnBus = 0;
|
||||
unsigned maxChannels = 0;
|
||||
for (unsigned i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||
if (busConfigs[i] == nullptr) break;
|
||||
if (!Bus::isDigital(busConfigs[i]->type)) continue;
|
||||
if (!Bus::is2Pin(busConfigs[i]->type)) {
|
||||
digitalCount++;
|
||||
unsigned channels = Bus::getNumberOfChannels(busConfigs[i]->type);
|
||||
if (busConfigs[i]->count > maxLedsOnBus) maxLedsOnBus = busConfigs[i]->count;
|
||||
if (channels > maxChannels) maxChannels = channels;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("Maximum LEDs on a bus: %u\nDigital buses: %u\n"), maxLedsOnBus, digitalCount);
|
||||
// we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
|
||||
if (maxLedsOnBus <= 300 && digitalCount > 5) {
|
||||
DEBUG_PRINTF_P(PSTR("Switching to parallel I2S."));
|
||||
useParallel = true;
|
||||
BusManager::useParallelOutput();
|
||||
mem = BusManager::memUsage(maxChannels, maxLedsOnBus, 8); // use alternate memory calculation (hse to be used *after* useParallelOutput())
|
||||
}
|
||||
#endif
|
||||
// create buses/outputs
|
||||
for (unsigned i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||
if (busConfigs[i] == nullptr || (!useParallel && i > 10)) break;
|
||||
if (useParallel && i < 8) {
|
||||
// if for some unexplained reason the above pre-calculation was wrong, update
|
||||
unsigned memT = BusManager::memUsage(*busConfigs[i]); // includes x8 memory allocation for parallel I2S
|
||||
if (memT > mem) mem = memT; // if we have unequal LED count use the largest
|
||||
} else
|
||||
mem += BusManager::memUsage(*busConfigs[i]); // includes global buffer
|
||||
if (mem <= MAX_LED_MEMORY) BusManager::add(*busConfigs[i]);
|
||||
delete busConfigs[i];
|
||||
busConfigs[i] = nullptr;
|
||||
}
|
||||
strip.finalizeInit(); // also loads default ledmap if present
|
||||
strip.finalizeInit(); // will create buses and also load default ledmap if present
|
||||
BusManager::setBrightness(bri); // fix re-initialised bus' brightness #4005
|
||||
if (aligned) strip.makeAutoSegments();
|
||||
else strip.fixInvalidSegments();
|
||||
@ -573,6 +534,7 @@ void WLED::beginStrip()
|
||||
strip.makeAutoSegments();
|
||||
strip.setBrightness(0);
|
||||
strip.setShowCallback(handleOverlayDraw);
|
||||
doInitBusses = false;
|
||||
|
||||
if (turnOnAtBoot) {
|
||||
if (briS > 0) bri = briS;
|
||||
|
@ -371,7 +371,7 @@ WLED_GLOBAL bool noWifiSleep _INIT(false);
|
||||
WLED_GLOBAL bool force802_3g _INIT(false);
|
||||
#endif // WLED_SAVE_RAM
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3))
|
||||
#if defined(LOLIN_WIFI_FIX) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
|
||||
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_8_5dBm);
|
||||
#else
|
||||
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_19_5dBm);
|
||||
@ -398,6 +398,9 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load
|
||||
WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266
|
||||
#else
|
||||
WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
WLED_GLOBAL bool useParallelI2S _INIT(false); // parallel I2S for ESP32
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WLED_USE_IC_CCT
|
||||
WLED_GLOBAL bool cctICused _INIT(true); // CCT IC used (Athom 15W bulbs)
|
||||
@ -893,7 +896,7 @@ WLED_GLOBAL bool e131NewData _INIT(false);
|
||||
// led fx library object
|
||||
WLED_GLOBAL BusManager busses _INIT(BusManager());
|
||||
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
|
||||
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES] _INIT({nullptr}); //temporary, to remember values from network callback until after
|
||||
WLED_GLOBAL std::vector<BusConfig> busConfigs; //temporary, to remember values from network callback until after
|
||||
WLED_GLOBAL bool doInitBusses _INIT(false);
|
||||
WLED_GLOBAL int8_t loadLedmap _INIT(-1);
|
||||
WLED_GLOBAL uint8_t currentLedmap _INIT(0);
|
||||
|
@ -289,6 +289,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
printSetFormValue(settingsScript,PSTR("FR"),strip.getTargetFps());
|
||||
printSetFormValue(settingsScript,PSTR("AW"),Bus::getGlobalAWMode());
|
||||
printSetFormCheckbox(settingsScript,PSTR("LD"),useGlobalLedBuffer);
|
||||
printSetFormCheckbox(settingsScript,PSTR("PR"),BusManager::hasParallelOutput()); // get it from bus manager not global variable
|
||||
|
||||
unsigned sumMa = 0;
|
||||
for (int s = 0; s < BusManager::getNumBusses(); s++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user