@@ -160,44 +160,46 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
160160 DEBUG_PRINTF_P (PSTR (" Heap before buses: %d\n " ), ESP.getFreeHeap ());
161161 int s = 0 ; // bus iterator
162162 if (fromFS) BusManager::removeAll (); // can't safely manipulate busses directly in network callback
163- uint32_t mem = 0 ;
164- bool busesChanged = false ;
163+ unsigned mem = 0 ;
164+
165165 // determine if it is sensible to use parallel I2S outputs on ESP32 (i.e. more than 5 outputs = 1 I2S + 4 RMT)
166166 bool useParallel = false ;
167167 #if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP32S2) && !defined(ARDUINO_ARCH_ESP32S3) && !defined(ARDUINO_ARCH_ESP32C3)
168168 unsigned digitalCount = 0 ;
169- unsigned maxLeds = 0 ;
170- int oldType = 0 ;
171- int j = 0 ;
169+ unsigned maxLedsOnBus = 0 ;
170+ unsigned maxChannels = 0 ;
172171 for (JsonObject elm : ins) {
173172 unsigned type = elm[" type" ] | TYPE_WS2812_RGB;
174- unsigned len = elm[" len" ] | 30 ;
175- if (IS_DIGITAL (type) && !IS_2PIN (type)) digitalCount++;
176- if (len > maxLeds) maxLeds = len;
177- // we need to have all LEDs of the same type for parallel
178- if (j++ < 8 && oldType > 0 && oldType != type) oldType = -1 ;
179- else if (oldType == 0 ) oldType = type;
173+ unsigned len = elm[" len" ] | DEFAULT_LED_COUNT;
174+ if (!IS_DIGITAL (type)) continue ;
175+ if (!IS_2PIN (type)) {
176+ digitalCount++;
177+ unsigned channels = Bus::getNumberOfChannels (type);
178+ if (len > maxLedsOnBus) maxLedsOnBus = len;
179+ if (channels > maxChannels) maxChannels = channels;
180+ }
180181 }
181- DEBUG_PRINTF_P (PSTR (" Maximum LEDs on a bus: %u\n Digital buses: %u\n Different types: %d \ n" ), maxLeds , digitalCount, ( int )(oldType == - 1 ) );
182+ DEBUG_PRINTF_P (PSTR (" Maximum LEDs on a bus: %u\n Digital buses: %u\n " ), maxLedsOnBus , digitalCount);
182183 // we may remove 300 LEDs per bus limit when NeoPixelBus is updated beyond 2.9.0
183- if (/* oldType != -1 && */ maxLeds <= 300 && digitalCount > 5 ) {
184+ if (maxLedsOnBus <= 300 && digitalCount > 5 ) {
185+ DEBUG_PRINTLN (F (" Switching to parallel I2S." ));
184186 useParallel = true ;
185187 BusManager::useParallelOutput ();
186- DEBUG_PRINTF_P ( PSTR ( " Switching to parallel I2S with max. %d LEDs per ouptut. \n " ), maxLeds);
188+ mem = BusManager::memUsage (maxChannels, maxLedsOnBus, 8 ); // use alternate memory calculation
187189 }
188190 #endif
191+
189192 for (JsonObject elm : ins) {
190193 if (s >= WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES) break ;
191194 uint8_t pins[5 ] = {255 , 255 , 255 , 255 , 255 };
192195 JsonArray pinArr = elm[" pin" ];
193196 if (pinArr.size () == 0 ) continue ;
194- pins[0 ] = pinArr[0 ];
197+ // pins[0] = pinArr[0];
195198 unsigned i = 0 ;
196199 for (int p : pinArr) {
197200 pins[i++] = p;
198201 if (i>4 ) break ;
199202 }
200-
201203 uint16_t length = elm[" len" ] | 1 ;
202204 uint8_t colorOrder = (int )elm[F (" order" )]; // contains white channel swap option in upper nibble
203205 uint8_t skipFirst = elm[F (" skip" )];
@@ -208,7 +210,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
208210 bool refresh = elm[" ref" ] | false ;
209211 uint16_t freqkHz = elm[F (" freq" )] | 0 ; // will be in kHz for DotStar and Hz for PWM
210212 uint8_t AWmode = elm[F (" rgbwm" )] | RGBW_MODE_MANUAL_ONLY;
211- uint8_t maPerLed = elm[F (" ledma" )] | 55 ;
213+ uint8_t maPerLed = elm[F (" ledma" )] | LED_MILLIAMPS_DEFAULT ;
212214 uint16_t maMax = elm[F (" maxpwr" )] | (ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists
213215 // To disable brightness limiter we either set output max current to 0 or single LED current to 0 (we choose output max current)
214216 if (IS_PWM (ledType) || IS_ONOFF (ledType) || IS_VIRTUAL (ledType)) { // analog and virtual
@@ -219,26 +221,21 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
219221 if (fromFS) {
220222 BusConfig bc = BusConfig (ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
221223 if (useParallel && s < 8 ) {
222- // we are using parallel I2S and memUsage() will include x8 allocation into account
223- if (s == 0 )
224- mem = BusManager::memUsage (bc); // includes x8 memory allocation for parallel I2S
225- else
226- if (BusManager::memUsage (bc) > mem)
227- mem = BusManager::memUsage (bc); // if we have unequal LED count use the largest
224+ // if for some unexplained reason the above pre-calculation was wrong, update
225+ unsigned memT = BusManager::memUsage (bc); // includes x8 memory allocation for parallel I2S
226+ if (memT > mem) mem = memT; // if we have unequal LED count use the largest
228227 } else
229228 mem += BusManager::memUsage (bc); // includes global buffer
230229 if (mem <= MAX_LED_MEMORY) if (BusManager::add (bc) == -1 ) break ; // finalization will be done in WLED::beginStrip()
231230 } else {
232231 if (busConfigs[s] != nullptr ) delete busConfigs[s];
233232 busConfigs[s] = new BusConfig (ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
234- busesChanged = true ;
233+ doInitBusses = true ; // finalization done in beginStrip()
235234 }
236235 s++;
237236 }
238237 DEBUG_PRINTF_P (PSTR (" LED buffer size: %uB\n " ), mem);
239238 DEBUG_PRINTF_P (PSTR (" Heap after buses: %d\n " ), ESP.getFreeHeap ());
240- doInitBusses = busesChanged;
241- // finalization done in beginStrip()
242239 }
243240 if (hw_led[" rev" ]) BusManager::getBus (0 )->setReversed (true ); // set 0.11 global reversed setting for first bus
244241
@@ -275,22 +272,34 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
275272 btnPin[s] = pin;
276273 #ifdef ARDUINO_ARCH_ESP32
277274 // ESP32 only: check that analog button pin is a valid ADC gpio
278- if (((buttonType[s] == BTN_TYPE_ANALOG) || (buttonType[s] == BTN_TYPE_ANALOG_INVERTED)) && (digitalPinToAnalogChannel (btnPin[s]) < 0 ))
279- {
280- // not an ADC analog pin
281- DEBUG_PRINT (F (" PIN ALLOC error: GPIO" )); DEBUG_PRINT (btnPin[s]);
282- DEBUG_PRINT (F (" for analog button #" )); DEBUG_PRINT (s);
283- DEBUG_PRINTLN (F (" is not an analog pin!" ));
284- btnPin[s] = -1 ;
285- pinManager.deallocatePin (pin,PinOwner::Button);
275+ if ((buttonType[s] == BTN_TYPE_ANALOG) || (buttonType[s] == BTN_TYPE_ANALOG_INVERTED)) {
276+ if (digitalPinToAnalogChannel (btnPin[s]) < 0 ) {
277+ // not an ADC analog pin
278+ DEBUG_PRINT (F (" PIN ALLOC error: GPIO" )); DEBUG_PRINT (btnPin[s]);
279+ DEBUG_PRINT (F (" for analog button #" )); DEBUG_PRINT (s);
280+ DEBUG_PRINTLN (F (" is not an analog pin!" ));
281+ btnPin[s] = -1 ;
282+ pinManager.deallocatePin (pin,PinOwner::Button);
283+ } else {
284+ analogReadResolution (12 ); // see #4040
285+ }
286286 }
287- // if touch pin, enable the touch interrupt on ESP32 S2 & S3
288- #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so
289- if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH))
287+ else if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH))
290288 {
291- touchAttachInterrupt (btnPin[s], touchButtonISR, 256 + (touchThreshold << 4 )); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000)
289+ if (digitalPinToTouchChannel (btnPin[s]) < 0 ) {
290+ // not a touch pin
291+ DEBUG_PRINTF_P (PSTR (" PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n " ), btnPin[s], s);
292+ btnPin[s] = -1 ;
293+ pinManager.deallocatePin (pin,PinOwner::Button);
294+ }
295+ // if touch pin, enable the touch interrupt on ESP32 S2 & S3
296+ #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state but need to attach an interrupt to do so
297+ else
298+ {
299+ touchAttachInterrupt (btnPin[s], touchButtonISR, 256 + (touchThreshold << 4 )); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000)
300+ }
301+ #endif
292302 }
293- #endif
294303 else
295304 #endif
296305 {
0 commit comments