src.nth.io/

summaryrefslogtreecommitdiff
path: root/main/local_screens.c
AgeCommit message (Collapse)AuthorFilesLines
6 daystemp: report on-die temperature in /state and the info screenLuke Hoersten1-0/+4
New chip_temp module wraps the ESP32-P4 TSENS driver (20-100C range for best accuracy in the warm band a PoE + 200MHz-PSRAM device lives in). /state gains temp_c (0.1C resolution, omitted when the sensor is unavailable); the long-press info overlay gains a temp line (lowercase c suffix — the local 8x8 font has no uppercase C). Junction temperature, ~10-20C above ambient under load.
2026-06-14Default name = MAC; brief wake on boot; drop dead touch defencesLuke Hoersten1-3/+6
- Seed viewport_name with the full base MAC, colons stripped (e8:f6:0a:e0:90:94 → "e8f60ae09094"). Stable across reboots, globally unique, 12 alphanumeric chars — well inside the mDNS hostname limit even with the "viewport-" prefix. - Add a mac_str field to viewport_state and expose it as the new "mac" key in GET /state and as a "mac" line on the info screen. - "Configured" no longer requires a viewport_name (it always has the MAC default); the scrypted URL alone gates outbound POSTs and the loading-vs-info screen choice. - Strip viewport_name[0] fallbacks in http_api / mdns / local_screens now that the field is never empty. - Replace the wake-on-boot-stays-on behaviour with a ~600 ms flash followed by sleep — long enough for the FT5426 touch IC to come out of its initial unresponsive state, short enough that an idle device doesn't burn the backlight. - Drop the touch defensive cruft added when we were chasing a PoE-power theory: the DEV_MODE=0x00 write at init, the touch_reset_pulse() call at init, and the runtime wedge-self-heal in the polling loop didn't actually fix anything — the wake-on-boot flash did. Also delete the display_touch_reset_pulse() helper since it now has zero callers.
2026-06-14Tidy: delete dead code, inline single-use helpers, fix double-lockLuke Hoersten1-35/+21
Code-review pass after the M5 colour fix. -126 net lines (-215 / +89). Dead code removed: - display_fill, display_test_pattern — M3 bring-up self-tests, no callers - net_eth_is_up — no callers - nvs_config_reset — no callers (factory-reset gesture was removed earlier; NVS wipe now goes through `idf.py erase-flash`) Helpers inlined or collapsed (each had one call site): - state_name / orientation_name — ternaries at the cJSON site - fmt_bytes / fmt_uptime — inline scope in local_screens_show_info - expected_dims (http_api) + effective_dims (local_screens) — merged into viewport_state_effective_dims() in viewport_state, one canonical source state_machine cleanup: - arm_idle_timer_unlocked / disarm_idle_timer collapsed to one arm_idle_timer(ms) that takes the snapshotted timeout (ms==0 disables). Removes the misleading name and the second viewport_state lock acquisition per painted frame. - state_machine_set + state_machine_frame_painted now snapshot state + idle_ms under one lock. mdns_service cleanup: - snapshot_state / apply_hostname / apply_txt collapsed into a single apply_state(include_hostname) helper; mdns_service_start grabs hostname once for hostname_set + log instead of going under the lock three times. http_api cleanup: - POST /config brightness-changed path uses the local `bright` it already validated instead of re-locking + re-reading st->brightness. - Trimmed verbose bring-up comments (stack-size justification, M5 saga, DSI shadow struct) to one line each — kept the load-bearing facts. Smoke-tested on hardware: boot clean, display + JPEG + touch all up ([DJT]), info screen renders, no crashes.
2026-06-14Drop VIEWPORT_STATE_UNCONFIGURED — state is just awake/asleepLuke Hoersten1-4/+1
\`state\` now reports only the screen's runtime state (awake or asleep). Whether a viewport is set up to talk to Scrypted is a separate \`configured\` flag, derived from \`viewport_name && scrypted_url\`. There's no third state. Behaviour changes: - POST /state always succeeds; the previous 409 "device unconfigured" path is gone. The screen toggles regardless of /config status. - POST /config now sets \`configured\` directly from the derived predicate instead of mutating the state enum. - Outbound state-client POST to Scrypted is still gated on a scrypted URL being present — that's the only thing the configured flag now actually controls in the runtime path. GET /state JSON unchanged in shape, but \`state\` is now never "unconfigured" — that's reported through the existing \`configured\` boolean instead.
2026-06-14Info screen: full /config + /state dump, replaces identity screenLuke Hoersten1-40/+142
Previously the 4-line "identity" screen showed only viewport name, mDNS host, IP, and state. Expanded to 15 lines covering the full GET /config + GET /state output (name, host, ip, state, configured, scrypted, orientation, brightness, idle, fw, uptime, frames, errs, free heap, free PSRAM), label/value pairs left-aligned with auto-scaled font. Renames "identity" → "info" throughout — symbol, log messages, README/TESTING references. Also: - Move the info-screen render's big locals (~1.6 KiB: lines[16][80] + scrypt[256] + vp_name[64]) to BSS. The touch task's 3 KiB stack was overflowing on every long-press, leaving whatever frame was previously on the panel — gave the appearance of a "blue screen" after the M5 test pattern. - Drop the ≥5 s touch factory-reset gesture and remove all stale references to it in docs and comments. NVS wipe is now a USB-side `idf.py erase-flash` operation only. - M5 follow-up TODO in jpeg_decoder.c: solid green renders ~black and solid blue renders green; not a byte-order issue (BGR setting turns red into blue). Tracked as a known M5 gap.
2026-06-14M3 WIP: DSI bring-up + state machine + identity overlayLuke Hoersten1-18/+50
DSI / panel: - LDO_VO3 acquired at 2500 mV (VDD_MIPI_DPHY) — without this the PHY PLL busy-waits forever inside esp_lcd_new_dsi_bus. - PSRAM bumped to 200 MHz (CONFIG_IDF_EXPERIMENTAL_FEATURES) to keep the DPI fed without underruns. - Pi-7"-style 800x480 panel init (REG_POWERON, PORTA/PORTB/PWM/PORTC) + 16-bit RGB565 framebuffer with portrait-mode rotation buffer in PSRAM. Currently shows garbled output — known issue, next commit switches to the TC358762-bridge-aware init sequence. State + UX: - viewport_state simplified to AWAKE/ASLEEP only; "unconfigured" is a flag, not a state. Tap always toggles; content choice (identity vs frame) is driven by the configured flag. - BOOT button arms a 15 s identity overlay via local_screens_overlay; expired callback returns to prior state. - Boot-done indicator: two backlight flashes (no usable LED GPIO on the Waveshare board — GPIO 35 BOOT is shared with EMAC TXD1). - Best-effort subsystem init in app_main; display init deferred to its own task so a panel hang can't block networking. Display test pattern: solid R/G/B for 2 s each on boot to characterize the garble independent of text rendering.
2026-06-14Identity screen: name + hostname + IP + state, auto-scaledLuke Hoersten1-10/+79
local_screens_show_ip() now renders four lines instead of two — all the device's runtime identity at once: line 1: viewport name ("mudroom" / "viewport" if unconfigured) line 2: mDNS hostname ("viewport-mudroom.local" / "viewport.local") line 3: IP ("192.168.1.42" / "no network") line 4: state ("awake" / "asleep" / "unconfigured") Same screen is shown on first boot, after factory reset, and as a 15s BOOT short-press overlay — operator always has the device's full identity one button-press away (find it on the LAN, confirm name + configuration without curling). Font scale is auto-picked: the largest integer scale (1×–6×) where the longest line fits within 90% of width AND all four lines plus inter-line spacing fit within 90% of height. Works for both portrait (480×800) and landscape (800×480) without separate code paths. Font expanded to cover the new strings: - All lowercase a–z (added b, f, h, j, k, m, q, s, u, x, y, z). - Punctuation: dash, slash (digits, period, colon already covered). Fallback policy unchanged: unsupported chars render as blank, which keeps the table tight and the failure mode visible rather than crashing. README "Local rendering" + TESTING.md M8 updated to describe the four-line identity layout and show both the unconfigured-boot and configured-overlay example outputs. Build verified clean against ESP-IDF 5.4 (binary ~873 KB, +1.6 KB for the expanded font).
2026-06-13M8: local screens (IP + Loading) + BOOT buttonLuke Hoersten1-0/+175
local_screens.{h,c}: - Embedded 8x8 bitmap font sized to a 95-char table; only the glyphs used by today's strings (viewport.local, the IPv4 string, Loading...) are populated. Unsupported chars render blank. - 768 KB PSRAM scratch FB at panel-native dims. - local_screens_show_ip() — two centered lines: "viewport.local" <current IP> Scale 3x portrait / 4x landscape; centered vertically. - local_screens_show_loading() — centered "Loading..." at scale 4x/5x. - local_screens_restore_for_state() — repaint after BOOT-overlay expiry: UNCONFIGURED -> IP screen; AWAKE/ASLEEP -> black FB (next /frame or sleep handles the rest). - All paths go through display_present_rgb565() so orientation rotation is automatic. button.{h,c}: - Polling task at 30ms, active-low with internal pull-up. - Short press (<5s, released) → backlight on, IP overlay for 15s via esp_timer one-shot, then restore. - Hold ≥ 5s → nvs_config_reset() + esp_restart(). - PIN_BOOT_BUTTON = GPIO 0 is a TODO placeholder. ESP32-P4 strap pin GPIO35 is owned by RMII TXD1 at runtime so Waveshare must expose a separate user button on a free pin; confirm against the schematic. Fail-soft if mis-wired: input reads stuck-high and the task never fires. state_machine on AWAKE transition now calls local_screens_show_loading() right after display_wake() — so every wake (tap or POST /state) flashes a clear "Loading..." until the next /frame paints over it. app_main on boot: - Calls local_screens_init() after display_init(). - UNCONFIGURED → paint IP screen (replaces the M3 test pattern). - ASLEEP → backlight off (unchanged). - After all subsystems: button_init(). Build clean against ESP-IDF 5.4 (binary ~870 KB; the font/glyph data is under 800 bytes). TESTING.md M8 documents the visual checks, the BOOT-pin placeholder caveat, the AWAKE-overlay-overwrite behavior, the open follow-up about post-overlay backlight when ASLEEP, and the font fallback policy.