diff options
| author | Luke Hoersten <[email protected]> | 2026-06-14 16:41:03 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-14 16:41:03 -0500 |
| commit | c6ce4b3f46a1f1adf700306dadc9034a6a2ac0d3 (patch) | |
| tree | 3bd6f0a3c2eea8b0095bd05549cae650fe166b40 /main/touch.c | |
| parent | 6c1a26bdae63d152caa45023e8255561a22fc0e2 (diff) | |
M3 done: drop boot test, fold BOOT button into touch long-press
The Waveshare ESP32-P4-ETH board exposes BOOT on GPIO 35, but at runtime
that pin is owned by the EMAC TXD1 signal. No usable GPIO is wired to a
separate user button, so the BOOT-button task could never fire.
Move both BOOT-button behaviours onto the touch panel:
- ≥1.5s hold → 15s identity overlay (was BOOT short-press)
- ≥5s hold → factory reset (was BOOT long-hold)
Short tap (<500ms) still toggles wake/sleep. Long-press fires while the
finger is still down so the user gets immediate feedback at each
threshold.
Also strip the R/G/B 6 s boot test sequence — the panel now renders
correctly, so it's no longer useful diagnostically.
Boot subsystem flags drop the trailing B column: [EMHDJT].
Diffstat (limited to 'main/touch.c')
| -rw-r--r-- | main/touch.c | 103 |
1 files changed, 60 insertions, 43 deletions
diff --git a/main/touch.c b/main/touch.c index 4d8003f..6b4e035 100644 --- a/main/touch.c +++ b/main/touch.c @@ -5,12 +5,14 @@ #include "driver/i2c_master.h" #include "esp_check.h" #include "esp_log.h" +#include "esp_system.h" #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "display.h" #include "local_screens.h" +#include "nvs_config.h" #include "state_machine.h" #include "viewport_state.h" @@ -19,18 +21,15 @@ static const char *TAG = "touch"; #define FT5426_ADDR 0x38 #define FT5426_I2C_FREQ_HZ 400000 -// FT5x06/FT5426 register map (subset). #define FT_REG_DEV_MODE 0x00 -#define FT_REG_GEST_ID 0x01 -#define FT_REG_TD_STATUS 0x02 // low 4 bits = touch count -#define FT_REG_P1_XH 0x03 // X high (bits 0..3) + event flag (bits 6..7) -#define FT_REG_P1_XL 0x04 -#define FT_REG_P1_YH 0x05 -#define FT_REG_P1_YL 0x06 +#define FT_REG_TD_STATUS 0x02 +#define FT_REG_P1_XH 0x03 #define POLL_PERIOD_MS 30 -#define TAP_MAX_MS 500 -#define TAP_MAX_MOVE_PX 25 +#define TAP_MAX_MS 500 // < this on release = short tap (toggle) +#define LONG_PRESS_MS 1500 // ≥ this while held = identity overlay +#define FACTORY_RESET_MS 5000 // ≥ this while held = factory reset +#define OVERLAY_MS 15000 #define TAP_DEBOUNCE_MS 150 static i2c_master_dev_handle_t s_dev; @@ -41,12 +40,37 @@ static esp_err_t ft_read(uint8_t reg, uint8_t *buf, size_t n) return i2c_master_transmit_receive(s_dev, ®, 1, buf, n, 50); } +static void on_short_tap(void) +{ + if (local_screens_overlay_active()) local_screens_overlay_dismiss(); + viewport_run_state_t target = + (state_machine_current() == VIEWPORT_STATE_AWAKE) + ? VIEWPORT_STATE_ASLEEP + : VIEWPORT_STATE_AWAKE; + ESP_LOGI(TAG, "tap -> %s", target == VIEWPORT_STATE_AWAKE ? "wake" : "sleep"); + state_machine_set_local(target); +} + +static void on_long_press(void) +{ + ESP_LOGI(TAG, "long-press → identity overlay for %dms", OVERLAY_MS); + if (display_is_up()) local_screens_overlay(OVERLAY_MS); +} + +static void on_factory_reset(void) +{ + ESP_LOGW(TAG, "very-long-press %dms → factory reset", FACTORY_RESET_MS); + nvs_config_reset(); + vTaskDelay(pdMS_TO_TICKS(200)); + esp_restart(); +} + static void touch_task(void *arg) { bool was_down = false; uint64_t down_us = 0; - uint16_t down_x = 0; - uint16_t down_y = 0; + bool long_fired = false; + bool reset_fired = false; uint64_t last_tap_us = 0; uint8_t buf[7]; @@ -54,43 +78,36 @@ static void touch_task(void *arg) vTaskDelay(pdMS_TO_TICKS(POLL_PERIOD_MS)); if (ft_read(FT_REG_DEV_MODE, buf, sizeof(buf)) != ESP_OK) continue; - uint8_t touches = buf[FT_REG_TD_STATUS] & 0x0F; + uint64_t now = (uint64_t)esp_timer_get_time(); + if (touches > 0) { - // Always capture P1; we only care about taps, not multi-touch. - uint16_t x = ((buf[FT_REG_P1_XH] & 0x0F) << 8) | buf[FT_REG_P1_XL]; - uint16_t y = ((buf[FT_REG_P1_YH] & 0x0F) << 8) | buf[FT_REG_P1_YL]; if (!was_down) { - was_down = true; - down_us = (uint64_t)esp_timer_get_time(); - down_x = x; - down_y = y; + was_down = true; + down_us = now; + long_fired = false; + reset_fired = false; + } else { + uint64_t held_ms = (now - down_us) / 1000ULL; + if (!long_fired && held_ms >= LONG_PRESS_MS) { + long_fired = true; + on_long_press(); + } + if (!reset_fired && held_ms >= FACTORY_RESET_MS) { + reset_fired = true; + on_factory_reset(); // does not return + } } } else if (was_down) { - // Release: was-down → up. was_down = false; - uint64_t now = (uint64_t)esp_timer_get_time(); - + uint64_t held_ms = (now - down_us) / 1000ULL; if (now - last_tap_us < (uint64_t)TAP_DEBOUNCE_MS * 1000ULL) continue; - uint64_t dt_ms = (now - down_us) / 1000ULL; - // No reliable last position from the burst; use down coordinates - // for the duration check, ignore movement check beyond the down - // capture. Good enough for tap-vs-press. - (void)down_x; (void)down_y; (void)TAP_MAX_MOVE_PX; - - if (dt_ms > 0 && dt_ms <= TAP_MAX_MS) { + // Short tap only fires on release; long-press already fired + // while the finger was still down. + if (!long_fired && held_ms > 0 && held_ms <= TAP_MAX_MS) { last_tap_us = now; - // Cancel any BOOT-button identity overlay so a tap-to-sleep - // doesn't fight the overlay timer trying to restore content. - if (local_screens_overlay_active()) local_screens_overlay_dismiss(); - viewport_run_state_t target = - (state_machine_current() == VIEWPORT_STATE_AWAKE) - ? VIEWPORT_STATE_ASLEEP - : VIEWPORT_STATE_AWAKE; - ESP_LOGI(TAG, "tap (%lu ms) -> %s", (unsigned long)dt_ms, - target == VIEWPORT_STATE_AWAKE ? "wake" : "sleep"); - state_machine_set_local(target); + on_short_tap(); } } } @@ -112,15 +129,15 @@ esp_err_t touch_init(void) ESP_RETURN_ON_ERROR(i2c_master_bus_add_device(bus, &cfg, &s_dev), TAG, "i2c add FT5426"); - // Sanity poll: read device mode. uint8_t dev_mode = 0; esp_err_t err = ft_read(FT_REG_DEV_MODE, &dev_mode, 1); if (err != ESP_OK) { - ESP_LOGE(TAG, "FT5426 @0x38 unreachable (%s) — check INT jumper", - esp_err_to_name(err)); + ESP_LOGE(TAG, "FT5426 @0x38 unreachable (%s)", esp_err_to_name(err)); return err; } - ESP_LOGI(TAG, "FT5426 ack'd (dev_mode=0x%02x)", dev_mode); + ESP_LOGI(TAG, "FT5426 ack'd (dev_mode=0x%02x); " + "tap=toggle, %dms hold=ID overlay, %dms hold=factory reset", + dev_mode, LONG_PRESS_MS, FACTORY_RESET_MS); BaseType_t ok = xTaskCreate(touch_task, "touch", 3072, NULL, 4, &s_task); return (ok == pdPASS) ? ESP_OK : ESP_FAIL; |
