fix: harden firmware NVS persistence, WDT, and 304 epd_sleep
Three bugs fixed: - NVS img_id now written before epd_init/draw; new draw_needed flag in NVS survives power-loss mid-refresh so next boot re-draws from LittleFS instead of showing stale content - epd_sleep() now only called when display was initialized this cycle, preventing a 60 s wait_busy() timeout on every 304 poll - esp_task_wdt_reset() added to wait_busy() loop so the ~20 s 6-color refresh no longer triggers the task watchdog Also extracts normal_operation into operation.h template and adds a native PlatformIO test suite (16 tests) covering the full response matrix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
|
||||
// Minimal String class that mimics Arduino's String for native tests
|
||||
struct String {
|
||||
std::string _s;
|
||||
|
||||
String() {}
|
||||
String(const char* s) : _s(s ? s : "") {}
|
||||
String(const std::string& s) : _s(s) {}
|
||||
String(int v) { _s = std::to_string(v); }
|
||||
String(unsigned long v) { _s = std::to_string(v); }
|
||||
String(long long v) { _s = std::to_string(v); }
|
||||
String(unsigned long long v) { _s = std::to_string(v); }
|
||||
|
||||
const char* c_str() const { return _s.c_str(); }
|
||||
size_t length() const { return _s.size(); }
|
||||
bool isEmpty() const { return _s.empty(); }
|
||||
bool empty() const { return _s.empty(); }
|
||||
|
||||
int toInt() const { return _s.empty() ? 0 : std::stoi(_s); }
|
||||
|
||||
String substring(size_t from) const { return String(_s.substr(from)); }
|
||||
String substring(size_t from, size_t to) const { return String(_s.substr(from, to - from)); }
|
||||
|
||||
void replace(const char* from, const char* to_str) {
|
||||
std::string result;
|
||||
std::string f(from), t(to_str);
|
||||
size_t pos = 0, found;
|
||||
while ((found = _s.find(f, pos)) != std::string::npos) {
|
||||
result += _s.substr(pos, found - pos);
|
||||
result += t;
|
||||
pos = found + f.size();
|
||||
}
|
||||
result += _s.substr(pos);
|
||||
_s = result;
|
||||
}
|
||||
|
||||
void toUpperCase() {
|
||||
for (char& c : _s) c = (char)toupper((unsigned char)c);
|
||||
}
|
||||
|
||||
bool operator==(const String& o) const { return _s == o._s; }
|
||||
bool operator==(const char* o) const { return _s == o; }
|
||||
bool operator!=(const String& o) const { return _s != o._s; }
|
||||
bool operator!=(const char* o) const { return _s != o; }
|
||||
|
||||
String operator+(const String& o) const { return String(_s + o._s); }
|
||||
String operator+(const char* o) const { return String(_s + o); }
|
||||
String& operator+=(const String& o) { _s += o._s; return *this; }
|
||||
String& operator+=(const char* o) { _s += o; return *this; }
|
||||
|
||||
// Allow use as map key
|
||||
operator std::string() const { return _s; }
|
||||
|
||||
// toString() for IP-like objects that have it
|
||||
String toString() const { return *this; }
|
||||
};
|
||||
|
||||
inline String operator+(const char* a, const String& b) { return String(std::string(a) + b._s); }
|
||||
inline String operator+(const std::string& a, const String& b) { return String(a + b._s); }
|
||||
|
||||
// Controllable millis and digitalRead for timeout / button tests
|
||||
extern uint32_t g_millis_value;
|
||||
extern int g_digital_read_value;
|
||||
|
||||
#ifndef LOW
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
#endif
|
||||
|
||||
inline unsigned long millis() { return g_millis_value += 10; }
|
||||
inline void delay(unsigned long) {}
|
||||
inline void pinMode(int, int) {}
|
||||
inline int digitalRead(int) { return g_digital_read_value; }
|
||||
|
||||
// Color constants (from config.h)
|
||||
#define COLOR_YELLOW 0x2
|
||||
#define COLOR_RED 0x3
|
||||
|
||||
// Serial mock
|
||||
struct SerialMock {
|
||||
void begin(int) {}
|
||||
void println(const String&) {}
|
||||
void println(const char*) {}
|
||||
void println(int) {}
|
||||
void print(const String&) {}
|
||||
void print(const char*) {}
|
||||
void flush() {}
|
||||
} Serial;
|
||||
|
||||
// strtoull is available from <cstdlib> on native
|
||||
Reference in New Issue
Block a user