From 782563b3ae1301b91759bcdc8f7cfcea221f3be0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 16 Oct 2019 19:00:20 +0200 Subject: [PATCH] Add reset after four Quick Power Cycles Add reset after four Quick Power Cycles (#6639) --- sonoff/settings.ino | 35 +++++++++++++++++++++++++++++++++++ sonoff/sonoff.ino | 8 +++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 7109f20b1..4cb4e5b0d 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -360,6 +360,36 @@ void SettingsSaveAll(void) SettingsSave(0); } +/*********************************************************************************************\ + * Quick power cycle monitoring +\*********************************************************************************************/ + +void UpdateQuickPowerCycle(bool update) +{ + uint32_t pc_register; + uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES; + + ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); + if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) { + uint32_t counter = ((pc_register & 0xF) << 1) & 0xF; + if (0 == counter) { // 4 power cycles in a row + SettingsErase(2); // Quickly reset all settings including QuickPowerCycle flag + EspRestart(); // And restart + } else { + pc_register = 0xFFA55AB0 | counter; + ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter); // Won't show as too early in power on sequence + } + } + else if (pc_register != 0xFFA55ABF) { + pc_register = 0xFFA55ABF; + // Assume flash is default all ones and setting a bit to zero does not need an erase + ESP.flashEraseSector(pc_location); + ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset")); // Won't show as too early in power on sequence + } +} + /*********************************************************************************************\ * Config Save - Save parameters to Flash ONLY if any parameter has changed \*********************************************************************************************/ @@ -486,6 +516,7 @@ void SettingsErase(uint8_t type) /* 0 = Erase from program end until end of physical flash 1 = Erase SDK parameter area at end of linker memory model (0x0FDxxx - 0x0FFFFF) solving possible wifi errors + 2 = Erase Tasmota settings */ #ifndef FIRMWARE_MINIMAL @@ -497,6 +528,10 @@ void SettingsErase(uint8_t type) _sectorStart = SETTINGS_LOCATION +2; // SDK parameter area above EEPROM area (0x0FDxxx - 0x0FFFFF) _sectorEnd = SETTINGS_LOCATION +5; } + else if (2 == type) { + _sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota parameter area (0x0F4xxx - 0x0FBFFF) + _sectorEnd = SETTINGS_LOCATION +1; + } bool _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index f3bd8bed0..22fb2daf7 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -781,6 +781,7 @@ void PerformEverySecond(void) if (BOOT_LOOP_TIME == uptime) { RtcReboot.fast_reboot_count = 0; RtcRebootSave(); + UpdateQuickPowerCycle(false); Settings.bootcount++; // Moved to here to stop flash writes during start-up AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount); @@ -1471,7 +1472,10 @@ void setup(void) global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues RtcRebootLoad(); - if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; } + if (!RtcRebootValid()) { + RtcReboot.fast_reboot_count = 0; + UpdateQuickPowerCycle(true); // As RTC is invalid it must be a power cycle + } RtcReboot.fast_reboot_count++; RtcRebootSave(); @@ -1545,6 +1549,8 @@ void setup(void) } } +// UpdateQuickPowerCycle(true); // Test location + Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client)); Format(mqtt_topic, Settings.mqtt_topic, sizeof(mqtt_topic)); if (strstr(Settings.hostname, "%") != nullptr) {