From d5afd0bd8750cea07607779af65e5e477b4b5e65 Mon Sep 17 00:00:00 2001 From: Peter Woolery Date: Mon, 13 Apr 2026 14:02:28 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20config=20module=20=E2=80=94=20NVS=20rea?= =?UTF-8?q?d/write=20via=20Preferences?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add config.h/config.cpp for DeviceConfig NVS persistence using Arduino Preferences library. Add minimal main.cpp stub. Fix partition table overlap (nvs 0x6000→0x5000, otadata 0xf000→0xe000) so firmware builds. Co-Authored-By: Claude Sonnet 4.6 --- firmware/partitions_8mb_ota.csv | 4 +-- firmware/src/config.cpp | 48 +++++++++++++++++++++++++++++++++ firmware/src/config.h | 24 +++++++++++++++++ firmware/src/main.cpp | 3 +++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 firmware/src/config.cpp create mode 100644 firmware/src/config.h create mode 100644 firmware/src/main.cpp diff --git a/firmware/partitions_8mb_ota.csv b/firmware/partitions_8mb_ota.csv index 55d0f5c..fd51f8b 100644 --- a/firmware/partitions_8mb_ota.csv +++ b/firmware/partitions_8mb_ota.csv @@ -1,6 +1,6 @@ # Name, Type, SubType, Offset, Size -nvs, data, nvs, 0x9000, 0x6000 -otadata, data, ota, 0xf000, 0x2000 +nvs, data, nvs, 0x9000, 0x5000 +otadata, data, ota, 0xe000, 0x2000 app0, app, ota_0, 0x10000, 0x300000 app1, app, ota_1, 0x310000, 0x300000 spiffs, data, spiffs, 0x610000, 0x1F0000 diff --git a/firmware/src/config.cpp b/firmware/src/config.cpp new file mode 100644 index 0000000..1ae4a9e --- /dev/null +++ b/firmware/src/config.cpp @@ -0,0 +1,48 @@ +// firmware/src/config.cpp +#include "config.h" +#include + +static const char* NS = "doorcounter"; + +bool config_load(DeviceConfig& cfg) { + Preferences prefs; + prefs.begin(NS, true); // read-only + + cfg.device_id = prefs.getString("device_id", ""); + cfg.location_id = prefs.getString("location_id", ""); + cfg.hmac_secret = prefs.getString("hmac_secret", ""); + cfg.wifi_ssid = prefs.getString("wifi_ssid", ""); + cfg.wifi_pass = prefs.getString("wifi_pass", ""); + cfg.line_offset = (uint8_t)prefs.getUInt("line_offset", 50); + + prefs.end(); + + return !cfg.device_id.isEmpty() && + !cfg.location_id.isEmpty() && + !cfg.hmac_secret.isEmpty(); +} + +bool config_save_wifi(const String& ssid, const String& pass) { + Preferences prefs; + prefs.begin(NS, false); + bool ok = prefs.putString("wifi_ssid", ssid) && + prefs.putString("wifi_pass", pass); + prefs.end(); + return ok; +} + +bool config_has_wifi() { + Preferences prefs; + prefs.begin(NS, true); + String ssid = prefs.getString("wifi_ssid", ""); + prefs.end(); + return !ssid.isEmpty(); +} + +void config_clear_wifi() { + Preferences prefs; + prefs.begin(NS, false); + prefs.remove("wifi_ssid"); + prefs.remove("wifi_pass"); + prefs.end(); +} diff --git a/firmware/src/config.h b/firmware/src/config.h new file mode 100644 index 0000000..3e07891 --- /dev/null +++ b/firmware/src/config.h @@ -0,0 +1,24 @@ +// firmware/src/config.h +#pragma once +#include + +struct DeviceConfig { + String device_id; // e.g. "dc-0042" + String location_id; // e.g. "retailer-123" + String hmac_secret; // 32-byte hex string + String wifi_ssid; + String wifi_pass; + uint8_t line_offset; // 0-100, percent of frame height for virtual line +}; + +// Load all config from NVS. Returns false if device_id/location_id/hmac_secret missing. +bool config_load(DeviceConfig& cfg); + +// Save WiFi credentials to NVS (called by provisioning after captive portal). +bool config_save_wifi(const String& ssid, const String& pass); + +// Returns true if wifi_ssid is set in NVS. +bool config_has_wifi(); + +// Erase WiFi credentials only (factory reset — preserves device_id etc). +void config_clear_wifi(); diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp new file mode 100644 index 0000000..27f3768 --- /dev/null +++ b/firmware/src/main.cpp @@ -0,0 +1,3 @@ +#include +void setup() {} +void loop() {}