From d2ffe674205c5074bdac32a06fdabf333f216cc3 Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:37:49 +0100 Subject: [PATCH] thinknode m1 fixes --- .gitignore | 1 + zephcore/ARCHITECTURE.md | 23 +++-------- zephcore/boards/common/logging.conf | 5 ++- .../nrf52840/thinknode_m1/thinknode_m1.dts | 40 ++++++++----------- zephcore/helpers/ui/display.c | 8 +++- 5 files changed, 33 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index b001782..9a6edb9 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,4 @@ WEST_UPDATE.md # Side projects (not part of main firmware) /doom/ THINKNODE_M1_HANDOVER.md +CLAUDE.md diff --git a/zephcore/ARCHITECTURE.md b/zephcore/ARCHITECTURE.md index 8e0bad4..e045fc1 100644 --- a/zephcore/ARCHITECTURE.md +++ b/zephcore/ARCHITECTURE.md @@ -590,24 +590,13 @@ Over USB CDC: V3 framing: `[2B LE length] [1B opcode] [payload...]` | `/lfs/repeater/regions2` | Region map | Header + 164B × N entries | | `/lfs/settings/` | BLE bonds + Zephyr settings | File-based settings (all platforms) | -### Preferences Binary Layout (93 bytes) +### Preferences Binary Layout (292 bytes) -``` -Offset Size Field -0 4 airtime_factor (float) -4 32 node_name -36 4 (padding) -40 8 node_lat (double) -48 8 node_lon (double) -56 4 freq (float) -60 1 sf -61 1 cr -62 1 client_repeat -63 1 manual_add_contacts -64 4 bw (float) -... ... (see CommonCLI.cpp loadPrefs/savePrefs for full layout) -92 1 rx_boost (ZephCore extension) -``` +Field-by-field serialization (NOT raw struct dump). See `memory/prefs-format.md` for full layout, +or `zephcore/helpers/CommonCLI.cpp` `loadPrefs()` for the authoritative source. + +Key ranges: name(4-36), radio(72-119), adaptive-delay(80-111, ignored at runtime), +Arduino-bridge(127-151, read+discarded), GPS(156-161), owner_info(170-290), rx_boost/duty(290-291). --- diff --git a/zephcore/boards/common/logging.conf b/zephcore/boards/common/logging.conf index badc2f7..c828825 100644 --- a/zephcore/boards/common/logging.conf +++ b/zephcore/boards/common/logging.conf @@ -13,7 +13,10 @@ CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1 CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048 # Backends -CONFIG_LOG_BACKEND_UART=y +# NOTE: UART backend on nRF52 routes through USB CDC ACM (zephyr,console = &cdc_acm_uart). +# There is no LOG_BACKEND_UART_MODE_DROP in Zephyr — if the USB host disconnects, the log +# processing thread stalls on uart_poll_out(). Disable UART backend on nRF52 to avoid this; +# RTT (below) is the reliable debug path and already configured with drop mode. CONFIG_LOG_BACKEND_RTT=y # Suppress noisy subsystem logs diff --git a/zephcore/boards/nrf52840/thinknode_m1/thinknode_m1.dts b/zephcore/boards/nrf52840/thinknode_m1/thinknode_m1.dts index a56c601..d66fb14 100644 --- a/zephcore/boards/nrf52840/thinknode_m1/thinknode_m1.dts +++ b/zephcore/boards/nrf52840/thinknode_m1/thinknode_m1.dts @@ -11,7 +11,7 @@ * - MX25R1635F 2MB QSPI flash * - GPS module on UART0 (9600 baud, multi-constellation) * - 1200 mAh battery with ADC on AIN2 (150K+150K divider) - * - Buzzer on PWM0, two user buttons, GPS hardware switch + * - Buzzer on PWM0, user button (P1.10), page button (P1.07), GPS hardware switch * - LEDs: GREEN=P1.04, BLUE=P0.14 (RED=P1.06 shared with display SPI) * * Pin conflicts (shared by hardware design): @@ -79,38 +79,30 @@ buttons: buttons { compatible = "gpio-keys"; + /* Action / enter button (P1.10) — KEY_ENTER direct, no filter. + * action_page_enter() handles double-press confirmation internally. */ user_button: button_0 { gpios = <&gpio1 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - zephyr,code = ; + zephyr,code = ; label = "User Button"; }; + /* Page turn button (P1.07) — raw KEY_0, consumed by multi-tap below. + * (P1.07 is shared with SPI1 MISO — safe because EPD is write-only.) */ page_button: button_1 { - gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - zephyr,code = ; + gpios = <&gpio1 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; label = "Page Button"; }; }; - /* Input filter: user button long-press (1000ms) */ - user_btn_longpress { - compatible = "zephyr,input-longpress"; - input = <&buttons>; - input-codes = ; - short-codes = ; - long-codes = ; - long-delay-ms = <1000>; - }; - - /* Input filter: user button multi-tap - * 1 tap → KEY_1 = next page on EPD - * 2 taps → KEY_B = flood advert - * 3 taps → KEY_D = buzzer mute toggle - * 4 taps → KEY_C = GPS on/off */ - user_btn_multitap { + /* Input filter: page button multi-tap + * 1 tap → KEY_1 = next page + * 2 taps → KEY_LEFT = previous page */ + page_btn_multitap { compatible = "zephcore,input-multi-tap"; - input-codes = ; - tap-codes = ; + input-codes = ; + tap-codes = ; tap-delay-ms = <400>; }; @@ -146,7 +138,7 @@ * Physical toggle switch on the board. * HIGH = GPS ON, LOW = GPS OFF. * Separate from the buttons node so it doesn't feed - * the longpress/multi-tap filter chain. */ + * the page button multi-tap filter. */ gps_switch: gps-switch { compatible = "gpio-keys"; gps_sw: gps_sw { @@ -209,7 +201,7 @@ reg = <0>; width = <200>; height = <200>; - rotation = <0>; + rotation = <270>; busy-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; /* Use internal temperature sensor for OTP waveform selection. */ diff --git a/zephcore/helpers/ui/display.c b/zephcore/helpers/ui/display.c index 9ee19a1..635a926 100644 --- a/zephcore/helpers/ui/display.c +++ b/zephcore/helpers/ui/display.c @@ -51,14 +51,17 @@ static const struct device *backlight_reg = static const struct device *backlight_reg; #endif +static bool backlight_on; + static inline void backlight_set(bool on) { - if (backlight_reg && device_is_ready(backlight_reg)) { + if (backlight_reg && device_is_ready(backlight_reg) && on != backlight_on) { if (on) { regulator_enable(backlight_reg); } else { regulator_disable(backlight_reg); } + backlight_on = on; } } @@ -220,8 +223,9 @@ int mc_display_init(void) disp_on = true; disp_initialized = true; - /* Set up auto-off timer */ + /* Set up auto-off timer and schedule initial timeout */ k_work_init_delayable(&auto_off_work, auto_off_handler); + mc_display_reset_auto_off(); LOG_INF("display initialized (%ux%u, font %ux%u)", disp_width, disp_height, font_w, font_h);