Add reset after four Quick Power Cycles

Add reset after four Quick Power Cycles (#6639)
This commit is contained in:
Theo Arends 2019-10-16 19:00:20 +02:00
parent a3c0451e41
commit 782563b3ae
2 changed files with 42 additions and 1 deletions

View File

@ -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);

View File

@ -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) {