Add third button: "scan to manage" QR overlay on the current photo

Pressing the manage button (GPIO1) overlays a small QR code -- "SCAN TO
MANAGE" -- in the top-right corner of whatever photo is currently on
screen, linking to the server's config page, then reverts to the plain
photo after 30 seconds.

The overlay is spliced into the existing streaming fetch as chunks pass
through (frame_client.c's http_read_fn), rather than buffering the full
192,000-byte frame in RAM: only the small overlay rectangle itself
(~30KB) is ever held in memory, generated via new stride-parameterized
drawing helpers (epd_draw_*_ex in epd_draw.c) that let the existing
QR/text drawing code target an arbitrarily-sized buffer instead of a
full-frame one. epd7in3e.c is untouched -- it has no idea an overlay
exists.
This commit is contained in:
2026-07-19 00:50:07 -04:00
parent c4cd9b73e8
commit f74085cedf
13 changed files with 395 additions and 27 deletions
+64
View File
@@ -0,0 +1,64 @@
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "manage_button.h"
static const char *TAG = "manage_button";
#if CONFIG_FRAME_MANAGE_BUTTON_GPIO >= 0
#define MANAGE_BUTTON_GPIO ((gpio_num_t)CONFIG_FRAME_MANAGE_BUTTON_GPIO)
#define MANAGE_BUTTON_DEBOUNCE_MS 20
#define MANAGE_BUTTON_DEBOUNCE_CHECKS 3
void manage_button_init(void)
{
gpio_config_t io_conf = {
.pin_bit_mask = 1ULL << MANAGE_BUTTON_GPIO,
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
gpio_config(&io_conf);
/* See reset_button.c for why this API (not ext1) -- it manages the
* pull resistor across the sleep transition itself, so the pin
* doesn't float and wake the device spuriously. */
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(1ULL << MANAGE_BUTTON_GPIO, ESP_GPIO_WAKEUP_GPIO_LOW);
}
bool manage_button_check(void)
{
/* See next_button.c for why the latched wakeup status is checked
* first: a quick tap can release before a live gpio_get_level() call
* this far into boot would still see it held, even though it's what
* woke the device. */
if (esp_sleep_get_gpio_wakeup_status() & (1ULL << MANAGE_BUTTON_GPIO)) {
ESP_LOGI(TAG, "Manage button caused this wake, showing management QR");
return true;
}
if (gpio_get_level(MANAGE_BUTTON_GPIO) != 0) {
return false;
}
for (int i = 0; i < MANAGE_BUTTON_DEBOUNCE_CHECKS; i++) {
vTaskDelay(pdMS_TO_TICKS(MANAGE_BUTTON_DEBOUNCE_MS));
if (gpio_get_level(MANAGE_BUTTON_GPIO) != 0) {
return false; /* noise, not a real press */
}
}
ESP_LOGI(TAG, "Manage button held during power-on, showing management QR");
return true;
}
#else
void manage_button_init(void) {}
bool manage_button_check(void) { return false; }
#endif