Commit Graph
848 Commits
Author SHA1 Message Date
pelgraine 355cd594e6 BLE: MECK_BLE_TX_POWER build flag (default +9 dBm), meck_max_ble at +15 dBm 2026-10-01 07:02:00 +10:00
pelgraine 178b2ef3cf Remove T5S3, T-Echo, CardKB and nRF support 2026-09-29 06:46:19 +10:00
pelgraine 1bad37d1ad Large font channel message view word wrap bug fix: What changed:
Driver: setTextWrap(false) once at init. GFX no longer moves text to the next line by itself, anywhere. This is what put the stray "t" on the margin; without it, a line the screen miscounts is clipped at the edge instead, which is the lesser evil for a UI that does all its own wrapping. Applies to every e-ink build, Pro and Max.
Compose: the usable line width is now the panel width less the driver's 2-unit x offset, so the compose wrap and the glyphs' real positions agree and lines wrap one word earlier when they need to.

GxEPD2_310_GDEQ031T10_FAST.cpp → fingerprint 473 (was 464). The 9-frame bytes (0x89 / 0x49 / 0x09) become 0x8C / 0x4C / 0x0C: same level bits, count 12. Improves colour density in Max fastlut test build.
2026-09-13 21:10:08 +10:00
pelgraine c276597f60 E-ink fast-waveform experiment build; GBC loading box and save timing
EXPERIMENT (Max only, env meck_max_ble_fastlut; all other builds unchanged)
- New vendored driver src/helpers/ui/GxEPD2_310_GDEQ031T10_FAST.{h,cpp}:
  the GxEPD2 GDEQ031T10 driver with a selectable partial-refresh
  waveform. Default is "LUT from register" loaded with the register
  tables bitbank2/bb_epaper uses for this panel on the T-Deck Pro (one
  9-frame push per pixel); the factory OTP waveform stays available.
  Full refreshes unchanged. Measured on the Max: partial refresh 244 ms
  (652 ms on the factory waveform) on home, menus, ROM list and typing.
  Cost: one short push per pixel gives weaker blacks and half-develops
  dithered stipple, so it suits text and does not suit the game.
- GxEPDDisplay: setFastWaveform() and fastPartialsSinceFull(), no-ops
  outside the experiment env. Switching back to the factory waveform
  hibernates the panel so the next refresh goes through a hardware
  reset (tested as a ghosting fix; it was not one, kept as a clean
  hand-over).
- UITask::setCurrScreen: after EINK_FAST_FULL_EVERY (20) fast partials
  the redraw at the next screen change is a full refresh, so the
  register waveform's ink imbalance is cleared where a redraw is
  happening anyway rather than mid-typing.
- GBC emulator switches the driver to the factory waveform while a
  game runs (its dithered picture needs the longer drive) and back to
  fast on quit.
- Finding, for the record: moving-sprite ghosting in Pokemon Gold
  appears on the stock build too, so it is the game plus dither plus
  the factory partial waveform, not the experiment.

GBC EMULATOR (all T-Deck builds)
- "Loading..." alert box the moment Enter is pressed on a ROM row; the
  multi-second SD read now runs on the next loop pass, after the box is
  on the panel, instead of inside the key handler.
- Games start with a full refresh (clean panel; added during the
  ghosting investigation, kept pending review).
- Save writes are timed and the durations logged (remove/open/write/
  close), after one unexplained ~45 s UI stall coincided with a save.

Files: examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp},
examples/companion_radio/ui-new/UITask.cpp, src/helpers/ui/GxEPDDisplay.h,
src/helpers/ui/GxEPD2_310_GDEQ031T10_FAST.{h,cpp},
variants/lilygo_tdeck_max/platformio.ini
2026-09-13 19:31:06 +10:00
pelgraine aadbac4996 Removed ptscan related reduncant code from gxepddisplay 2026-09-13 10:56:22 +10:00
pelgraine b6963e9411 GBC emulator: robust after Bluetooth, background saves, faster typing, font prefs on games menus
Follow-up to the v1.14 emulator commits. T-Deck Max unless noted.

MEMORY AND STABILITY (GBCEmulatorScreen.cpp)
- Emulator task stack is now 8 KB, static, reserved at boot. Once
  Bluetooth has been switched on in a boot its stack stays resident
  (SerialBLEInterface::disable() never releases it) and a later game
  launch could not find 12 KB of internal RAM in one piece. Measured
  use is about 2 KB.
- Core context released on every failed launch, not just on quit; a
  failure no longer holds 50 KB.
- No periodic full refresh during play (too distracting). The full
  refresh on quit stays, to clear ghosting before the ROM list.

SAVES
- .sav written in the background: cart-RAM writes mark it dirty and
  the UI task writes the file once the game has left its cart RAM
  alone for 2 s, i.e. shortly after the user saves in-game. Quit
  writes only if still dirty, and no longer draws and refreshes an
  intermediate "Saving..." frame (that frame cost 650 ms by itself).

INPUT
- Both-shifts keyboard-backlight chord works mid-game: it is the one
  key raw joypad mode lets through. The toggle body moved from
  handleKeyboardInput() into toggleKeyboardBacklight() (main.cpp) so
  the game and the normal path share one on/off state.
- On quit the keyboard stays in raw mode, still drained through the
  panel's busy wait, until the ROM list has been drawn. Keys pressed
  during the quit flash used to queue in the TCA8418 and replay as
  navigation afterwards (one held Q ran four screens back).

PICTURE
- Game pictures after the first refresh only the 216-line game window
  (GxEPDDisplay::requestWindowRefresh, consumed by endFrame). Measured
  at 652 ms either way, the same as full-panel: the panel's waveform
  time is the floor, so this saves data transfer only.

TYPING (main.cpp, all e-ink builds)
- COMPOSE_REFRESH_INTERVAL 700 -> 0. lastComposeRefresh is stamped
  after the blocking e-ink refresh completes, so the interval only
  added dead time on top of it. Worst-case keystroke-to-screen drops
  from about 1.6 s to about 0.9 s. COMPOSE_TYPING_PAUSE unchanged.

GAMES MENUS
- Games menu and Game Boy ROM list rows follow the user's font size
  and style via the NodePrefs helpers (as the channel picker does);
  Max touch hit-test updated to match. Footers read Q:Back.

BUILD ENVS (Pro)
- meck_audio_wifi_hyn and meck_audio_standalone_hyn, the HYN-touch
  counterparts of the existing meck_audio_ble_hyn.

Files: examples/companion_radio/{main.cpp, ui-new/GBCEmulatorScreen.{h,cpp},
ui-new/GamesMenuScreen.h}, src/helpers/ui/GxEPDDisplay.{h,cpp},
variants/lilygo_tdeck_max/TCA8418Keyboard.h,
variants/lilygo_tdeck_pro/platformio.ini
2026-09-13 07:21:33 +10:00
pelgraine 3647bdcc88 GBC emulator: full speed, 1.5x dithered picture, live keys, ghosting control
Follow-up to the initial Game Boy emulator commit (T-Deck Max).

SPEED (GBCEmulatorScreen.cpp)
- Pacing keeps its deficit: a frame that finishes late is paid back by
  running the next ones back-to-back instead of resetting the deadline
  and forgiving the lost time, which held Pokemon Gold at 0.96x. Only a
  stall of more than 250 ms resyncs. Now measures 1.00x on every 5 s
  window. A 1 ms yield every 30 undelayed frames keeps the idle task
  (and the task watchdog) fed.
- The core context (49952 bytes) is allocated from internal RAM for
  the duration of a game and freed on quit, with PSRAM as the fallback
  if no internal block is free; the launch log says which it got.
- Speed line printed to serial every 5 s (window fps, average, ratio to
  real time).

INPUT (GBCEmulatorScreen.cpp, GxEPDDisplay.h)
- GxEPDDisplay::setBusyCallback() exposes GxEPD2's busy-wait hook. The
  emulator registers a keyboard poll on it while a game runs, so key
  presses and releases are seen through the ~650 ms panel refresh
  instead of waiting for it to finish.

PICTURE (GBCEmulatorScreen.cpp, UITask.cpp, GxEPDDisplay.{h,cpp})
- 1.5x nearest-neighbour scale to 240x216, the full panel width,
  centred; title line removed, quit hint kept.
- Ordered 4x4 Bayer dithering replaces the single threshold: the four
  Game Boy shades map to 0, 6, 11 and 16 dark pixels in 16, so
  sprites with mid-tone colours are no longer flattened to white or
  black. The pattern is fixed to panel position so it does not crawl
  between refreshes.
- UITask: the 800 ms minimum interval between e-ink refreshes is
  lifted while a game runs, so pictures follow at the panel's own
  partial-refresh rate (about 0.7 s).
- GxEPDDisplay::requestFullRefresh(): the next endFrame() uses the
  full black/white waveform regardless of frame change. The emulator
  requests one every 45 pictures (about 30 s) and once on quit, to
  clear the residue that continuous partial refreshes leave on the
  game screen and the home screen after it. No other screen calls it.

Files: examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp},
examples/companion_radio/ui-new/UITask.cpp,
src/helpers/ui/GxEPDDisplay.{h,cpp}
2026-09-13 01:23:02 +10:00
pelgraine db9f5ae7b6 Fix Maps tile SD detection; add Garmin BLE build env; Game Boy emulator (T-Deck Max)
MAPS FIX (all T-Deck Pro and Max builds)
Opening Maps from the home tile showed "SD card not found" until the G key
had been pressed once that boot. The map screen's SD flag was only set by
the G key handler; the touch tile and CardKB routes opened the screen
without it. The G handler's setup (SD flag, GPS position, contact markers,
CPU boost) is now openMapScreen() in main.cpp and all three routes call
it. G on the map (re-centre) is unchanged.

PLATFORMIO (variants/lilygo_tdeck_max)
- New meck_max_ble_garmin env for the Garmin watch companion: identical to
  meck_max_ble with BLE_DEBUG_LOGGING, MECK_BLE_JUST_WORKS (no-passkey
  pairing), MECK_BLE_SMALL_MTU_SPLIT (23-byte ATT frame slicing),
  MECK_WATCH_EXT (watch extension commands) and MECK_BLE_SLOW_INTERVAL
  switched on.
- meck_max_ble now has those five flags commented out, so the standard
  phone-app build is isolated from the watch experiments.

GAME BOY / GAME BOY COLOR EMULATOR (T-Deck Max only in this build)
New "Game Boy" entry in the Games menu. Lists .gb/.gbc ROMs in /roms on
the SD card and runs them with the Peanut-GB core (same patched copy as
Meck-P4) in its own task on core 0 at the real 59.73 fps, drawing a
black-and-white snapshot to the e-ink at the panel's refresh rate.
- Keys: W/A/S/D d-pad, K = A, J = B, Enter = Start, Space = Select,
  Shift+Backspace = quit (save written). No sound yet.
- Saves: .sav next to the ROM, written on quit.
- LoRa radio in standby and mesh loop paused while a game runs (reuses
  the OTA pause). CPU held at 240 MHz.
- Keyboard polled through the e-ink busy wait so input is not delayed by
  the ~650 ms refresh; the 800 ms refresh floor is lifted during play.
- Speed line printed to serial every 5 s.
Files:
- ui-new/GBCEmulatorScreen.{h,cpp} (new), ui-new/peanut_gb.h (new)
- ui-new/GamesMenuScreen.h: GAME_GBC entry
- ui-new/UITask.{h,cpp}: gbc_screen, goto/is/get, resetIdleTimer(),
  no refresh floor while a game runs
- main.cpp: launch, exit and key routing
- variants/lilygo_tdeck_max/TCA8418Keyboard.h: raw joypad mode
- src/helpers/ui/GxEPDDisplay.h: setBusyCallback()
Pro builds compile unchanged (all emulator code is guarded).
2026-09-13 00:47:40 +10:00
pelgraine 7ebe1b900f Garmin: Regions: derive per-channel scope key at set/load; BLE slice length byte and relaxed watch interval
- ChannelDetails gains scope_key[16]; MyMesh::setChannel derives it from
  scope_name on every write (screens, serial, phone sync, boot load), so
  sending copies bytes instead of doing a name lookup and derivation per
  message. Port of the Meck Watch regions fix.
- getChannelScopeName now copies out instead of returning a pointer into
  a local (dangling; caused intermittent unscoped sends).
- BLE small-MTU slices become [tag][len][payload] (18 payload bytes) so
  stream transports (nRF52) can find slice boundaries; same format on
  ESP32 for one dialect across nodes and the Garmin app.
- New MECK_BLE_SLOW_INTERVAL flag: request a 100-200 ms connection
  interval instead of 15-20 ms for the watch build.
2026-09-08 06:21:26 +10:00
pelgraine 51a4435008 BLE: small-MTU slicing verified with Garmin 2026-09-07 17:34:00 +10:00
pelgraine fe13fc96a9 BLE: recover deviceConnected when auth completes before GATT connect 2026-09-07 06:43:57 +10:00
pelgraine e130019061 New Max Home UI design 2026-07-21 19:03:52 +10:00
pelgraine e447b17f37 Remove T-Watch code from repo 2026-07-19 11:55:31 +10:00
pelgraine 3e40ccbaa1 T-Watch - amend text wrap on settingscreen 2026-07-15 06:14:11 +10:00
pelgraine a5dacc3db8 T-Watch: reduce brightness to 25 2026-07-12 17:39:16 +10:00
pelgraine 0fa7a321bf Rename LILYGO_TWATCH_S3_PLUS to MECK_TWATCH as the watch form-factor gate
The macro was doing double duty: gating the 240x240 touch UI (tile grid, lock
screen, VKB, grey palette) and gating the Plus's onboard GNSS. A non-GPS watch
cannot reuse the first without dragging in the second.

  MECK_TWATCH             watch form factor
  LILYGO_TWATCH_S3_PLUS   Plus-only hardware (GNSS on BLDO1, GPIO0 user button)
  MECK_PMU_BUTTON         user button is the AXP2101 PWRON key, not a GPIO

84 sites renamed across 14 files. The WatchMapScreen include, construction and
its three touch handlers now also require HAS_GPS, as does the Maps tile branch
inside the home tile grid.

Behaviour-preserving: the Plus defines both MECK_TWATCH and HAS_GPS=1, so every
new condition evaluates as before. No other board defines MECK_TWATCH.
2026-07-10 18:40:53 +10:00
Pelgraine ada989ea72 t-watch: spiffs+littlefs partition, maps initial support 2026-07-09 06:32:57 +10:00
Pelgraine 973d02df60 T-Watch target.cpp: fixed preamble = (sf <= 8) ? 32 : 16 to (sf <= 9) which I should have done in the first place to match meshcore PR 1954. Testing on Watch before applying wider change.
T-Watch: So many UI changes. Also swapped render battery indicator to use the AXP2101 gauge for hopefully higher accuracy. Also implemnted meck rx duty cycle for watch builds only to test out power saving effects first on watch build before implementing elsewhere.
2026-07-07 21:58:32 +10:00
Pelgraine d4286fdf84 TWatch: reduce brightness by 15% to save battery, change settingscreen behaviour so utc offset can be edited in standalone build - still yet to edit the rest of the settings to behave accordingly 2026-07-07 06:18:45 +10:00
Pelgraine b8b3353cf3 Fix twatch tilt raise lock screen functionality. Implement unread count on tw_picker. Fix channel missage history and full message view 2026-07-07 06:03:12 +10:00
pelgraine f6d7c48845 watch ui updates prelim 2026-07-04 22:06:33 +10:00
pelgraine 443aa42e7b What you now have on the CLI:
get dutycycle → reports the current duty as a percentage (e.g. > 50%)
set dutycycle <10-100> → sets it, saves to prefs, persists on reboot; anything below 10 or above 100 returns ERR - duty cycle must be 10-100
set af <value> is untouched, for anyone who prefers the raw factor
2026-07-02 06:17:56 +10:00
pelgraine 444631e08b update lock screen reference in Readme; update footers and exit behaviour so nearly all instances of Q:Exit is now Shift+Delete=Exit. Add first pass change for Meck issue 20 to dispatcher cpp and h 2026-06-30 20:05:51 +10:00
pelgraine b80184cf96 initial builds, standalone and ble twatch s3 plus 2026-06-26 19:28:24 +10:00
pelgraine 353048aab3 So the power investigation wraps up like this:
GPS — fixed (the "off" toggle and boot path now actually cut the XL9555 rail). Kept in main.cpp + UITask.cpp.
BLE controller — the ~13 mA between the BLE build (BLE off) and standalone is the controller staying initialised; the boot-gate in SerialBLEInterface.cpp/.h defers BLEDevice::init() until first enable, reclaiming it. That's the meaningful idle win.
CPU, gyro rail, ES8311, frontlight — all measured and ruled out. The residual ~12 mA Max-vs-Pro is distributed always-on hardware with no software switch — hardware overhead, not a bug.

Defer ESP32 BLE controller bring-up to first user enable
MyMesh::startInterface() called serial.enable() unconditionally at boot. On the ESP32 BLE build this ran the deferred-init SerialBLEInterface's _realBegin()/BLEDevice::init() and powered the BT controller before main.cpp's boot-time disable(), which only stops advertising and cannot power the controller back down -- so the controller stayed up while "off", drawing ~13 mA at idle. Guard the enable() so ESP32 BLE builds skip it at boot; the controller now comes up lazily on the first enable() when the user turns Bluetooth on from the Bluetooth page. WiFi builds are unaffected and still enable at boot.
2026-06-07 00:09:56 +10:00
pelgraine 4b734f1bac updated drivers for t-echo card 2026-05-05 12:43:53 +10:00
pelgraine f51d8be290 Fix to beer emoji mug handle; font changes that support diacritics meaning updates to display drivers, fonts, highlighting, sprites; build flag added to both tdpro and t5s3 pro to enable diacritics rendering changes 2026-05-02 09:26:30 +10:00
pelgraine 6c0c77d788 improved tdpro and t5s3 ble sync speed with large contact lists; updated firmware build date 2026-05-02 06:07:12 +10:00
pelgraine 64afdb2829 updated max frame size in base serial interface to match upstream meshcore; fix getbatterypercent in abstractuitask; update renderbatteryindicator et al in uitask; change lock screen refresh to 1 min for td pro and 2 min to t5s3; fix issue in t5s3 where it was still showing lock screen in hibernating mode'; fixed cardkb bug caused by t-echo lite wip work 2026-04-30 00:20:00 +10:00
pelgraine e74aa3b214 t-echo lite - attempt to fix debounce and emoji gibberish 2026-04-22 15:12:20 +10:00
pelgraine 36976e0029 t-echo lite - stripped emoji in contacts and last heard, changed recent adverts list to default 4 2026-04-22 12:54:16 +10:00
pelgraine f461777214 t-echo lite screen: removed diag diagnostic prints, sorted compose mode with cardkb, fixed enter & esc handlers; increased e-ink offset for home screen centering; condensed footer text for all screens; datastore chunked saved guarded for esp32 ; still encountering memory problems with ble build even w 250 contacts and 10 chanel message history so trying standalone 2026-04-21 22:43:29 +10:00
pelgraine db0ecd3c58 initial screen based t-echo lite with card kb support build 2026-04-21 14:07:06 +10:00
pelgraine 4ec5d17402 update remote repeater firmware files to enable loop detection and regions 2026-04-19 22:04:31 +10:00
pelgraine 31ac732f08 fix bug where channels imported from older config files displayed gibberish in channel scope under settingsscreen even when region scope not set; fix bug where after device clock sync advert times last heard weren't displaying correctly (ie showed 16895h) 2026-04-19 20:23:12 +10:00
pelgraine 5c275a8c23 Regions - including settings nudge to remind user if no default nor channel region set. Set region by typing custom entry 2026-04-19 18:17:25 +10:00
pelgraine 8e3a09e3b1 added channel picker screen as messages home screen view; fixed battery curve reading to better reflect actual charge state (4200 to 4160); patched clock sync to throw out garbage rtc when device has been powered off for a while & now syncs on ble app connection: more font style customisation; nav bar hint text reduced when larger fonts are selected; ensured font style persists across reboots 2026-04-19 15:37:52 +10:00
pelgraine d2ce070a3f fix wifi companion builds sync bug & add planning for future 1000+ contacts load 2026-04-12 21:04:35 +10:00
pelgraine 595f0073f9 TDeckBoard.cpp — both * 3 / 2 thresholds changed to > designCapacity_mAh, so FCC=3000 with DC=2500 now triggers the Qmax + stored FCC correction.
SerialBLEInterface.cpp — added esp_bt.h include and three esp_ble_tx_power_set calls at +9 dBm after BLEDevice::init(), covering default, advertising, and scan power types.

MyMesh.h — FIRMWARE_VER_CODE bumped from 10 → 11.
MyMesh.cpp — The RESP_CODE_DEVICE_INFO frame construction now:
Byte 2: sends 0xFF (sentinel) when MAX_CONTACTS > 510, otherwise the normal MAX_CONTACTS / 2. Older apps interpret 0xFF as 510 contacts — completely harmless.
Bytes 80-81 (new, appended after the version string): uint16_t little-endian with the true MAX_CONTACTS value. Apps that understand v11+ read it here. Apps < v11 ignore trailing bytes — the BLE/serial frame protocol is length-delimited, so extra bytes at the tail are safe.

platformio.ini — Both BLE builds (meck_audio_ble, meck_4g_ble) bumped from 510 → 2000.

mymesh.cpp: writeContactRespFrame return type change (return _serial->writeFrame() result)
checkSerialInterface() batch-fill loop.
2026-04-07 20:04:36 +10:00
pelgraine 424e152d4b simple remote wifi repeater v0.2 & remote repeater path hash mode improvements 2026-04-04 10:51:48 +11:00
pelgraine bf8cf32bc2 speed up ble sync time; fix version in tdpro platformio 2026-03-27 01:56:17 +11:00
pelgraine 81eca29b69 implement meshcore PR 2151 changes 2026-03-27 00:43:10 +11:00
pelgraine a7bc7a4733 t5s3 only lightsleep mode 2026-03-25 20:17:42 +11:00
pelgraine 5dda0b686e Incorporate PR 2044 and 2141; tdpro alarm screen - needs 44khz mp3 for sounds 2026-03-25 19:57:35 +11:00
pelgraine c2c2d8cf21 tdpro - reduce occurrences of slow key responsiveness on boot 2026-03-17 18:42:12 +11:00
pelgraine cd69ea546f tdpro lock screen stage 1 - double click user/boot to lock/unlock screen 2026-03-17 16:56:55 +11:00
pelgraine b77059706b tdpro dark mode 2026-03-13 22:50:24 +11:00
pelgraine a6f0052b89 t5s3 standalone clock sync over serial 2026-03-13 22:50:24 +11:00
pelgraine b55892431d t5s3 portrait mode and dark mode 2026-03-13 22:50:24 +11:00
pelgraine dc5331702d 55s3 ghosting improvement 2026-03-13 22:50:24 +11:00