Build and push server image / build-and-push (push) Successful in 37s
All firmware-related controls (manual upload, Gitea repo URL, auto-update checkbox, detected board, Update frame button) now live in one "Firmware update" card instead of being split across the main Settings form and a separate card. The board variant used to pick a Gitea release asset was a dropdown the user had to set by hand and could get wrong. The device now reports it itself via a new X-Frame-Board header (CONFIG_FRAME_BOARD_NAME, "devkit" by default, "xiao" in sdkconfig.xiao) on every /frame/config poll, stored as device_board_variant -- the server learns it instead. Update checks/applies are gated on the board being known, since there's nothing to fetch until a device has checked in at least once.
225 lines
11 KiB
Plaintext
225 lines
11 KiB
Plaintext
menu "ESPresso Frame Configuration"
|
|
|
|
config FRAME_BOARD_NAME
|
|
string "Board variant name, reported to the server"
|
|
default "devkit"
|
|
help
|
|
Sent as the X-Frame-Board request header on every
|
|
GET /frame/config poll, so the server can learn which board
|
|
this device is and automatically fetch the right OTA build
|
|
from a configured Gitea repo's releases -- no manual "which
|
|
board" picker in the web UI. Must match one of the asset
|
|
names .gitea/workflows/firmware-release-build.yml publishes
|
|
(firmware-<name>.bin): "devkit" (this default, for the
|
|
plain ESP32-C6-DevKitC-1 build) or "xiao" (set via
|
|
sdkconfig.xiao for the Seeed XIAO ESP32-C6 build -- see
|
|
build_for_board.sh).
|
|
|
|
config FRAME_XIAO_ANTENNA_INIT
|
|
bool "Select onboard antenna on Seeed XIAO ESP32-C6 (RF switch init)"
|
|
default n
|
|
help
|
|
The XIAO ESP32-C6 routes its antenna through an FM8625H RF
|
|
switch (GPIO3 = switch power enable, GPIO14 = antenna
|
|
select) so it can optionally use an external u.FL antenna
|
|
instead of the onboard ceramic one. Seeed's own Arduino
|
|
board package powers the switch and selects the onboard
|
|
antenna automatically at boot; plain ESP-IDF (what this
|
|
firmware uses) does not -- without this, the switch's
|
|
GPIOs are left floating and the radio may not reliably
|
|
reach the onboard antenna at all. Symptom: a softAP (or
|
|
STA connection) that starts successfully in the log but
|
|
is never actually visible/reachable over the air. Enabled
|
|
by default in sdkconfig.xiao; leave off for the DevKitC-1
|
|
dev board, which has no such switch.
|
|
|
|
config ESP_AP_SSID
|
|
string "Provisioning softAP SSID prefix"
|
|
default "ESPRESSO"
|
|
help
|
|
SSID prefix of the softAP the device brings up when it needs
|
|
provisioning; the device appends "_XXXXXX" (last 3 bytes of its
|
|
WiFi MAC) so multiple frames never collide on the same SSID.
|
|
The password is generated randomly per device on first boot and
|
|
shown on the e-ink panel both as a WiFi-join QR code and as
|
|
plaintext underneath it, so it can be typed in by hand on a
|
|
desktop/laptop that can't scan the QR.
|
|
|
|
config ESP_MAX_STA_CONN
|
|
int "Maximal STA connections"
|
|
default 4
|
|
range 1 4 if IDF_TARGET_ESP32C2
|
|
range 1 15
|
|
help
|
|
Maximum number of STAs allowed to connect to the soft-AP (wifi_config_t.ap.max_connection).
|
|
Upper bound matches ESP_WIFI_MAX_CONN_NUM in esp_wifi_types_native.h:
|
|
1-4 on ESP32-C2, 1-15 on other Wi-Fi chips.
|
|
Soft-AP and ESP-NOW share encryption keys; see Wi-Fi driver documentation
|
|
if ESP-NOW is enabled.
|
|
|
|
config ESP_ENABLE_DHCP_CAPTIVEPORTAL
|
|
bool "DHCP Captive portal"
|
|
default y
|
|
help
|
|
Enables more modern DHCP-based Option 114 to provide clients with the captive portal URI
|
|
|
|
config FRAME_STA_CONNECT_MAX_RETRIES
|
|
int "Home WiFi connect max retries before falling back to provisioning"
|
|
default 3
|
|
help
|
|
Number of failed connection attempts to the stored home WiFi network
|
|
before the device gives up and re-enters provisioning (softAP) mode.
|
|
|
|
config FRAME_STA_CONNECT_TIMEOUT_MS
|
|
int "Home WiFi connect timeout per attempt (ms)"
|
|
default 15000
|
|
help
|
|
How long to wait for an IP address on each connection attempt to the
|
|
stored home WiFi network before counting it as a failed retry.
|
|
|
|
config FRAME_SERVER_CHECK_TIMEOUT_MS
|
|
int "Tools server /frame/config request timeout (ms)"
|
|
default 3000
|
|
help
|
|
How long to wait for a GET /frame/config response from the
|
|
tools server -- doubles as both the reachability check for the
|
|
post-connect status screen and the source of the
|
|
server-configured refresh interval below.
|
|
|
|
config FRAME_FETCH_TIMEOUT_MS
|
|
int "Image fetch HTTP timeout (ms)"
|
|
default 15000
|
|
help
|
|
How long to wait on the GET /frame/image request before giving
|
|
up. The server does real work per request (Immich download +
|
|
resize + dither), so this is longer than the reachability
|
|
check's timeout.
|
|
|
|
config FRAME_SLEEP_INTERVAL_S
|
|
int "Fallback deep sleep interval between refreshes (seconds)"
|
|
default 3600
|
|
help
|
|
The refresh interval is normally set server-side (the "Refresh
|
|
interval" field in the server's web UI, delivered via GET
|
|
/frame/config) so it can be changed without reflashing. This
|
|
value is only a fallback: used before the device has ever
|
|
successfully reached a configured server, or if the server's
|
|
response doesn't include a valid interval (e.g. an older
|
|
server version). Lower this for bench testing so you don't
|
|
have to wait an hour per iteration.
|
|
|
|
config FRAME_RETRY_INTERVAL_S
|
|
int "Deep sleep interval after a failed cycle (seconds)"
|
|
default 300
|
|
help
|
|
How long the device deep-sleeps before retrying after the
|
|
server was unreachable or the fetch/display failed, instead of
|
|
waiting the full FRAME_SLEEP_INTERVAL_S.
|
|
|
|
config FRAME_NEXT_BUTTON_GPIO
|
|
int "Next-photo button GPIO (-1 to disable)"
|
|
default 2
|
|
range -1 7
|
|
help
|
|
Button wired between this GPIO and GND (active-low, internal
|
|
pull-up enabled in firmware -- no external resistor needed).
|
|
Pressing it wakes the device (if asleep), forces the server to
|
|
advance to the next photo immediately (POST /frame/advance)
|
|
regardless of the configured refresh interval, and displays
|
|
it. Must be GPIO 0-7 -- the only pins the ESP32-C6 can use as
|
|
a deep-sleep GPIO wakeup source, which is what lets a press
|
|
wake the device promptly instead of only being noticed during
|
|
its brief awake windows. Set to -1 to disable the feature.
|
|
|
|
config FRAME_BACK_BUTTON_GPIO
|
|
int "Back-photo button GPIO (-1 to disable)"
|
|
default 0
|
|
range -1 7
|
|
help
|
|
Button wired between this GPIO and GND (active-low, internal
|
|
pull-up enabled in firmware -- no external resistor needed).
|
|
Pressing it wakes the device (if asleep), forces the server
|
|
to return to the previously-current photo immediately
|
|
(POST /frame/back), and displays it. Pressing next
|
|
afterwards returns to where you were before pressing back.
|
|
Must be GPIO 0-7 for the same deep-sleep-wakeup reason as
|
|
FRAME_NEXT_BUTTON_GPIO above; defaults to a different pin
|
|
than the other buttons. Set to -1 to disable the feature.
|
|
|
|
config FRAME_COMBO_BUTTON_GPIO
|
|
int "Menu/reset button GPIO (-1 to disable)"
|
|
default 1
|
|
range -1 7
|
|
help
|
|
Button wired between this GPIO and GND (active-low, internal
|
|
pull-up enabled in firmware -- no external resistor needed).
|
|
One pin, three actions depending on how long it's held:
|
|
a quick press shows the management menu (same as before);
|
|
holding it FRAME_COMBO_SOFT_RESET_HOLD_MS then releasing
|
|
soft-resets the device (reboots, keeps the stored WiFi/
|
|
server config); holding it all the way to
|
|
FRAME_COMBO_FACTORY_RESET_HOLD_MS clears the stored config
|
|
and restarts into provisioning, regardless of whether it's
|
|
released yet. Must be GPIO 0-7 for the same deep-sleep-
|
|
wakeup reason as FRAME_NEXT_BUTTON_GPIO above; defaults to
|
|
a different pin than the other buttons. Set to -1 to
|
|
disable the feature entirely (also disables the management
|
|
menu, both reset tiers, and factory-reset-via-button --
|
|
reconfiguring then only works by erasing NVS over USB, see
|
|
firmware/README.md).
|
|
|
|
config FRAME_COMBO_SOFT_RESET_HOLD_MS
|
|
int "Soft-reset hold duration (ms)"
|
|
default 3000
|
|
depends on FRAME_COMBO_BUTTON_GPIO >= 0
|
|
help
|
|
How long the menu/reset button must be held before releasing
|
|
it triggers a soft reset (reboot, config kept). Long enough
|
|
to be clearly distinct from a quick menu-opening press.
|
|
|
|
config FRAME_COMBO_FACTORY_RESET_HOLD_MS
|
|
int "Factory-reset hold duration (ms)"
|
|
default 15000
|
|
depends on FRAME_COMBO_BUTTON_GPIO >= 0
|
|
help
|
|
How long the menu/reset button must be held continuously
|
|
before the device clears its stored config and reboots into
|
|
provisioning, regardless of release. Comfortably longer than
|
|
FRAME_COMBO_SOFT_RESET_HOLD_MS so the two tiers can't be
|
|
confused for each other.
|
|
|
|
config FRAME_BATTERY_ADC_GPIO
|
|
int "Battery voltage-divider ADC GPIO (-1 to disable)"
|
|
default -1
|
|
range -1 6
|
|
help
|
|
GPIO wired to the midpoint of a 2x200k voltage divider from
|
|
BAT+ to GND (halving the battery voltage into ADC range --
|
|
the wiring Seeed documents for the XIAO ESP32-C6's A0).
|
|
Must be GPIO 0-6, the ESP32-C6's only ADC-capable pins. The
|
|
settled XIAO design shares this with the back button's pin
|
|
(0): a high-impedance divider coexists fine with the
|
|
button's pull-up and deep-sleep wake, and the firmware
|
|
time-shares the pin (brief ADC read once per wake, restored
|
|
to button duty right after). -1 (the default) disables
|
|
battery reporting entirely -- correct for boards with no
|
|
battery wired, like the DevKitC-1 dev board.
|
|
|
|
config FRAME_VBUS_SENSE_GPIO
|
|
int "USB-power (VBUS) sense GPIO (-1 to disable)"
|
|
default -1
|
|
range -1 23
|
|
depends on FRAME_BATTERY_ADC_GPIO >= 0
|
|
help
|
|
GPIO wired to the midpoint of a 2x100k divider from the 5V
|
|
pin (which only carries voltage when USB is plugged in --
|
|
it's dead on battery power) -- a plain digital high/low
|
|
"on mains" signal, no ADC needed. The divider is required:
|
|
raw 5V exceeds the 3.3V pin limit. When on mains, the
|
|
battery indicator is hidden and no battery report is sent
|
|
(the charging voltage would read misleadingly full). -1
|
|
disables mains detection -- the indicator then shows
|
|
whenever the battery reading is plausible.
|
|
|
|
endmenu
|