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.
62 lines
2.4 KiB
C
62 lines
2.4 KiB
C
#include "esp_event.h"
|
|
#include "esp_log.h"
|
|
#include "esp_system.h"
|
|
#include "nvs_flash.h"
|
|
#include "esp_netif.h"
|
|
|
|
#include "wifi_provisioning.h"
|
|
#include "frame_client.h"
|
|
|
|
static const char *TAG = "main";
|
|
|
|
void app_main(void)
|
|
{
|
|
/* Redirected/invalid captive-portal traffic generates a lot of noise
|
|
* at the default log level. */
|
|
esp_log_level_set("httpd_uri", ESP_LOG_ERROR);
|
|
esp_log_level_set("httpd_txrx", ESP_LOG_ERROR);
|
|
esp_log_level_set("httpd_parse", ESP_LOG_ERROR);
|
|
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
|
|
esp_err_t nvs_err = nvs_flash_init();
|
|
if (nvs_err == ESP_ERR_NVS_NO_FREE_PAGES || nvs_err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
nvs_err = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK(nvs_err);
|
|
|
|
/* ESP32-C6 (like most ESP32 variants) can't electrically distinguish
|
|
* the RST/EN button from a genuine power-on -- both report as
|
|
* ESP_RST_POWERON, since there's no separate external-reset-pin signal
|
|
* (see ESP_RST_EXT's doc comment). The device's only *normal* restart
|
|
* path is ESP_RST_DEEPSLEEP (its own scheduled timer wake); crash-type
|
|
* resets (brownout/watchdog/panic) report their own distinct reasons,
|
|
* not POWERON. So treating POWERON as "user wants to reconfigure" is
|
|
* safe: it won't fire on a scheduled wake or a transient crash, only
|
|
* on an actual power cycle or RST press -- which for this device
|
|
* plausibly means it's being moved/redeployed anyway. */
|
|
if (esp_reset_reason() == ESP_RST_POWERON) {
|
|
ESP_LOGI(TAG, "Power-on/RST reset -- entering provisioning to allow reconfiguration");
|
|
wifi_provisioning_start();
|
|
return;
|
|
}
|
|
|
|
frame_config_t cfg;
|
|
esp_err_t cfg_err = frame_config_load(&cfg);
|
|
if (cfg_err == ESP_OK) {
|
|
ESP_LOGI(TAG, "Found stored config for '%s', connecting to home WiFi", cfg.sta_ssid);
|
|
if (frame_wifi_connect_sta(&cfg) == ESP_OK) {
|
|
frame_client_run(&cfg);
|
|
return; /* frame_client_run currently never returns */
|
|
}
|
|
ESP_LOGW(TAG, "Could not connect to stored WiFi after %d attempts, falling back to provisioning",
|
|
CONFIG_FRAME_STA_CONNECT_MAX_RETRIES);
|
|
} else {
|
|
ESP_LOGI(TAG, "No stored config found (%s), starting provisioning", esp_err_to_name(cfg_err));
|
|
}
|
|
|
|
wifi_provisioning_start();
|
|
}
|