Add back-photo button; consolidate reset/manage onto one hold-duration button
Build and push server image / build-and-push (push) Successful in 32s

Back button (new GPIO0, POST /frame/back): the server now tracks a
bounded history of previously-current photos (photo_queue.py), pushed
to on every advance (auto or forced) and popped by back_forced() --
symmetric with advance, so pressing next afterwards returns to right
where you were. frame_client.c's force_advance bool becomes a 3-way
fetch_action_t (NORMAL/ADVANCE/BACK) threaded through the whole fetch
path.

Also folds the separate reset and manage buttons onto one pin
(combo_button.c, replacing reset_button.c/manage_button.c entirely),
disambiguated by hold duration: quick press shows the management menu
(unchanged), ~3s hold-then-release soft-resets (esp_restart(), config
kept -- new), ~15s hold factory-resets (today's old reset behavior,
extended from 10s for clearer tier separation). Driven by a production
board (Seeed XIAO ESP32-C6) exposing only 3 of the ESP32-C6's 8
deep-sleep-wakeup-capable GPIOs -- next/back keep their own dedicated
pins where instant response matters most, everything else shares the
third pin via timing instead of needing its own. Same three-pin layout
now works on both the dev board and the production board.

Fixed a fast-tap bug in combo_button_check() before shipping: it only
did a live gpio_get_level() read to decide whether the button was
pressed at all, so a press fast enough to already be released by the
time boot reached that check was missed entirely (treated as "never
pressed" rather than "quick press"). Added the same latched
esp_sleep_get_gpio_wakeup_status() check the other buttons already use
for exactly this reason.
This commit is contained in:
2026-07-19 12:53:26 -04:00
parent bb4f473bfa
commit 3868d357ff
22 changed files with 521 additions and 351 deletions
+55 -36
View File
@@ -83,30 +83,6 @@ menu "ESPresso Frame Configuration"
server was unreachable or the fetch/display failed, instead of
waiting the full FRAME_SLEEP_INTERVAL_S.
config FRAME_RESET_BUTTON_GPIO
int "Factory-reset button GPIO (-1 to disable)"
default 3
range -1 7
help
Button wired between this GPIO and GND (active-low, internal
pull-up enabled in firmware -- no external resistor needed).
Holding it for FRAME_RESET_BUTTON_HOLD_MS clears the stored
WiFi/server config and restarts the device into provisioning
mode. Must be GPIO 0-7 -- the only pins the ESP32-C6 can use as
an EXT1 deep-sleep 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
entirely.
config FRAME_RESET_BUTTON_HOLD_MS
int "Factory-reset button hold duration (ms)"
default 10000
depends on FRAME_RESET_BUTTON_GPIO >= 0
help
How long the reset button must be held continuously before the
device clears its stored config and reboots into provisioning.
Long enough that it won't trigger by accident.
config FRAME_NEXT_BUTTON_GPIO
int "Next-photo button GPIO (-1 to disable)"
default 2
@@ -117,23 +93,66 @@ menu "ESPresso Frame Configuration"
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 for the same deep-sleep-wakeup reason as
FRAME_RESET_BUTTON_GPIO above; defaults to a different pin
than the reset button. Set to -1 to disable the feature.
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_MANAGE_BUTTON_GPIO
int "Manage button GPIO (-1 to disable)"
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).
Pressing it wakes the device (if asleep), displays the
current photo with a small "scan to manage" QR code overlaid
in the top-right corner (linking to the tools server's config
page) for 30 seconds, then reverts to the plain photo. Must
be GPIO 0-7 for the same deep-sleep-wakeup reason as
FRAME_RESET_BUTTON_GPIO above; defaults to a different pin
than the other two buttons. Set to -1 to disable the feature.
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.
endmenu