mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-24 23:07:17 +00:00
Make Quick Power Cycle Detection Actually work
This commit is contained in:
parent
731ca297b0
commit
ef128fdafb
@ -334,46 +334,62 @@ void SettingsSaveAll(void)
|
||||
* Quick power cycle monitoring
|
||||
\*********************************************************************************************/
|
||||
|
||||
void UpdateQuickPowerCycle(bool update)
|
||||
{
|
||||
void UpdateQuickPowerCycle(bool update) {
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset
|
||||
|
||||
uint32_t pc_register;
|
||||
uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES;
|
||||
const uint32_t QPC_COUNT = 7; // Number of Power Cycles before Settings erase
|
||||
const uint32_t QPC_SIGNATURE = 0xFFA55AFF;
|
||||
|
||||
#ifdef ESP8266
|
||||
ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else // ESP32
|
||||
QPCRead(&pc_register, sizeof(pc_register));
|
||||
#endif // ESP8266 - ESP32
|
||||
if (update && ((pc_register & 0xFFFFFF80) == 0xFFA55A80)) {
|
||||
uint32_t counter = ((pc_register & 0x7F) << 1) & 0x7F;
|
||||
if (0 == counter) { // 7 power cycles in a row
|
||||
SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag
|
||||
EspRestart(); // And restart
|
||||
const uint32_t qpc_sector = SETTINGS_LOCATION - CFG_ROTATES;
|
||||
const uint32_t qpc_location = qpc_sector * SPI_FLASH_SEC_SIZE;
|
||||
|
||||
uint32_t qpc_buffer[QPC_COUNT +1];
|
||||
ESP.flashRead(qpc_location, (uint32*)&qpc_buffer, sizeof(qpc_buffer));
|
||||
if (update && (QPC_SIGNATURE == qpc_buffer[0])) {
|
||||
uint32_t counter = 1;
|
||||
while ((0 == qpc_buffer[counter]) && (counter <= QPC_COUNT)) { 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 = 0xFFA55AB0 | counter;
|
||||
#ifdef ESP8266
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else // ESP32
|
||||
QPCWrite(&pc_register, sizeof(pc_register));
|
||||
#endif // ESP8266 - ESP32
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter);
|
||||
qpc_buffer[0] = 0;
|
||||
ESP.flashWrite(qpc_location + (counter * 4), (uint32*)&qpc_buffer, 4);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("QPC: Count %d"), counter);
|
||||
}
|
||||
}
|
||||
else if (pc_register != 0xFFA55AFF) {
|
||||
pc_register = 0xFFA55AFF;
|
||||
#ifdef ESP8266
|
||||
else if ((qpc_buffer[0] != QPC_SIGNATURE) || (0 == qpc_buffer[1])) {
|
||||
qpc_buffer[0] = QPC_SIGNATURE;
|
||||
// Assume flash is default all ones and setting a bit to zero does not need an erase
|
||||
if (ESP.flashEraseSector(pc_location)) {
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
if (ESP.flashEraseSector(qpc_sector)) {
|
||||
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
|
||||
}
|
||||
|
||||
@ -556,6 +572,7 @@ void SettingsLoad(void) {
|
||||
#ifdef ESP8266
|
||||
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
|
||||
#ifdef CFG_LEGACY_LOAD
|
||||
// Active until version 8.4.0.2
|
||||
struct {
|
||||
uint16_t cfg_holder; // 000
|
||||
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);
|
||||
}
|
||||
#else // CFG_RESILIENT
|
||||
// Activated with version 8.4.0.2
|
||||
settings_location = 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
|
||||
flash_location--;
|
||||
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.save_flag > save_flag) { // Find latest page based on incrementing save_flag
|
||||
@ -613,6 +630,7 @@ void SettingsLoad(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
flash_location--;
|
||||
delay(1);
|
||||
}
|
||||
if (settings_location > 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user