Require the button to confirm a knob wake

A knob turn still wakes the chip (the RTC can't tell gestures apart), but
the firmware now stays dark and checks the button: held while turning it
boots at once; otherwise the ring glows for 2.5 s waiting for a click and
goes back to deep sleep if none comes. Screen and Wi-Fi never start for
an accidental nudge.
This commit is contained in:
Juli committed 2026-09-17 15:12:53 +02:00
1 parent 3bdfcba6fb
commit e82f0ac137
4 files changed
+39 -4

No files matched your search

+5 -4
View File
@@ -76,10 +76,11 @@ Entries:
off**, the board name with its IP, and the power source.
*Power off* switches the peripheral rail off (screen, ring, codec) and puts the
ESP32-S3 into deep sleep; turning the knob wakes it and it boots as normal. The
encoder's push button is deliberately not a wake source: it is GPIO 0, and a
press that is still held when the chip resets would land it in the ROM
bootloader instead.
ESP32-S3 into deep sleep. To wake it, **hold the button and turn the knob** —
or turn it and then click within 2.5 s while the ring glows softly. A plain
nudge of the knob wakes the chip (the RTC can't tell gestures apart) but the
firmware notices the missing button and goes straight back to sleep without
ever lighting the screen.
The menu closes by itself after 45 s without input.
+1
View File
@@ -34,6 +34,7 @@ void app_main(void)
settings_init();
leds_init();
leds_set_brightness(settings.led_brightness);
power_confirm_wake(); // may go back to sleep instead of returning
leds_set_mode(LED_BREATHE, 0x404040);
display_init();
+29
View File
@@ -7,6 +7,7 @@
#include "driver/rtc_io.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "esp_timer.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -52,6 +53,34 @@ void power_off(void)
esp_deep_sleep_start();
}
#define CONFIRM_WINDOW_MS 2500
void power_confirm_wake(void)
{
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) return;
gpio_config_t btn = {.pin_bit_mask = 1ULL << board->enc_btn, .mode = GPIO_MODE_INPUT, .pull_up_en = 1};
gpio_config(&btn);
if (!gpio_get_level(board->enc_btn)) {
ESP_LOGI(TAG, "wake confirmed: button held while turning");
return;
}
leds_set_mode(LED_BREATHE, 0x302838); // soft hint: "click to wake"
int64_t deadline = esp_timer_get_time() / 1000 + CONFIRM_WINDOW_MS;
while (esp_timer_get_time() / 1000 < deadline) {
if (!gpio_get_level(board->enc_btn)) {
ESP_LOGI(TAG, "wake confirmed: click");
return;
}
vTaskDelay(pdMS_TO_TICKS(20));
}
ESP_LOGI(TAG, "knob nudge without the button; back to sleep");
leds_set_mode(LED_OFF, 0);
vTaskDelay(pdMS_TO_TICKS(80));
gpio_set_level(board->pwr_en, 0);
arm_knob_wakeup();
esp_deep_sleep_start();
}
void power_report_wakeup(void)
{
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
+4
View File
@@ -3,3 +3,7 @@
void power_off(void) __attribute__((noreturn));
// Logs how we came up (cold boot vs. knob wake).
void power_report_wakeup(void);
// After a knob wake, insists on the button: held while turning, or clicked within a
// short window while the ring glows. Otherwise goes straight back to sleep (no return).
// Returns normally on a cold boot or a confirmed wake. Needs the LED driver up.
void power_confirm_wake(void);