diff --git a/usermods/audioreactive/audio_reactive.cpp b/usermods/audioreactive/audio_reactive.cpp index a5ff961d59..15da96e0df 100644 --- a/usermods/audioreactive/audio_reactive.cpp +++ b/usermods/audioreactive/audio_reactive.cpp @@ -2071,6 +2071,13 @@ class AudioReactive : public Usermod { bool configComplete = !top.isNull(); bool oldEnabled = enabled; bool oldAddPalettes = addPalettes; + #ifdef ARDUINO_ARCH_ESP32 + auto oldDMType = dmType; + auto oldI2SsdPin = i2ssdPin; + auto oldI2swsPin = i2swsPin; + auto oldI2SckPin = i2sckPin; + auto oldI2SmclkPin = mclkPin; + #endif configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled); configComplete &= getJsonValue(top[FPSTR(_addPalettes)], addPalettes); @@ -2112,6 +2119,15 @@ class AudioReactive : public Usermod { // add/remove custom/audioreactive palettes if ((oldAddPalettes && !addPalettes) || (oldAddPalettes && !enabled)) removeAudioPalettes(); if ((addPalettes && !oldAddPalettes && enabled) || (addPalettes && !oldEnabled && enabled)) createAudioPalettes(); + #ifdef ARDUINO_ARCH_ESP32 + // notify user when a reboot is necessary + if ((audioSource != nullptr) && (oldDMType != dmType)) errorFlag = ERR_REBOOT_NEEDED; // changing mic type requires reboot + if ( (audioSource != nullptr) && (enabled==true) + && ((oldI2SsdPin != i2ssdPin) || (oldI2swsPin != i2swsPin) || (oldI2SckPin != i2sckPin)) ) errorFlag = ERR_REBOOT_NEEDED; // changing mic pins requires reboot + if ((audioSource != nullptr) && (oldI2SmclkPin != mclkPin)) errorFlag = ERR_REBOOT_NEEDED; // changing MCLK pin requires reboot + if ((oldDMType != dmType) && (oldDMType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing from analog mic requires power cycle + if ((oldDMType != dmType) && (dmType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing to analog mic requires power cycle + #endif } // else setup() will create palettes return configComplete; } diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 05f10493a1..8fc43f7694 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -1134,6 +1134,8 @@ void BusHub75Matrix::cleanup() { if (display != nullptr) delete display; display = nullptr; virtualDisp = nullptr; // note: when not using "NO_GFX" this causes a memory leak + #else // runtime reconfiguration is not working on -S3, request reboot from user instead + errorFlag = ERR_REBOOT_NEEDED; #endif if (_ledBuffer != nullptr) d_free(_ledBuffer); _ledBuffer = nullptr; if (_ledsDirty != nullptr) d_free(_ledsDirty); _ledsDirty = nullptr; diff --git a/wled00/const.h b/wled00/const.h index 1055942cb1..04ff8ded61 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -472,8 +472,17 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit"); #define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented) #define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented) #define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented) -#define ERR_REBOOT_NEEDED 98 // reboot needed after changing hardware setting -#define ERR_POWEROFF_NEEDED 99 // power-cycle needed after changing hardware setting +#define ERR_LOW_MEM 33 // low memory (RAM) +#define ERR_LOW_SEG_MEM 34 // low memory (effect data RAM) +#define ERR_LOW_WS_MEM 35 // low memory (ws) +//#define ERR_LOW_AJAX_MEM 36 // (not used any more) low memory (oappend) +#define ERR_LOW_BUF 37 // low memory (LED pixels buffer) +#define ERR_SYS_REBOOT 90 // reboot after error, trying to roll back +#define ERR_SYS_BROWNOUT 91 // reboot after brownout alert +#define ERR_PERSISTENT_THRESHOLD 100 // ToDO: errors below this value are non-persistent; persistent errors stay in the UI until restart +// ERR_PERSISTENT_THRESHOLD is a threshold value only - never assign directly to errorFlag +#define ERR_REBOOT_NEEDED 100 // reboot needed after changing hardware setting +#define ERR_POWEROFF_NEEDED 101 // power-cycle needed after changing hardware setting // JSON buffer lock owners #define JSON_LOCK_UNKNOWN 255 diff --git a/wled00/data/index.js b/wled00/data/index.js index ee5126973c..ef5129e69f 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1567,8 +1567,36 @@ function readState(s,command=false) case 19: errstr = "A filesystem error has occured."; break; +// error code from WLEDMM - not supported yet +// case 33: +// errstr = "Low Memory (generic RAM)."; +// break; +// case 34: +// errstr = "Low Memory (effect data)."; +// break; +// case 35: +// errstr = "Low Memory (WS data)."; +// break; +// case 36: +// errstr = "Low Memory (oappend buffer)."; +// break; +// case 37: +// errstr = "no memory for LEDs buffer."; +// break; + case 90: + errstr = "Unexpected Restart."; + break; + case 91: + errstr = "Brownout Restart."; + break; + case 100: + errstr = "Please reboot WLED to activate changed settings."; + break; + case 101: + errstr = "Please switch your device off and back on."; + break; } - showToast('Error ' + s.error + ": " + errstr, true); + showToast((s.error<100) ? 'Error ': 'Note ' + s.error + ": " + errstr, true); // show "please restart" as a note, all others as errors } selectedPal = i.pal; @@ -3597,4 +3625,4 @@ _C.addEventListener('touchstart', lock, false); _C.addEventListener('mouseout', move, false); _C.addEventListener('mouseup', move, false); -_C.addEventListener('touchend', move, false); \ No newline at end of file +_C.addEventListener('touchend', move, false); diff --git a/wled00/util.cpp b/wled00/util.cpp index 179310e117..20c934b0f1 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -8,6 +8,7 @@ #else #include #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + #include "rom/rtc.h" // for rtc_get_reset_reason() #include "esp32/rtc.h" // for bootloop detection #elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(3, 3, 0) #include "soc/rtc.h" @@ -998,6 +999,11 @@ RTC_NOINIT_ATTR static uint32_t bl_crashcounter; RTC_NOINIT_ATTR static uint32_t bl_actiontracker; static inline ResetReason rebootReason() { + // check RTC restart reason first - brownout is not reliably reported by esp_reset_reason() + if (rtc_get_reset_reason(0) == RTCWDT_BROWN_OUT_RESET) return ResetReason::Brownout; // core0 brownout + #if SOC_CPU_CORES_NUM > 1 + if (rtc_get_reset_reason(1) == RTCWDT_BROWN_OUT_RESET) return ResetReason::Brownout; // core1 brownout + #endif esp_reset_reason_t reason = esp_reset_reason(); if (reason == ESP_RST_BROWNOUT) return ResetReason::Brownout; if (reason == ESP_RST_SW) return ResetReason::Software; @@ -1032,6 +1038,7 @@ static bool detectBootLoop() { case ResetReason::Crash: { DEBUG_PRINTLN(F("crash detected!")); + errorFlag = ERR_SYS_REBOOT; uint32_t rebootinterval = rtctime - bl_last_boottime; if (rebootinterval < BOOTLOOP_INTERVAL_MILLIS) { bl_crashcounter++; @@ -1052,6 +1059,7 @@ static bool detectBootLoop() { case ResetReason::Brownout: // crash due to brownout can't be detected unless using flash memory to store bootloop variables DEBUG_PRINTLN(F("brownout detected")); + errorFlag = ERR_SYS_BROWNOUT; //restoreConfig(); // TODO: blindly restoring config if brownout detected is a bad idea, need a better way (if at all) break; }