Skip to content

Commit 0c84235

Browse files
committed
Bus rework
- Implement vector in bus manager - Memory calculation according to explanation from @Makuna - Prefer 8 RMT before 8 I2S on ESP32 (fixes wled#4380) - speed improvements in ABL - verbose debugging - get bus size from NPB (prototype) - Parallel I2S output bugfix - automatic selection of appropriate I2S bus (`X1xxxxxxMethod`) - removed I2S0 on ESP32 (used by AudioReactive) - renumbered internal bus numbers (iType) - added buffer size reporting
1 parent aab29cb commit 0c84235

File tree

11 files changed

+678
-517
lines changed

11 files changed

+678
-517
lines changed

wled00/FX_fcn.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,33 @@ void WS2812FX::finalizeInit() {
12201220

12211221
_hasWhiteChannel = _isOffRefreshRequired = false;
12221222

1223+
unsigned digitalCount = 0;
1224+
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
1225+
// determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
1226+
unsigned maxLedsOnBus = 0;
1227+
for (const auto &bus : busConfigs) {
1228+
if (Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type)) {
1229+
digitalCount++;
1230+
if (bus.count > maxLedsOnBus) maxLedsOnBus = bus.count;
1231+
}
1232+
}
1233+
DEBUG_PRINTF_P(PSTR("Maximum LEDs on a bus: %u\nDigital buses: %u\n"), maxLedsOnBus, digitalCount);
1234+
// we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
1235+
if (maxLedsOnBus <= 300 && useParallelI2S) BusManager::useParallelOutput(); // must call before creating buses
1236+
else useParallelI2S = false; // enforce single I2S
1237+
#endif
1238+
1239+
// create buses/outputs
1240+
unsigned mem = 0;
1241+
digitalCount = 0;
1242+
for (const auto &bus : busConfigs) {
1243+
mem += bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount++ : 0); // includes global buffer
1244+
if (mem <= MAX_LED_MEMORY) BusManager::add(bus);
1245+
else DEBUG_PRINTF_P(PSTR("Out of LED memory! Bus %d (%d) #%u not created."), (int)bus.type, (int)bus.count, digitalCount);
1246+
}
1247+
busConfigs.clear();
1248+
busConfigs.shrink_to_fit();
1249+
12231250
//if busses failed to load, add default (fresh install, FS issue, ...)
12241251
if (BusManager::getNumBusses() == 0) {
12251252
DEBUG_PRINTLN(F("No busses, init default"));
@@ -1235,6 +1262,7 @@ void WS2812FX::finalizeInit() {
12351262

12361263
unsigned prevLen = 0;
12371264
unsigned pinsIndex = 0;
1265+
digitalCount = 0;
12381266
for (unsigned i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
12391267
uint8_t defPin[OUTPUT_MAX_PINS];
12401268
// if we have less types than requested outputs and they do not align, use last known type to set current type
@@ -1299,9 +1327,11 @@ void WS2812FX::finalizeInit() {
12991327
if (Bus::isPWM(dataType) || Bus::isOnOff(dataType)) count = 1;
13001328
prevLen += count;
13011329
BusConfig defCfg = BusConfig(dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY, 0, useGlobalLedBuffer);
1330+
mem += defCfg.memUsage(Bus::isDigital(dataType) && !Bus::is2Pin(dataType) ? digitalCount++ : 0);
13021331
if (BusManager::add(defCfg) == -1) break;
13031332
}
13041333
}
1334+
DEBUG_PRINTF_P(PSTR("LED buffer size: %uB/%uB\n"), mem, BusManager::memUsage());
13051335

13061336
_length = 0;
13071337
for (int i=0; i<BusManager::getNumBusses(); i++) {

0 commit comments

Comments
 (0)