Merge branch 'mdev' into audio_fastpath
This commit is contained in:
@@ -879,6 +879,7 @@ build_flags_XL =
|
||||
; -D USERMOD_SHT ;; experimental
|
||||
-D USERMOD_VL53L0X_GESTURES
|
||||
-D WLED_ENABLE_PIXART
|
||||
-D USERMOD_ANIMARTRIX ; WLEDMM usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick
|
||||
|
||||
lib_deps_XL =
|
||||
claws/BH1750 @^1.2.0 ; used for USERMOD_BH1750
|
||||
|
||||
@@ -727,7 +727,7 @@ class WS2812FX { // 96 bytes
|
||||
_cumulativeFps500(2*500), // WLEDMM more accurate FPS measurement for ESP32
|
||||
_lastShow500(0),
|
||||
#endif
|
||||
_isServicing(false),
|
||||
_isServicing(true), // WLEDMM start with "true" - flag will be reset by strip.finalizeInit()
|
||||
_isOffRefreshRequired(false),
|
||||
_hasWhiteChannel(false),
|
||||
_triggered(false),
|
||||
@@ -766,6 +766,7 @@ class WS2812FX { // 96 bytes
|
||||
printSize(),
|
||||
#endif
|
||||
finalizeInit(),
|
||||
waitUntilIdle(void), // WLEDMM
|
||||
service(void),
|
||||
setMode(uint8_t segid, uint8_t m),
|
||||
setColor(uint8_t slot, uint32_t c),
|
||||
|
||||
@@ -1424,6 +1424,7 @@ void WS2812FX::enumerateLedmaps() {
|
||||
void WS2812FX::finalizeInit(void)
|
||||
{
|
||||
//reset segment runtimes
|
||||
suspendStripService = true; // WELDMM avoid running effects on an incomplete strip
|
||||
for (segment &seg : _segments) {
|
||||
seg.markForReset();
|
||||
seg.resetIfRequired();
|
||||
@@ -1503,6 +1504,27 @@ void WS2812FX::finalizeInit(void)
|
||||
loadCustomPalettes(); // (re)load all custom palettes
|
||||
DEBUG_PRINTLN(F("Loading custom ledmaps"));
|
||||
deserializeMap(); // (re)load default ledmap
|
||||
_isServicing = false; // WLEDMM
|
||||
suspendStripService = false; // WELDMM ready, run !
|
||||
}
|
||||
|
||||
// WLEDMM wait until strip is idle (=not servicing).
|
||||
// on 8266 this function does nothing, because we can only do "buisy waiting" on ESP32
|
||||
#define MAX_IDLE_WAIT_MS 50 // seems to work in most cases
|
||||
void WS2812FX::waitUntilIdle(void) {
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (isServicing()) {
|
||||
unsigned long waitStarted = millis();
|
||||
do {
|
||||
delay(1);
|
||||
yield();
|
||||
} while (isServicing() && (millis() - waitStarted < MAX_IDLE_WAIT_MS));
|
||||
USER_PRINTF("strip.waitUntilIdle(): strip %sidle after %d ms. (task %s)\n", isServicing()?"not ":"", int(millis() - waitStarted), pcTaskGetTaskName(NULL));
|
||||
}
|
||||
return;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::service() {
|
||||
|
||||
@@ -90,6 +90,19 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
// initialize LED pins and lengths prior to other HW (except for ethernet)
|
||||
JsonObject hw_led = hw["led"];
|
||||
|
||||
// WLEDMM: before changing strip, make sure our strip is _not_ servicing effects in parallel
|
||||
suspendStripService = true; // temporarily lock out strip updates
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (strip.isServicing() && (strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) != 0)) { // if we are in looptask (arduino loop), its safe to proceed without waiting
|
||||
if (fromFS) {
|
||||
USER_PRINTLN(F("deserializeConfig(fromFS): strip is still drawing effects, waiting ..."));
|
||||
} else {
|
||||
USER_PRINTLN(F("deserializeConfig(): strip is still drawing effects, waiting ..."));
|
||||
}
|
||||
strip.waitUntilIdle();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t autoWhiteMode = RGBW_MODE_MANUAL_ONLY;
|
||||
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
||||
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
||||
@@ -599,6 +612,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
needsSave = !usermods.readFromConfig(usermods_settings);
|
||||
}
|
||||
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
|
||||
if (fromFS) return needsSave;
|
||||
// if from /json/cfg
|
||||
doReboot = doc[F("rb")] | doReboot;
|
||||
|
||||
@@ -85,8 +85,15 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
id = strip.getSegmentsNum()-1; // segments are added at the end of list
|
||||
}
|
||||
|
||||
// WLEDMM: before changing segments, make sure our strip is _not_ servicing effects in parallel
|
||||
suspendStripService = true; // temporarily lock out strip updates
|
||||
if (strip.isServicing()) {
|
||||
USER_PRINTLN(F("deserializeSegment(): strip is still drawing effects, waiting ..."));
|
||||
strip.waitUntilIdle();
|
||||
}
|
||||
|
||||
Segment& seg = strip.getSegment(id);
|
||||
Segment prev = seg; //make a backup so we can tell if something changed
|
||||
Segment prev = seg; //make a backup so we can tell if something changed // WLEDMM fixMe: copy constructor = waste of memory
|
||||
|
||||
uint16_t start = elem["start"] | seg.start;
|
||||
if (stop < 0) {
|
||||
@@ -113,6 +120,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
elem["rev"] = !elem["rev"]; // alternate reverse on even/odd segments
|
||||
deserializeSegment(elem, i, presetId); // recursive call with new id
|
||||
}
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -153,7 +161,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (map1D2D != M12_jMap && seg.jMap)
|
||||
seg.deletejMap();
|
||||
|
||||
if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.fill(BLACK); // clear spacing gaps
|
||||
if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.fill(BLACK); // clear spacing gaps // WLEDMM softhack007: this line sometimes crashes with "Stack canary watchpoint triggered (async_tcp)"
|
||||
|
||||
seg.map1D2D = constrain(map1D2D, 0, 7);
|
||||
seg.soundSim = constrain(soundSim, 0, 7);
|
||||
@@ -170,7 +178,10 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (stop > start && of > len -1) of = len -1;
|
||||
seg.set(start, stop, grp, spc, of, startY, stopY);
|
||||
|
||||
if (seg.reset && seg.stop == 0) return true; // segment was deleted & is marked for reset, no need to change anything else
|
||||
if (seg.reset && seg.stop == 0) {
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
return true; // segment was deleted & is marked for reset, no need to change anything else
|
||||
}
|
||||
|
||||
byte segbri = seg.opacity;
|
||||
if (getVal(elem["bri"], &segbri)) {
|
||||
@@ -293,7 +304,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
// freeze and init to black
|
||||
if (!seg.freeze) {
|
||||
seg.freeze = true;
|
||||
seg.fill(BLACK);
|
||||
seg.fill(BLACK); // WLEDMM why now?
|
||||
}
|
||||
|
||||
uint16_t start = 0, stop = 0;
|
||||
@@ -334,6 +345,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
// send UDP/WS if segment options changed (except selection; will also deselect current preset)
|
||||
if (seg.differs(prev) & 0x7F) stateChanged = true;
|
||||
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -389,6 +401,13 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
// WLEDMM: before changing strip, make sure our strip is _not_ servicing effects in parallel
|
||||
suspendStripService = true; // temporarily lock out strip updates
|
||||
if (strip.isServicing()) {
|
||||
USER_PRINTLN(F("deserializeState(): strip is still drawing effects, waiting ..."));
|
||||
strip.waitUntilIdle();
|
||||
}
|
||||
|
||||
// temporary transition (applies only once)
|
||||
tr = root[F("tt")] | -1;
|
||||
if (tr >= 0)
|
||||
@@ -505,6 +524,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
presetCycCurr = ps;
|
||||
unloadPlaylist(); // applying a preset unloads the playlist
|
||||
applyPreset(ps, callMode); // async load from file system (only preset ID was specified)
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
return stateResponse;
|
||||
}
|
||||
}
|
||||
@@ -528,6 +548,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
stateUpdated(callMode);
|
||||
if (presetToRestore) currentPreset = presetToRestore;
|
||||
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
return stateResponse;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,15 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 7: DMX 8: usermods 9: N/A 10: 2D
|
||||
if (subPage <1 || subPage >10 || !correctPIN) return;
|
||||
|
||||
// WLEDMM: before changing bus or strip settings, make sure our strip is _not_ servicing effects in parallel
|
||||
if ((subPage == 2) || (subPage == 10)) {
|
||||
suspendStripService = true; // temporarily lock out strip updates
|
||||
if (strip.isServicing()) {
|
||||
USER_PRINTLN(F("handleSettingsSet(): strip is still drawing effects, waiting ..."));
|
||||
strip.waitUntilIdle();
|
||||
}
|
||||
}
|
||||
|
||||
//WIFI SETTINGS
|
||||
if (subPage == 1)
|
||||
{
|
||||
@@ -766,6 +775,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((subPage == 2) || (subPage == 10)) {
|
||||
suspendStripService = false; // WLEDMM release lock
|
||||
}
|
||||
|
||||
lastEditTime = millis();
|
||||
if (subPage != 2 && !doReboot) doSerializeConfig = true; //serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
@@ -802,6 +815,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
}
|
||||
|
||||
// WLEDMM: before changing segment settings, make sure our strip is _not_ servicing effects in parallel
|
||||
if (strip.isServicing()) {
|
||||
USER_PRINTLN(F("handleSet(): strip is still drawing effects, waiting ..."));
|
||||
strip.waitUntilIdle();
|
||||
}
|
||||
|
||||
Segment& selseg = strip.getSegment(selectedSeg);
|
||||
pos = req.indexOf(F("SV=")); //segment selected
|
||||
if (pos > 0) {
|
||||
|
||||
@@ -164,8 +164,17 @@ void WLED::loop()
|
||||
#ifdef WLED_DEBUG
|
||||
unsigned long stripMillis = millis();
|
||||
#endif
|
||||
if (!offMode || strip.isOffRefreshRequired())
|
||||
strip.service();
|
||||
if (!offMode || strip.isOffRefreshRequired()) {
|
||||
static unsigned long lastTimeService = 0; // WLEMM needed to remove stale lock
|
||||
if (!suspendStripService && !doInitBusses && !loadLedmap) { // WLEDMM prevent effect drawing while strip or segments are being updated
|
||||
strip.service();
|
||||
lastTimeService = millis();
|
||||
} else {
|
||||
if (suspendStripService && (millis() - lastTimeService > 1500)) { // WLEDMM remove stale lock after 1.5 seconds
|
||||
USER_PRINTLN("--> looptask: stale suspendStripService lock removed after 1500 ms."); // should not happen - check for missing "suspendStripService = false"
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ESP8266
|
||||
else if (!noWifiSleep)
|
||||
delay(1); //required to make sure ESP enters modem sleep (see #1184)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2305301
|
||||
#define VERSION 2306010
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@@ -690,9 +690,11 @@ WLED_GLOBAL bool e131NewData _INIT(false);
|
||||
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 bool doInitBusses _INIT(false);
|
||||
WLED_GLOBAL bool loadLedmap _INIT(false); //WLEDMM use as bool and use loadedLedmap for Nr
|
||||
WLED_GLOBAL uint8_t loadedLedmap _INIT(0); //WLEDMM default 0
|
||||
// WLEDMM a few "poor man's" mutal exclusion (mutex) flags, because there are not mutex objects on 8266.
|
||||
WLED_GLOBAL volatile bool doInitBusses _INIT(false); // WLEDMM "volatile" added - needed as we want to sync parallel tasks
|
||||
WLED_GLOBAL volatile bool loadLedmap _INIT(false); // WLEDMM use as bool and use loadedLedmap for Nr
|
||||
WLED_GLOBAL volatile uint8_t loadedLedmap _INIT(0); // WLEDMM default 0
|
||||
WLED_GLOBAL volatile bool suspendStripService _INIT(false); // WLEDMM temporarily prevent running strip.service, when strip or segments are "under update" and inconsistent
|
||||
#ifndef ESP8266
|
||||
WLED_GLOBAL char *ledmapNames[WLED_MAX_LEDMAPS-1] _INIT_N(({nullptr}));
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user