@@ -456,7 +456,7 @@ void Segment::handleRandomPalette() {
456456}
457457
458458// 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) {
460460 // return if neither bounds nor grouping have changed
461461 bool boundsUnchanged = (start == i1 && stop == i2);
462462 #ifndef WLED_DISABLE_2D
@@ -601,6 +601,20 @@ Segment &Segment::setPalette(uint8_t pal) {
601601 return *this ;
602602}
603603
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+
604618// 2D matrix
605619unsigned IRAM_ATTR Segment::virtualWidth () const {
606620 unsigned groupLen = groupLength ();
@@ -951,7 +965,7 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
951965 return strip.getPixelColor (i);
952966}
953967
954- uint8_t Segment::differs (Segment& b) const {
968+ uint8_t Segment::differs (const Segment& b) const {
955969 uint8_t d = 0 ;
956970 if (start != b.start ) d |= SEG_DIFFERS_BOUNDS;
957971 if (stop != b.stop ) d |= SEG_DIFFERS_BOUNDS;
@@ -1192,6 +1206,34 @@ void WS2812FX::finalizeInit() {
11921206
11931207 _hasWhiteChannel = _isOffRefreshRequired = false ;
11941208
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+
11951237 // if busses failed to load, add default (fresh install, FS issue, ...)
11961238 if (BusManager::getNumBusses () == 0 ) {
11971239 DEBUG_PRINTLN (F (" No busses, init default" ));
@@ -1207,6 +1249,7 @@ void WS2812FX::finalizeInit() {
12071249
12081250 unsigned prevLen = 0 ;
12091251 unsigned pinsIndex = 0 ;
1252+ digitalCount = 0 ;
12101253 for (unsigned i = 0 ; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
12111254 uint8_t defPin[OUTPUT_MAX_PINS];
12121255 // 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() {
12711314 if (Bus::isPWM (dataType) || Bus::isOnOff (dataType)) count = 1 ;
12721315 prevLen += count;
12731316 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 );
12741318 if (BusManager::add (defCfg) == -1 ) break ;
12751319 }
12761320 }
1321+ DEBUG_PRINTF_P (PSTR (" LED buffer size: %uB/%uB\n " ), mem, BusManager::memUsage ());
12771322
12781323 _length = 0 ;
12791324 for (int i=0 ; i<BusManager::getNumBusses (); i++) {
@@ -1290,6 +1335,7 @@ void WS2812FX::finalizeInit() {
12901335 // This must be done after all buses have been created, as some kinds (parallel I2S) interact
12911336 bus->begin ();
12921337 }
1338+ DEBUG_PRINTF_P (PSTR (" Heap after buses: %d\n " ), ESP.getFreeHeap ());
12931339
12941340 Segment::maxWidth = _length;
12951341 Segment::maxHeight = 1 ;
@@ -1601,7 +1647,7 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
16011647 segId = getSegmentsNum ()-1 ; // segments are added at the end of list
16021648 }
16031649 suspend ();
1604- _segments[segId].setUp (i1, i2, grouping, spacing, offset, startY, stopY);
1650+ _segments[segId].setGeometry (i1, i2, grouping, spacing, offset, startY, stopY);
16051651 resume ();
16061652 if (segId > 0 && segId == getSegmentsNum ()-1 && i2 <= i1) _segments.pop_back (); // if last segment was deleted remove it from vector
16071653}
0 commit comments