Collapse UX to single Usage view + hold-to-pair + status line
Removes the Bluetooth screen — the device now has just splash + Usage. Keeps main's responsive Layout intact. - ui: drop the Bluetooth screen, ui_cycle_screen, and SCREEN_BLUETOOTH. The bottom spinner becomes a status line — Connected / Disconnected / Pairing… (via ble_has_bonds()) plus the whimsical messages when connected and idle. A "To pair / hold the power button / for 3 seconds, then release" hint shows while disconnected so the screen isn't empty. - main: hold-to-pair gesture (pair_tick) — hold PWR ~3s then RELEASE clears bonds and re-advertises. Clearing on release (not while held) means holding to power off (8s hardware shutdown) leaves the bond intact; disarms at 6s. PWR short-press now cycles brightness on the Usage view (animations on splash). - ble: add ble_has_bonds() for the status line. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
ddb812ab5d
commit
2b4a0802fa
+56
-3
@@ -11,6 +11,7 @@
|
||||
#include "usage_rate.h"
|
||||
#include "idle.h"
|
||||
#include "idle_cfg.h"
|
||||
#include "brightness.h"
|
||||
|
||||
#include "hal/board_caps.h"
|
||||
#include "hal/display_hal.h"
|
||||
@@ -185,7 +186,8 @@ void setup() {
|
||||
|
||||
display_hal_init();
|
||||
display_hal_begin();
|
||||
idle_init(); // takes over brightness (DISPLAY_DEFAULT_BRIGHTNESS) and starts the idle timer
|
||||
idle_init(); // takes over panel brightness and starts the idle timer
|
||||
brightness_init(); // load the user's saved brightness level and apply via idle
|
||||
|
||||
power_hal_init();
|
||||
imu_hal_init();
|
||||
@@ -226,6 +228,52 @@ void setup() {
|
||||
|
||||
static ble_state_t last_ble_state = BLE_STATE_INIT;
|
||||
|
||||
// Hold-to-pair gesture: hold the PWR button ~3s, then RELEASE → clear all BLE
|
||||
// bonds and re-advertise. Clearing on *release* (not while held) is deliberate:
|
||||
// holding to power the device OFF (AXP hardware shutdown at 8s) must not wipe
|
||||
// the bond — a power-off hold never releases before shutdown. To stop a
|
||||
// "chicken-out" release just before 8s from pairing, the gesture disarms at 6s.
|
||||
//
|
||||
// ~1.5s long-press edge → PENDING
|
||||
// 3.0s (+1500) → ARMED (release from here clears bonds)
|
||||
// 6.0s (+4500) → DISARMED (no clear; AXP powers off at 8s)
|
||||
#define PAIR_ARM_AFTER_LONG_MS 1500 // 3.0s total
|
||||
#define PAIR_DISARM_AFTER_LONG_MS 4500 // 6.0s total
|
||||
enum pair_state_t { PAIR_IDLE, PAIR_PENDING, PAIR_ARMED };
|
||||
static pair_state_t pair_state = PAIR_IDLE;
|
||||
static uint32_t pair_long_seen_ms = 0;
|
||||
|
||||
static void pair_tick(void) {
|
||||
if (pair_state == PAIR_IDLE && power_hal_pwr_long_pressed()) {
|
||||
pair_state = PAIR_PENDING;
|
||||
pair_long_seen_ms = millis();
|
||||
(void)power_hal_pwr_released(); // drain any stale release edge
|
||||
Serial.println("PWR long-press: hold to ~3s then release to pair");
|
||||
return;
|
||||
}
|
||||
if (pair_state == PAIR_IDLE) return;
|
||||
|
||||
if (power_hal_pwr_released()) {
|
||||
if (pair_state == PAIR_ARMED) {
|
||||
Serial.println("Pair: released in window — clearing bonds, advertising");
|
||||
ble_clear_bonds();
|
||||
} else {
|
||||
Serial.println("Pair: released too early — cancelled");
|
||||
}
|
||||
pair_state = PAIR_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t held = millis() - pair_long_seen_ms;
|
||||
if (pair_state == PAIR_PENDING && held >= PAIR_ARM_AFTER_LONG_MS) {
|
||||
pair_state = PAIR_ARMED;
|
||||
Serial.println("Pair: armed — release to pair");
|
||||
} else if (pair_state == PAIR_ARMED && held >= PAIR_DISARM_AFTER_LONG_MS) {
|
||||
pair_state = PAIR_IDLE; // power-off territory; don't pair
|
||||
Serial.println("Pair: disarmed (holding toward power-off)");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
idle_tick();
|
||||
lv_timer_handler();
|
||||
@@ -242,7 +290,8 @@ void loop() {
|
||||
// ---- Physical buttons ----
|
||||
// PRIMARY → HID Space (Claude Code voice-mode PTT)
|
||||
// SECONDARY → HID Shift+Tab (mode toggle; only if the board has one)
|
||||
// PWR → cycle screens; on splash, cycle animations
|
||||
// PWR → on splash: cycle animations; on usage: cycle brightness;
|
||||
// hold ~3s + release: pairing mode
|
||||
// First press from sleep is consumed as a wake-only event by
|
||||
// idle_consume_wake_press(); the normal action fires from the second
|
||||
// press. Activity bookkeeping happens inside idle_consume_wake_press
|
||||
@@ -280,10 +329,14 @@ void loop() {
|
||||
|
||||
if (power_hal_pwr_pressed()) {
|
||||
if (!idle_consume_wake_press()) {
|
||||
// On splash: cycle animations. On the usage view: cycle
|
||||
// screen brightness (single non-splash view, no more screens).
|
||||
if (ui_get_current_screen() == SCREEN_SPLASH) splash_next();
|
||||
else ui_cycle_screen();
|
||||
else brightness_cycle();
|
||||
}
|
||||
}
|
||||
|
||||
pair_tick();
|
||||
}
|
||||
|
||||
ble_state_t bs = ble_get_state();
|
||||
|
||||
Reference in New Issue
Block a user