diff --git a/mLRS/Common/hal/esp-powerup.h b/mLRS/Common/hal/esp-powerup.h index 1fdab1804..6cc49517f 100644 --- a/mLRS/Common/hal/esp-powerup.h +++ b/mLRS/Common/hal/esp-powerup.h @@ -9,9 +9,6 @@ #define ESP_POWERUP_CNT_H #pragma once -// Needs more work to implement on ESP8266 -// Needed for entering bind mode with rapid power cycles - #include @@ -22,6 +19,75 @@ typedef enum { } POWERUPCNT_TASK_ENUM; +// ESP32 only: EEPROM.commit() is NVS-backed with wear leveling. +// On ESP8266 commit() does a raw sector erase, so not implemented. +#ifdef ESP32 + +#define POWERUPCNT_TMO_MS 2000 +#define POWERUPCNT_BIND_COUNT 4 + + +class tPowerupCounter +{ + public: + void Init(void); + void Do(void); + uint8_t Task(void); + + private: + bool powerup_do; + uint8_t task; +}; + + +void tPowerupCounter::Init(void) +{ + powerup_do = true; + task = POWERUPCNT_TASK_NONE; + + uint8_t count = EEPROM.read(POWERUPCNT_EE_ADDRESS); + + if (count > POWERUPCNT_BIND_COUNT) count = 0; // sanitize, e.g. first use is 0xFF + + count++; + + if (count >= POWERUPCNT_BIND_COUNT) { + task = POWERUPCNT_TASK_BIND; + powerup_do = false; + count = 0; + } + + EEPROM.write(POWERUPCNT_EE_ADDRESS, count); + EEPROM.commit(); +} + + +void tPowerupCounter::Do(void) +{ + if (!powerup_do) return; + + uint32_t tnow_ms = millis32(); + if (tnow_ms < POWERUPCNT_TMO_MS) return; + + powerup_do = false; + + EEPROM.write(POWERUPCNT_EE_ADDRESS, 0); + EEPROM.commit(); +} + + +uint8_t tPowerupCounter::Task(void) +{ + switch (task) { + case POWERUPCNT_TASK_BIND: + task = POWERUPCNT_TASK_NONE; + return POWERUPCNT_TASK_BIND; + } + + return POWERUPCNT_TASK_NONE; +} + +#else // ESP8266 class tPowerupCounter { @@ -31,5 +97,7 @@ class tPowerupCounter uint8_t Task(void) { return POWERUPCNT_TASK_NONE; } }; +#endif + -#endif // ESP_POWERUP_CNT +#endif // ESP_POWERUP_CNT_H diff --git a/mLRS/modules/esp-lib/esp-eeprom.h b/mLRS/modules/esp-lib/esp-eeprom.h index 214536a6c..f2002b692 100644 --- a/mLRS/modules/esp-lib/esp-eeprom.h +++ b/mLRS/modules/esp-lib/esp-eeprom.h @@ -30,9 +30,9 @@ typedef enum { EE_STATUS_OK } EE_STATUS_ENUM; -// ESP8266 has 4kb available for EEPROM. We need 3 pages, 2 for setup and -// 1 for the powerup counter. So best to keep page size to 3kb to let it -// fit in. +// ESP8266 only has 4kb available for EEPROM, so we use 2 pages of 1kb each. +// Powerup counter is only implemented on ESP32 as EEPROM is NVS-backed with +// wear leveling, whereas on ESP8266, each commit erases a raw flash sector. #define EE_START_PAGE 0 #define EE_PAGE_SIZE 0x0400 // Page size = 1 KByte @@ -49,6 +49,8 @@ typedef enum { #define EE_START_PAGE0 ((uint32_t)(EE_START_PAGE)) #define EE_START_PAGE1 ((uint32_t)(EE_START_PAGE + 1)) +#define POWERUPCNT_EE_ADDRESS (EE_PAGE_SIZE * 2) // = 0x0800 + // Page status definitions stored in EEPROM #define EE_ERASE ((uint32_t)0xFFFFFFFF) // PAGE is erased, may not be completely erased in case of an error #define EE_VALID_PAGE ((uint32_t)0x11111111) // PAGE containing valid data @@ -228,7 +230,11 @@ EE_STATUS_ENUM status; EE_STATUS_ENUM ee_init(void) { +#ifdef ESP32 + EEPROM.begin(EE_PAGE_SIZE*2 + 4); // +4 for powerup counter byte +#else EEPROM.begin(EE_PAGE_SIZE*2); +#endif EE_STATUS_ENUM status; uint32_t Page0Status, Page1Status;