Make Quick Power Cycle Detection Actually work

This commit is contained in:
Theo Arends 2020-08-13 16:25:48 +02:00
parent 731ca297b0
commit ef128fdafb

View File

@ -334,46 +334,62 @@ void SettingsSaveAll(void)
* Quick power cycle monitoring * Quick power cycle monitoring
\*********************************************************************************************/ \*********************************************************************************************/
void UpdateQuickPowerCycle(bool update) void UpdateQuickPowerCycle(bool update) {
{
#ifndef FIRMWARE_MINIMAL #ifndef FIRMWARE_MINIMAL
if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset
uint32_t pc_register; const uint32_t QPC_COUNT = 7; // Number of Power Cycles before Settings erase
uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES; const uint32_t QPC_SIGNATURE = 0xFFA55AFF;
#ifdef ESP8266 #ifdef ESP8266
ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); const uint32_t qpc_sector = SETTINGS_LOCATION - CFG_ROTATES;
#else // ESP32 const uint32_t qpc_location = qpc_sector * SPI_FLASH_SEC_SIZE;
QPCRead(&pc_register, sizeof(pc_register));
#endif // ESP8266 - ESP32 uint32_t qpc_buffer[QPC_COUNT +1];
if (update && ((pc_register & 0xFFFFFF80) == 0xFFA55A80)) { ESP.flashRead(qpc_location, (uint32*)&qpc_buffer, sizeof(qpc_buffer));
uint32_t counter = ((pc_register & 0x7F) << 1) & 0x7F; if (update && (QPC_SIGNATURE == qpc_buffer[0])) {
if (0 == counter) { // 7 power cycles in a row uint32_t counter = 1;
SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag while ((0 == qpc_buffer[counter]) && (counter <= QPC_COUNT)) { counter++; }
EspRestart(); // And restart if (QPC_COUNT == counter) { // 7 power cycles in a row
SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag
EspRestart(); // And restart
} else { } else {
pc_register = 0xFFA55AB0 | counter; qpc_buffer[0] = 0;
#ifdef ESP8266 ESP.flashWrite(qpc_location + (counter * 4), (uint32*)&qpc_buffer, 4);
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); AddLog_P2(LOG_LEVEL_INFO, PSTR("QPC: Count %d"), counter);
#else // ESP32
QPCWrite(&pc_register, sizeof(pc_register));
#endif // ESP8266 - ESP32
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter);
} }
} }
else if (pc_register != 0xFFA55AFF) { else if ((qpc_buffer[0] != QPC_SIGNATURE) || (0 == qpc_buffer[1])) {
pc_register = 0xFFA55AFF; qpc_buffer[0] = QPC_SIGNATURE;
#ifdef ESP8266
// Assume flash is default all ones and setting a bit to zero does not need an erase // Assume flash is default all ones and setting a bit to zero does not need an erase
if (ESP.flashEraseSector(pc_location)) { if (ESP.flashEraseSector(qpc_sector)) {
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); ESP.flashWrite(qpc_location, (uint32*)&qpc_buffer, 4);
AddLog_P2(LOG_LEVEL_INFO, PSTR("QPC: Reset"));
} }
#else // ESP32
QPCWrite(&pc_register, sizeof(pc_register));
#endif // ESP8266 - ESP32
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset"));
} }
#else // ESP32
uint32_t pc_register;
QPCRead(&pc_register, sizeof(pc_register));
if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AF0)) {
uint32_t counter = pc_register & 0xF; // Allow up to 15 cycles
if (0xF == counter) { counter = 0; }
counter++;
if (QPC_COUNT == counter) { // 7 power cycles in a row
SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag
EspRestart(); // And restart
} else {
pc_register = 0xFFA55AF0 | counter;
QPCWrite(&pc_register, sizeof(pc_register));
AddLog_P2(LOG_LEVEL_INFO, PSTR("QPC: Count %d"), counter);
}
}
else if (pc_register != QPC_SIGNATURE) {
pc_register = QPC_SIGNATURE;
QPCWrite(&pc_register, sizeof(pc_register));
AddLog_P2(LOG_LEVEL_INFO, PSTR("QPC: Reset"));
}
#endif // ESP8266 or ESP32
#endif // FIRMWARE_MINIMAL #endif // FIRMWARE_MINIMAL
} }
@ -556,6 +572,7 @@ void SettingsLoad(void) {
#ifdef ESP8266 #ifdef ESP8266
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate // Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
#ifdef CFG_LEGACY_LOAD #ifdef CFG_LEGACY_LOAD
// Active until version 8.4.0.2
struct { struct {
uint16_t cfg_holder; // 000 uint16_t cfg_holder; // 000
uint16_t cfg_size; // 002 uint16_t cfg_size; // 002
@ -598,11 +615,11 @@ void SettingsLoad(void) {
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag); AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
} }
#else // CFG_RESILIENT #else // CFG_RESILIENT
// Activated with version 8.4.0.2
settings_location = 0; settings_location = 0;
uint32_t save_flag = 0; uint32_t save_flag = 0;
uint32_t flash_location = SETTINGS_LOCATION +1; uint32_t flash_location = SETTINGS_LOCATION;
for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
flash_location--;
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) { if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) {
if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag
@ -613,6 +630,7 @@ void SettingsLoad(void) {
} }
} }
} }
flash_location--;
delay(1); delay(1);
} }
if (settings_location > 0) { if (settings_location > 0) {