@@ -456,7 +456,7 @@ void Segment::handleRandomPalette() {
456
456
}
457
457
458
458
// segId is given when called from network callback, changes are queued if that segment is currently in its effect function
459
- void Segment::setUp (uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
459
+ void Segment::setGeometry (uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
460
460
// return if neither bounds nor grouping have changed
461
461
bool boundsUnchanged = (start == i1 && stop == i2);
462
462
#ifndef WLED_DISABLE_2D
@@ -601,6 +601,20 @@ Segment &Segment::setPalette(uint8_t pal) {
601
601
return *this ;
602
602
}
603
603
604
+ Segment &Segment::setName (const char *newName) {
605
+ if (newName) {
606
+ const int newLen = min (strlen (newName), (size_t )WLED_MAX_SEGNAME_LEN);
607
+ if (newLen) {
608
+ if (name) name = static_cast <char *>(realloc (name, newLen+1 ));
609
+ else name = static_cast <char *>(malloc (newLen+1 ));
610
+ if (name) strlcpy (name, newName, newLen+1 );
611
+ name[newLen] = 0 ;
612
+ return *this ;
613
+ }
614
+ }
615
+ return clearName ();
616
+ }
617
+
604
618
// 2D matrix
605
619
unsigned IRAM_ATTR Segment::virtualWidth () const {
606
620
unsigned groupLen = groupLength ();
@@ -951,7 +965,7 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
951
965
return strip.getPixelColor (i);
952
966
}
953
967
954
- uint8_t Segment::differs (Segment& b) const {
968
+ uint8_t Segment::differs (const Segment& b) const {
955
969
uint8_t d = 0 ;
956
970
if (start != b.start ) d |= SEG_DIFFERS_BOUNDS;
957
971
if (stop != b.stop ) d |= SEG_DIFFERS_BOUNDS;
@@ -1192,6 +1206,34 @@ void WS2812FX::finalizeInit() {
1192
1206
1193
1207
_hasWhiteChannel = _isOffRefreshRequired = false ;
1194
1208
1209
+ unsigned digitalCount = 0 ;
1210
+ #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
1211
+ // determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
1212
+ unsigned maxLedsOnBus = 0 ;
1213
+ for (const auto &bus : busConfigs) {
1214
+ if (Bus::isDigital (bus.type ) && !Bus::is2Pin (bus.type )) {
1215
+ digitalCount++;
1216
+ if (bus.count > maxLedsOnBus) maxLedsOnBus = bus.count ;
1217
+ }
1218
+ }
1219
+ DEBUG_PRINTF_P (PSTR (" Maximum LEDs on a bus: %u\n Digital buses: %u\n " ), maxLedsOnBus, digitalCount);
1220
+ // we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
1221
+ if (maxLedsOnBus <= 300 && useParallelI2S) BusManager::useParallelOutput (); // must call before creating buses
1222
+ else useParallelI2S = false ; // enforce single I2S
1223
+ #endif
1224
+
1225
+ // create buses/outputs
1226
+ unsigned mem = 0 ;
1227
+ digitalCount = 0 ;
1228
+ for (const auto &bus : busConfigs) {
1229
+ mem += bus.memUsage (Bus::isDigital (bus.type ) && !Bus::is2Pin (bus.type ) ? digitalCount++ : 0 ); // includes global buffer
1230
+ if (mem <= MAX_LED_MEMORY) {
1231
+ if (BusManager::add (bus) == -1 ) break ;
1232
+ } else DEBUG_PRINTF_P (PSTR (" Out of LED memory! Bus %d (%d) #%u not created." ), (int )bus.type , (int )bus.count , digitalCount);
1233
+ }
1234
+ busConfigs.clear ();
1235
+ busConfigs.shrink_to_fit ();
1236
+
1195
1237
// if busses failed to load, add default (fresh install, FS issue, ...)
1196
1238
if (BusManager::getNumBusses () == 0 ) {
1197
1239
DEBUG_PRINTLN (F (" No busses, init default" ));
@@ -1207,6 +1249,7 @@ void WS2812FX::finalizeInit() {
1207
1249
1208
1250
unsigned prevLen = 0 ;
1209
1251
unsigned pinsIndex = 0 ;
1252
+ digitalCount = 0 ;
1210
1253
for (unsigned i = 0 ; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
1211
1254
uint8_t defPin[OUTPUT_MAX_PINS];
1212
1255
// if we have less types than requested outputs and they do not align, use last known type to set current type
@@ -1271,9 +1314,11 @@ void WS2812FX::finalizeInit() {
1271
1314
if (Bus::isPWM (dataType) || Bus::isOnOff (dataType)) count = 1 ;
1272
1315
prevLen += count;
1273
1316
BusConfig defCfg = BusConfig (dataType, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false , 0 , RGBW_MODE_MANUAL_ONLY, 0 , useGlobalLedBuffer);
1317
+ mem += defCfg.memUsage (Bus::isDigital (dataType) && !Bus::is2Pin (dataType) ? digitalCount++ : 0 );
1274
1318
if (BusManager::add (defCfg) == -1 ) break ;
1275
1319
}
1276
1320
}
1321
+ DEBUG_PRINTF_P (PSTR (" LED buffer size: %uB/%uB\n " ), mem, BusManager::memUsage ());
1277
1322
1278
1323
_length = 0 ;
1279
1324
for (int i=0 ; i<BusManager::getNumBusses (); i++) {
@@ -1290,6 +1335,7 @@ void WS2812FX::finalizeInit() {
1290
1335
// This must be done after all buses have been created, as some kinds (parallel I2S) interact
1291
1336
bus->begin ();
1292
1337
}
1338
+ DEBUG_PRINTF_P (PSTR (" Heap after buses: %d\n " ), ESP.getFreeHeap ());
1293
1339
1294
1340
Segment::maxWidth = _length;
1295
1341
Segment::maxHeight = 1 ;
@@ -1601,7 +1647,7 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
1601
1647
segId = getSegmentsNum ()-1 ; // segments are added at the end of list
1602
1648
}
1603
1649
suspend ();
1604
- _segments[segId].setUp (i1, i2, grouping, spacing, offset, startY, stopY);
1650
+ _segments[segId].setGeometry (i1, i2, grouping, spacing, offset, startY, stopY);
1605
1651
resume ();
1606
1652
if (segId > 0 && segId == getSegmentsNum ()-1 && i2 <= i1) _segments.pop_back (); // if last segment was deleted remove it from vector
1607
1653
}
0 commit comments