Skip to content

E213: runtime-configurable display rotation via NodePrefs#2393

Open
chrisfore wants to merge 10 commits intomeshcore-dev:devfrom
chrisfore:fix/e213-display-rotation
Open

E213: runtime-configurable display rotation via NodePrefs#2393
chrisfore wants to merge 10 commits intomeshcore-dev:devfrom
chrisfore:fix/e213-display-rotation

Conversation

@chrisfore
Copy link
Copy Markdown

Problem

src/helpers/ui/E213Display.cpp hardcodes display->setRotation(3). Users who flash stock firmware from the web flasher can't un-flip the display when their case orients the panel differently — the only current fix requires a source rebuild with a custom build flag, which is out of reach for most users.

Solution

Adds uint8_t display_rotation to both NodePrefs structs (companion_radio and the common one used by repeater/room_server) and exposes it via the existing text CLI:

  • set display.rotation N / get display.rotation in CommonCLI (repeater, room_server)
  • set display.rotation N in companion_radio's MyMesh.cpp CLI (matches set pin style)

Value range 0–3 (same semantics as Arduino GFX setRotation). Default is 3, preserving current behavior for every existing install. DisplayDriver gets a virtual no-op setRotation(uint8_t) so main.cpp can call it uniformly; E213Display overrides it. The three main.cpp files (companion_radio, simple_repeater, simple_room_server) call display.setRotation(prefs->display_rotation) after prefs load.

Schema migration

New field is appended at the end of the existing fixed-offset NodePrefs serialization in both src/helpers/CommonCLI.cpp (byte 291) and examples/companion_radio/DataStore.cpp (byte 137). Reading an older prefs file returns 0 bytes for the trailing read, leaving the in-memory default of 3. No data loss, no format break. Same pattern already used when rx_boosted_gain was moved to the end of CommonCLI's layout.

Verified on hardware

Tested on a Heltec Vision Master E213 running Heltec_E213_companion_radio_usb:

  1. Fresh install rotation change: flashed fix-branch firmware on erased flash, entered CLI rescue mode (long-press USER button within 8s of boot), ran set display.rotation 1 over USB serial, rebooted. Display renders at rotation 1 — un-flips the panel in the target 3D-printed case.
  2. Persistence across cold boot: full power-cycle after step 1. Rotation stayed at 1, confirming savePrefs() wrote correctly.
  3. Backward-compat from stock firmware: flashed stock Heltec_E213_companion_radio_usb from meshcore.io/flasher on erased flash, set pin 999999 via CLI rescue, then reflashed fix-branch firmware at 0x0 without erasing the data partition. On reboot, display renders at rotation 3 (new field defaulted correctly on the old prefs file), and cat UserData/new_prefs shows ble_pin bytes at offset 80 still reading 3F420F00 (= 999999 little-endian) — migration preserves all existing fields.

Also clean-built across all 5 E213 envs (companion_radio_{usb,ble}, repeater, room_server, repeater_bridge_espnow) and regression envs (Heltec_v3_repeater, Heltec_v3_companion_radio_usb, RAK_4631_repeater).

Known limitation for companion_radio_usb users

On companion_radio_usb, the USB Serial is dedicated to the binary cmd_frame protocol for the companion app, so raw text input from a terminal like screen is consumed by the frame parser (ArduinoSerialInterface::checkRecvFrame discards non-< bytes) and never reaches the text CLI reader. The existing CLI rescue mechanism (long-press USER button within 8 s of boot, which sets _cli_rescue = true) gives access to the text CLI — that's how I ran set display.rotation in the verification above. companion_radio_ble users don't have this issue: Serial is free because the companion protocol runs over BLE.

A cleaner UX (exposing display_rotation via a new cmd_frame opcode so the phone app can toggle it without the rescue-button gesture) is filed as a follow-up issue.

Out of scope / follow-ups

  • E290Display.cpp has the same hardcoded-rotation pattern; filed as a separate issue (I have no E290 hardware to test).
  • cmd_frame opcode for companion-app display_rotation control — separate issue. Needed by both companion_radio_usb users (to avoid rescue-mode workaround) and _ble users (who have no USB CLI at all).
  • Bringing other display drivers (SSD1306, ST7735, GxEPD, ST7789) onto the prefs-backed mechanism — out of scope; they continue to use the DISPLAY_ROTATION compile flag.

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.

1 participant