Status: Beta testing — several users have flashed successfully. See Known Issues below.
Standalone off-grid LoRa mesh messaging firmware for the LilyGo T-Deck (ESP32-S3 + SX1262 + ST7789 240×320 TFT touchscreen + physical QWERTY keyboard).
Built on the MeshCore mesh networking protocol — fully interoperable with existing MeshCore repeaters, room servers, and companion radios.
| Feature | Status |
|---|---|
| Dark Discord-like UI (LVGL v9.3.0) | ✅ Complete |
| Home screen (4×3 icon grid + status bars) | ✅ Complete |
| Chat screen (channel list, message bubbles, text input) | ✅ Complete |
| Packets / Contacts / Repeaters screens | ✅ Complete |
| Signal / Network diagnostics screens | ✅ Complete |
| Map (offline tiles + PNG/JPEG decode) | ✅ Complete |
| Settings / Terminal / Trace screens | ✅ Complete |
| Finder / Advertise / Onboarding wizard screens | ✅ Complete |
| MeshCore protocol (radio, routing, encryption) | ✅ Integrated |
| T-Deck HAL (display, battery, LoRa, pins) | ✅ Complete |
| Unit tests (13 modules) | ✅ 276 tests |
| Touch input driver (GT911) | ✅ Complete |
| Keyboard input driver (I2C, ESP32-C3 MCU) | ✅ Complete |
| Full mesh messaging (send/receive queue + UI integration) | ✅ Complete |
| GPS NMEA parser | ✅ Complete |
| SD card support (SPI mount, read/write) | ✅ Complete |
| Offline map renderer (tile math + LVGL canvas grid) | ✅ Complete |
# Run all 276 tests on native platform (no hardware needed)
pio test -e native_test -v
# Run a specific test module
pio test -e native_test -f test_battery -v| Test Module | Tests | What's Covered |
|---|---|---|
test_touch |
22 | GT911 coordinate mapping, multitouch parsing, press→release lifecycle |
test_keyboard |
20 | Matrix scan, keymap, debounce, ghost detection, LVGL mapping |
test_battery |
16 | mV→% conversion, clamping, monotonicity, edge cases, ADC math |
test_sdcard |
15 | SPI init, mount, read/write, directory listing, edge cases |
test_mesh_messaging |
15 | Message queue, send/receive, channel ops, contact export |
test_map |
14 | Tile math (lat/lon→tile), zoom levels, bounding box |
test_mesh_wrapper |
13 | API signatures, return value ranges, unread count init |
test_navigation |
12 | Forward/back with history stack, deep nav chains, all pairs |
test_gps |
12 | NMEA parsing, coordinate conversion, fix detection |
test_trackball |
9 | Direction debounce, deadtime, click detection, idle calibration |
test_pins |
9 | GPIO ranges, SPI/I2C bus conflicts, duplicate detection, LoRa params |
test_theme |
7 | Color darkness, vibrancy, distinctness, readability hierarchy |
test_build |
7 | All headers compile together, cross-module API consistency |
Full test documentation: test/README.md
| Component | Detail |
|---|---|
| MCU | ESP32-S3, 240 MHz, 16 MB Flash, 8 MB PSRAM |
| Display | ST7789 240×320 TFT (landscape via rotation) |
| Touch | GT911 capacitive (I2C) |
| Keyboard | Physical QWERTY matrix |
| LoRa | SX1262 (SPI) |
| GPS | Serial1 (optional) |
| SD Card | SPI (shared bus) |
SlopOS-tdeck/
├── firmware/ ← Pre-built merged binaries (flash at 0x0)
├── lib/meshcore/ ← Git submodule: MeshCore protocol (routing, radio, encryption)
├── src/
│ ├── main.cpp ← Boot sequence (board → display → mesh → UI)
│ ├── lv_conf.h ← LVGL v9 config (16-bit, partial render)
│ ├── hal/
│ │ ├── tdeck_pins.h ← Complete T-Deck pinout + version string
│ │ ├── tdeck_board.h ← TDeckBoard :: mesh::MainBoard
│ │ ├── display.cpp/h ← LovyanGFX ST7789 + LVGL driver
│ │ ├── trackball.cpp/h ← 5-direction trackball (debounce, event queue)
│ │ ├── battery.cpp/h ← ADC battery (mV + %)
│ │ ├── touch.cpp/h ← GT911 touch controller (I2C)
│ │ ├── keyboard.cpp/h ← I2C keyboard (ESP32-C3 MCU)
│ │ ├── gps.cpp/h ← NMEA GPS parser (Serial1)
│ │ ├── sdcard.cpp/h ← microSD card (SPI, shared bus)
│ │ └── prefs.cpp/h ← NVS preferences (radio config, identity)
│ ├── mesh/
│ │ ├── mesh_wrapper.cpp/h ← SX1262 radio init, RTC, mesh API
│ │ └── slop_mesh.h ← SlopMesh : mesh::Mesh subclass
│ ├── app/
│ │ └── map_renderer.cpp/h ← Offline map tile renderer (PNG/JPEG, PSRAM canvas)
│ ├── fonts/
│ │ └── emoji_font_setup.cpp/h ← Emoji font fallback
│ └── ui/
│ ├── theme.h ← Discord-inspired dark palette
│ ├── responsive.h ← Adaptive layout helpers (bars, grids, dialogs)
│ ├── home_screen.cpp/h ← 4×3 icon grid + top/bottom bars
│ ├── chat_screen.cpp/h ← Discord-like chat (channels, bubbles, input)
│ ├── screens.cpp/h ← Heard, Map, Settings, Terminals, etc.
│ ├── onboarding_screen.cpp/h ← First-boot setup wizard
│ ├── navigation.cpp/h ← Screen routing with animations
│ └── ui.cpp/h ← Splash → Home transition
├── boards/t-deck.json ← PlatformIO board definition
├── platformio.ini ← Build config (ESP32-S3 + LVGL + MeshCore)
├── test/ ← Unit test directory (13 modules, 171 tests)
- PlatformIO (VS Code extension or CLI)
- LilyGo T-Deck with USB-C cable
Install everything from a PowerShell terminal:
# 1. Git
winget install Git.Git
# 2. Python 3.12
winget install Python.Python.3.12
# 3. PlatformIO CLI
pip install platformio
# 4. CP210x USB driver (for T-Deck USB-to-UART)
# Download from: https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers
# Unzip → right-click silabser.inf → Install
#
# Verify: Device Manager → Ports (COM & LPT) → "Silicon Labs CP210x USB to UART Bridge"Restart your terminal after installing Python, then verify:
git --version
python --version
pio --version# Ubuntu/Debian
sudo apt install git python3 python3-pip
pip install platformio
# Arch
sudo pacman -S git python python-pip
pip install platformioNo USB driver needed on Linux — the CP210x kernel module ships with the kernel.
# Homebrew
brew install git python platformioNo USB driver needed on macOS — the CP210x driver is built into the OS.
git clone --recurse-submodules https://github.com/hermes-gadget/SlopOS-tdeck.git
cd SlopOS-tdeckIf lib/meshcore/ is empty after clone, run:
git submodule update --init --recursivepio run -e SlopOS_TDeckFirst build downloads the ESP32-S3 toolchain (~800 MB). Subsequent builds are fast.
Put the T-Deck in download mode: hold the trackball button while plugging in USB (or hold BOOT + tap RESET). The screen stays black — that's correct.
pio run -e SlopOS_TDeck -t uploadpio device monitor -b 115200After cloning, these files must exist or the build will fail:
| File | Purpose |
|---|---|
boards/t-deck.json |
Board definition (16 MB flash, QIO, ESP32-S3) |
lib/meshcore/src/Mesh.h |
MeshCore submodule (must not be empty) |
platformio.ini |
Build configuration |
Pre-built merged binaries are in firmware/. Flash directly with esptool — no PlatformIO needed:
pip install esptool
esptool.py --chip esp32s3 --port COM21 --baud 921600 \
--before default_reset --after hard_reset write_flash \
--flash_mode qio --flash_freq 80m --flash_size 16MB \
0x0 firmware/slopos-tdeck-merged.binSee firmware/README.md for details.
All screens from the SlopOS T-Deck UI, captured from a live device running the production firmware build.
GPL-3.0-or-later
This project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Dependencies remain under their original licenses (MIT, FreeBSD, LGPL-2.1, zlib/libpng, BSD-3-Clause) — see Open Source Acknowledgments below for the full audit.
This project builds on and incorporates open source software from the following projects:
| Project | License | Usage in SlopOS |
|---|---|---|
| MeshCore | MIT | Mesh networking protocol (submodule at lib/meshcore/). Also: RTC clock (ESP32RTCClock), auto-off display timer, deep sleep patterns, and NodePrefs struct — all adapted from MeshCore's companion radio firmware. |
| LilyGo T-Deck Keyboard_ESP32C3 | MIT | I2C keyboard protocol reference — our keyboard.cpp driver is based on the command set and keymap from this firmware (© 2023 Shenzhen Xin Yuan Electronic Technology Co., Ltd) |
| LVGL | MIT | Embedded GUI framework (v9.3.0) |
| LovyanGFX | FreeBSD | Display driver for ST7789 TFT |
| RadioLib | MIT | SX1262 LoRa radio driver |
| Adafruit BusIO | MIT | I2C/SPI bus abstraction for sensor/display drivers |
| Arduino Crypto | MIT | AES/SHA for MeshCore packet encryption |
| Google Test | BSD-3-Clause | Unit testing framework |
| ed25519 | zlib/libpng | Embedded Ed25519 crypto (Orson Peters) — bundled in MeshCore at lib/meshcore/lib/ed25519/ |
| ESP32 Arduino Core | LGPL-2.1 | ESP32-S3 hardware abstraction and Arduino framework (LGPL→GPLv2+ bridge compatible) |
| PlatformIO | Apache 2.0 | Build system (not linked into firmware) |













