Server: Frame.panel_type (new column + migration) is auto-derived from the device's reported board (X-Frame-Board), never user-set -- the panel is a property of the hardware, not a picker in the UI. image_pipeline's packing/render pipeline is parameterized by panel geometry instead of hardcoded 800x480 globals, with the real confirmed 13.3in geometry (1600x1200) registered alongside the original 7.3in panel. Existing 7.3in frames are unaffected (column default + board mapping both resolve to the original panel). Board identifiers are also renamed (devkit/xiao -> devkit_esp32c6/ xiao_esp32c6, plus new "ee02") since the EE02 board also carries a XIAO module -- "xiao" alone stopped disambiguating hardware. The server keeps accepting the legacy bare names indefinitely for already-flashed devices. Firmware: scaffolds a third build target (ee02, ESP32-S3 -- a real chip-target change, not just a same-chip Kconfig variant like xiao) and a new epd13in3e driver component skeleton. The actual panel init/LUT/ refresh register sequence isn't ported from vendor demo code yet (none was available), so that component deliberately fails to compile (#error) rather than risk sending unverified register values to real hardware -- devkit/xiao are unaffected and build identically to before. CI's ee02 build step is continue-on-error for the same reason.
264 lines
13 KiB
Plaintext
264 lines
13 KiB
Plaintext
menu "ESPresso Frame Configuration"
|
|
|
|
config FRAME_BOARD_NAME
|
|
string "Board variant name, reported to the server"
|
|
default "devkit_esp32c6"
|
|
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, and (see
|
|
routers/device.py's BOARD_PANEL_MAP) which EPD panel it
|
|
drives -- no manual "which board/panel" picker in the web
|
|
UI. Must match one of the asset names
|
|
.gitea/workflows/firmware-release-build.yml publishes
|
|
(firmware-<name>.bin): "devkit_esp32c6" (this default, for
|
|
the plain ESP32-C6-DevKitC-1 build), "xiao_esp32c6" (set via
|
|
sdkconfig.xiao for the Seeed XIAO ESP32-C6 build), or "ee02"
|
|
(set via sdkconfig.ee02 for the Seeed EE02/XIAO ESP32-S3
|
|
Plus + 13.3" panel build) -- see build_for_board.sh.
|
|
|
|
Chip-qualified rather than plain "devkit"/"xiao": the EE02
|
|
board also sockets a XIAO module (an ESP32-S3 one), so
|
|
"xiao" alone stopped disambiguating hardware once EE02
|
|
existed. The server keeps accepting the old bare
|
|
"devkit"/"xiao" names indefinitely too, since already-
|
|
flashed devices report whatever name their current firmware
|
|
was built with and can't be retroactively renamed.
|
|
|
|
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 FRAME_PANEL_EE02_13IN3
|
|
bool "Build for the EE02 board + 13.3in Spectra 6 panel (ESP32-S3), not the 7.3in panel"
|
|
default n
|
|
help
|
|
Selects the epd13in3e driver component (13.3", 1600x1200)
|
|
instead of epd7in3e (7.3", 800x480) as main/epd_board.h's
|
|
target -- see firmware/components/epd13in3e. Firmware only
|
|
ever links one EPD driver at a time, same as the
|
|
devkit/xiao split links exactly one board's pin config.
|
|
Enabled by default in sdkconfig.ee02; leave off for the
|
|
ESP32-C6 boards (devkit/xiao), which drive the 7.3" panel.
|
|
|
|
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 soft-resets the device (reboots, keeps the
|
|
stored WiFi/server config); holding it FRAME_COMBO_MENU_HOLD_MS
|
|
then releasing shows the management menu; 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_MENU_HOLD_MS
|
|
int "Management-menu 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 shows the management menu instead of soft-resetting. Long
|
|
enough to be clearly distinct from a quick reset tap.
|
|
|
|
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_MENU_HOLD_MS so the two tiers can't be confused
|
|
for each other.
|
|
|
|
config FRAME_HOLD_ACTION_MS
|
|
int "Next/back hold-for-global-action duration (ms)"
|
|
default 3000
|
|
range 3000 10000
|
|
help
|
|
How long the NEXT or BACK button must be held before it
|
|
triggers a frame-wide action (see server/app/global_actions.py
|
|
-- e.g. cycling saved layouts) instead of that button's normal
|
|
short-press behavior. Only a first-boot/never-connected
|
|
fallback: once the device has fetched GET /frame/config at
|
|
least once, the server's own Frame.hold_duration_ms (set on
|
|
the Configuration tab) overrides this on every later boot --
|
|
see wifi_provisioning.h's frame_config_get_hold_duration_ms.
|
|
Floor matches the server's own minimum, so a long-held button
|
|
never means something different depending on which value
|
|
happened to apply.
|
|
|
|
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
|