RST/power-on trigger: checks esp_reset_reason() at the very top of boot. ESP32-C6 can't electrically distinguish the RST/EN button from a genuine power-on (both report ESP_RST_POWERON -- confirmed against ESP-IDF's own docs, ESP_RST_EXT is explicitly "not applicable"), so POWERON is treated as "user wants to reconfigure" and routes straight to provisioning. Safe because the device's only normal restart path is ESP_RST_DEEPSLEEP (its own scheduled wake), and crash-type resets (brownout/watchdog/panic) report their own distinct reasons, not POWERON -- so a flaky power supply or transient crash won't get bounced into provisioning, only an actual power cycle or RST press will (which plausibly means the frame is being moved/redeployed anyway). Auto-fallback: a new NVS-persisted consecutive-failure counter (frame_config_record_server_failure/reset_server_failures) tracks wakes where the tools server was unreachable. After CONFIG_FRAME_REPROVISION_AFTER_FAILURES in a row (default 12, ~1hr at the retry interval), the device clears its stored WiFi config and esp_restart()s rather than calling wifi_provisioning_start() directly -- doing that inline would mean initializing the display driver a second time in the same session (frame_client_run already did once), the same class of double-init bug hit earlier with WiFi. The next boot's frame_config_load() naturally reports "not provisioned" and routes through the existing, already-tested provisioning path with a single fresh epd_init(). Solves the "I moved the server to a new address" case without needing USB access. Both frame_config_save() (fresh provisioning) and any successful server contact reset the failure counter.
75 lines
2.7 KiB
C
75 lines
2.7 KiB
C
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include "esp_err.h"
|
|
|
|
#define FRAME_CFG_SSID_MAX_LEN 32
|
|
#define FRAME_CFG_PASSWORD_MAX_LEN 64
|
|
#define FRAME_CFG_SERVER_MAX_LEN 128
|
|
#define FRAME_AP_PASSWORD_LEN 10
|
|
|
|
typedef struct {
|
|
char sta_ssid[FRAME_CFG_SSID_MAX_LEN + 1];
|
|
char sta_password[FRAME_CFG_PASSWORD_MAX_LEN + 1];
|
|
char toolsserver[FRAME_CFG_SERVER_MAX_LEN + 1];
|
|
} frame_config_t;
|
|
|
|
/**
|
|
* Loads the saved home-network config from NVS.
|
|
* Returns ESP_ERR_NVS_NOT_FOUND if the device has never been provisioned.
|
|
*/
|
|
esp_err_t frame_config_load(frame_config_t *out);
|
|
|
|
/** Saves the home-network config to NVS. Resets the "connected once"
|
|
* flag below, since this is a fresh (re)provisioning event. */
|
|
esp_err_t frame_config_save(const frame_config_t *cfg);
|
|
|
|
/**
|
|
* Whether the device has already shown the post-connect status screen at
|
|
* least once since the current WiFi config was saved. Used so the status
|
|
* screen always shows on the first connection after (re)provisioning, but
|
|
* is skipped on later successful wakes to save an extra refresh.
|
|
*/
|
|
bool frame_config_has_connected_once(void);
|
|
|
|
/** Marks the status screen as having been shown for the current WiFi config. */
|
|
void frame_config_mark_connected_once(void);
|
|
|
|
/**
|
|
* Increments the persisted count of consecutive wakes where the tools
|
|
* server was unreachable. Returns true once it reaches
|
|
* CONFIG_FRAME_REPROVISION_AFTER_FAILURES, signaling the caller should
|
|
* fall back to provisioning instead of just retrying again.
|
|
*/
|
|
bool frame_config_record_server_failure(void);
|
|
|
|
/** Resets the consecutive-server-failure count. Call on any successful
|
|
* contact with the tools server. */
|
|
void frame_config_reset_server_failures(void);
|
|
|
|
/**
|
|
* Erases the saved home-network config (SSID/password/toolsserver) so the
|
|
* next boot's frame_config_load() reports "not provisioned" and falls
|
|
* back into provisioning. Doesn't touch the AP password or other
|
|
* device-identity state. Follow with esp_restart() -- doesn't itself
|
|
* bring up provisioning, since that would mean initializing the display
|
|
* driver a second time in a session that may have already done so.
|
|
*/
|
|
esp_err_t frame_config_clear(void);
|
|
|
|
/**
|
|
* Returns this device's provisioning AP identity: a fixed SSID (from
|
|
* Kconfig) and a password that's generated once on first use and persisted
|
|
* in NVS from then on. The password is drawn from an easy-to-type charset
|
|
* since it's shown on the e-ink panel (as both a QR code and plaintext) and
|
|
* may need to be typed in by hand.
|
|
*/
|
|
void ap_identity_get(char *ssid_out, size_t ssid_len, char *pass_out, size_t pass_len);
|
|
|
|
/**
|
|
* Brings up the ESPRESSO softAP + captive portal (DNS + HTTP) so the user
|
|
* can provision the device. Does not return.
|
|
*/
|
|
void wifi_provisioning_start(void);
|