Skip to content

Add LilyGO T4-S3 board target + UI layout refactor#11

Open
jjhuff wants to merge 1 commit into
HermannBjorgvin:mainfrom
jjhuff:jjhuff/lilygo-t4s3-port
Open

Add LilyGO T4-S3 board target + UI layout refactor#11
jjhuff wants to merge 1 commit into
HermannBjorgvin:mainfrom
jjhuff:jjhuff/lilygo-t4s3-port

Conversation

@jjhuff

@jjhuff jjhuff commented May 15, 2026

Copy link
Copy Markdown

NOTE: I'm happy to keep this as a draft until #5 merges, then I can roll that in. The ui_layout work fit nicely, so I pulled that in to simplify the rebase. Thanks @lorddavidson and @HermannBjorgvin

Adds a second board target (LilyGO T4-S3, 450×600 portrait, RM690B0 + CST226SE + SY6970) alongside the existing Waveshare 2.16" 480×480.

Commits

  1. Multi-board scaffolding + LilyGO bring-up — splits `display_cfg.h` into a per-board header dispatcher, adds typedef driver aliases (`DisplayDriver`, `TouchDriver`, `PmuDriver`, `ImuDriver`) and capability flags (`HAS_IMU`, `HAS_PMU_BUTTON`, `HAS_BTN_FWD`) so shared code can gate features without naming a board. Includes the SY6970 `0x6A` address fix, RM690B0 column offset (482-wide controller → 450-wide viewport), and panel-power sequencing via `power_early_enable()` before `gfx->begin()` (the SY6970's PMICEN gates the panel rail on this board).
  2. screenshot.sh: honor SCREENSHOT_START dimensions — was hardcoded to 480×480, now uses the panel size the firmware reports.
  3. Centralize UI layout in ui_layout.h — adapts the layout-header approach from Add macOS host support and Waveshare 1.8" AMOLED board port #5. Currently only one per-board override (`UI_BT_LINE_FONT` drops to styrene_24 on LilyGO so the BT-screen MAC line doesn't clip at the right edge of the 450-wide panel).

Test plan

  • `pio run -e waveshare_amoled_216` builds clean
  • `pio run -e lilygo_t4s3` builds clean
  • Hardware bring-up on T4-S3: display, touch, BLE, SY6970 all init OK
  • Splash / Usage / Bluetooth screens render correctly on 450×600
  • BLE pairs with daemon as "Claude Controller"
  • Hardware retest on Waveshare 2.16" (no Waveshare board on hand right now — code path unchanged, but ui_layout.h refactor warrants a sanity check)

@HermannBjorgvin

Copy link
Copy Markdown
Owner

Ok I'll test that the 2.16" board still works and merge in that order, #5 and then yours

An alternative hardware section in the readme might be warranted soon, I appreciate people aren't letting the hardware availability stop them

@jjhuff

jjhuff commented May 15, 2026

Copy link
Copy Markdown
Author

Ok cool, I'll get this rebased on #5.
Re hardware: yeah, at least a "known working" list.

This was actually my first firmware work with Claude code, and it was fantastic. There's so many of these modules that are just a little bit different.

@HermannBjorgvin

Copy link
Copy Markdown
Owner

Hey thanks for your contribution! Here's a bit of an update:

I held off on merging any alternative hardware ports because I wanted a good abstraction layer for that. Then @tobby168 came in clutch and delivered that in #25 with instructions in the docs folder on how to implement your port.

We include detailed instructions now which hopefully would allow your clanker to refactor your PR to conform with the new standard, thank you for your patience!

P.S. if you can post a picture of your port that would be appreciated, I enjoy seeing how it looks on people's devices!

@jjhuff

jjhuff commented May 21, 2026

Copy link
Copy Markdown
Author

Awesome, 100% in support. I'll get it updated

New port under firmware/src/boards/lilygo_t4s3/ implementing the HAL
introduced by PR HermannBjorgvin#25:

- RM690B0 QSPI panel with col_offset=16 (visible 450 cols inside 482-wide
  controller RAM), no rotation
- CST226SE touch via SensorLib TouchClassCST226
- SY6970 charger PMU (XPOWERS_CHIP_SY6970); voltage→% approximation
  since the chip is a charger, not a fuel gauge
- PMICEN (GPIO 9) raised in board_init() before display brings up, so
  the panel rail is alive when display_hal_init() probes the QSPI bus
- No IMU, no PMU push-button, no second GPIO button — screen cycling
  maps to a 1500 ms long-hold of BOOT synthesized as a PWR press inside
  power_hal, well above a comfortable voice-mode PTT hold so it doesn't
  trigger accidentally

ui.cpp::compute_layout() gets a narrow-panel override: the BT "Address:"
line at styrene_28 clipped the right margin on the 450-wide panel, so a
single-font swap to styrene_24 kicks in for c.width < 470. The two
reference ports are unchanged (480 ≥ 470; 368 was already in the compact
branch with styrene_20).

Verified on hardware: splash, usage, and BT screens all render correctly;
BLE handshakes with the host daemon and shows Connected with the MAC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jjhuff
jjhuff force-pushed the jjhuff/lilygo-t4s3-port branch from 0ed42ac to c99559c Compare May 21, 2026 23:44
@jjhuff

jjhuff commented May 22, 2026

Copy link
Copy Markdown
Author

@HermannBjorgvin Updated!
Here's my hardware:
PXL_20260521_233526404

I need to find/design a case w/ battery, and maybe wireless charging...

@jjhuff
jjhuff marked this pull request as ready for review May 22, 2026 00:17
phowpinyo added a commit to phowpinyo/Clawdmeter that referenced this pull request May 22, 2026
Third reference port — a 240x240 IPS LCD kit with ST7789 over SPI,
CST816 capacitive touch, QMI8658 IMU, three buttons (BOOT/PLUS/PWR),
and no PMU (battery indicator hidden via BOARD_HAS_BATTERY=0).

Board files (firmware/src/boards/waveshare_lcd_154/):
- display.cpp: Arduino_ST7789 + Arduino_ESP32SPI, backlight PWM via ledc
- touch.cpp: SensorLib TouchDrvCSTXXX (CST816 @ 0x15)
- power.cpp: PWR button on GPIO 4 with debounced edge detection
  (replaces the AXP2101 PKEY IRQ path used on the AMOLED ports)
- imu.cpp: QMI8658 polling, same logic as the 2.16 port
- IMU rotation is OFF (BOARD_HAS_ROTATION=0) — see gotcha HermannBjorgvin#11 about
  ST7789 GRAM ghost on runtime setRotation()

Shared code changes (ui.cpp):
- New tiny breakpoint (H < 280) in compute_layout for 240x240. Logo,
  Bluetooth credits, and the usage anim line are hidden at this size.
- Lifted previously-hardcoded usage screen fonts into the Layout struct
  so the tiny breakpoint can pick smaller fonts. Large/compact branches
  keep previous values, so the 480x480 and 368x448 ports render the
  same as before.
- Fixed apply_battery_visibility() to honor caps.has_battery.

CLAUDE.md updated for the third port + two new gotchas.

Verified: builds clean for waveshare_lcd_154 and waveshare_amoled_216
(regression-safe). Flashed to live hardware — splash, Usage, Bluetooth
screens all render correctly at 240x240.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
phowpinyo added a commit to phowpinyo/Clawdmeter that referenced this pull request May 22, 2026
… setRotation

ST7789's setRotation() only rewrites MADCTL — the panel's GRAM keeps
the previous frame, so when LVGL flushes the new orientation the old
pixels show through as a ghost in the new coordinate system (this was
gotcha HermannBjorgvin#11 in CLAUDE.md and the reason rotation was originally off on
this port).

Fix: in display_hal_tick(), on rotation change call setRotation(rot)
then fillScreen(0x0000) to wipe GRAM in one burst, then invalidate the
LVGL active screen so it redraws at the new orientation, then ramp the
backlight back from 0 → 200 over ~100ms so the transition reads as
deliberate.

Flips BOARD_HAS_ROTATION back to 1 and caps.has_rotation = true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
iBrewerRoot added a commit to iBrewerRoot/Clawdmeter-Standalone that referenced this pull request Jun 20, 2026
The autonomous WiFi path runs a TLS handshake whose mbedTLS buffers are
routed to PSRAM (the libs build INTERNAL_MEM_ALLOC), so a PSRAM-free chip
can't complete a poll. The ESP32-C6 board has no PSRAM and is dropped.

- remove the waveshare_amoled_216_c6 env + board folder
- README: 2 supported boards, "PSRAM required" note, porting board criteria
- docs/porting: capability-flags + adding-a-board explain why PSRAM is
  mandatory (TLS handshake) and that no-PSRAM ports aren't viable
- CLAUDE.md: replace the daemon section with the autonomous Networking
  flow, update buttons (Enter + triple-click portal), architecture module
  list, gotcha HermannBjorgvin#11 (mbedTLS-on-PSRAM + pinned roots)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants