- RLCD device.properties: DefaultDark (focus UI visible), fontSize 18
(+28% vs 14: small 10->14, default 14->18, large 18->24, icons 16->20/36->48)
- ST7305 driver: honor invertColor config (was ignored), call
esp_lcd_panel_invert_color after init
- DisplayDevice: add supportsInvertColor + set/get, and
supportsMonochromeThreshold/set/get (ST7305 only)
- EspLcdDisplay: implement invert via panelHandle, and mono threshold via
global g_mono_threshold shared with esp_lvgl_port
- DisplaySettings: new fields invertColor (default true to preserve current
inverted look) and monochromeThreshold (default 60 best for DefaultDark per
user testing, range 20-230)
- Lvgl.cpp: apply invert + threshold at boot from settings
- Display app: add Invert colors switch (if supportsInvertColor) + Mono
threshold slider with live preview and persistence
- esp_lvgl_port_disp.c (components override for hash mismatch): fix B/W
conversion
BEFORE: blue >16 only -> crushed colors, no gray handling
AFTER: proper luminance Y=0.299R+0.587G+0.114B with adjustable threshold
(default 60), no Bayer dithering dots. Crisp text on reflective
- Launcher/button/list wrappers reverted to stock DefaultDark (no white
focus hacks) per user request - focus UI now uses default outline which
survives luminance threshold
Verified on waveshare-esp32-s3-rlcd /dev/cu.usbmodem1101:
- Build 2877200 bytes, flash hash verified
- Invert toggle works, threshold slider live (60 best per test)
- Font bump visible, focus UI visible for button navigation
- No dithering dots
Docs: LVGL mono https://docs.lvgl.io/9.2/porting/display.html#monochrome-displays
Themes: https://docs.lvgl.io/9.2/details/common-widget-features/styles/themes.html
Co-authored-by: Hermes Agent <hermes@noreply>
- Scan: store nameless directed adv to keep addr_type cache for Fosmon-type
keyboards that wake without name -> fixes auto-connect on boot not finding device
- HID parser: strip Report ID, support standard 3/4-byte mouse [btn,x8,y8,wheel]
instead of mis-detecting as 12-bit packed; heuristic only when std small
- HID reconnect: try PUBLIC then RANDOM addr_type with 8s timeout,
periodic retry timer (3/10/30s backoff) that exists at boot via ensureAutoConnTimer,
direct connect even without advert after empty scans to catch wake-on-keypress
- Verified on waveshare-esp32-s3-rlcd /dev/cu.usbmodem1101 - Fosmon mini
B00BX0YKX4 combo now moves smoothly and reconnects after board restart
Co-authored-by: Hermes Agent <hermes@noreply>
RLCD ST7305 has !supportsBacklightDuty(). Previous fix that fixed MCP flash-then-back left entire idle state machine gated by supportsBacklight, causing once dimmed it could never wake on button press -> appears locked weird state reported.
Fix: run timeout logic for all displays, guard only setBacklightDuty calls.
- timeout disabled (Never) branch always restores displayDimmed
- timeout activation creates screensaver for all
- wake on inactive<100ms + charging block works for RLCD
- setBacklightDuty only when supportsBacklight && display!=nullptr
Also preserves deadlock-free ordering (MCP state outside LVGL lock) from 3629ffef.
RLCD: 0x2b78b0 32%% free flashed /dev/cu.usbmodem101
Co-Authored-By: internal-model
DisplayIdle::tick() runs every 50ms. After startMcpScreensaver()
sets displayDimmed=true, the next tick saw inactive_ms < 100ms
(user navigated Settings) and called stopScreensaver() ->
overlay deleted in <1s, text tool flash-then-back.
Root cause: idle wake logic (inactive<100ms) + charging guard +
duty-restore all operated on any overlay including MCP override.
Fix: detect MCP active via (drawArea != nullptr || overrideActive)
under state.mutex, guard all auto-stop paths with !isMcpActive.
MCP still closable via click handler on overlay (CLICKABLE flag).
Test: flash es3c28p 2be0c0 31% free to /dev/cu.usbmodem101
192.168.68.113 dashboard 200, dev 6666 ok, /api/mcp 25 tools.
Requires PYTHONPATH cleaned for idf.py build (Hermes venv hijacks
pydantic_core).
- McpSettings was hardcoded to /data/service/mcp/settings.properties,
but ES3C28P uses storage.userDataLocation=SD so user data lives on
/sdcard/tactility/. Settings appeared to save but on reload returned
default false -> "enable and when I go back shows disabled".
Fixed to use getUserDataPath()+"/settings/mcp.properties" pattern
consistent with DisplaySettings/WebServerSettings, with
findOrCreateParentDirectory() and isFile() guard.
- HttpServer ctrl_port collision: ESP-IDF default 32768 used by both
WebServer (80) and DevelopmentService (6666). Second httpd_start()
failed silently -> dashboard up but /api/mcp 404 and :6666 refused.
Fixed with unique ctrl_port = 32768 + (port % 1000).
Added CONFIG_HTTPD_MAX_URI_HANDLERS=20 (default 8 < 9 needed for
7 handlers + 2 internal).
- DevService stack 5120 -> 8192 for /app/install handling.
- McpSystem video stream task stack 4096 -> 8192 and idle yield 50ms
(was 5ms always) to avoid CPU starvation blocking httpd tasks.
On RLCD, timer must always run: DisplayIdle early return on
!supportsBacklightDuty() broke MCP manual activation (cachedSettings
not loaded, backlight duty 0). Fixed to always load settings +
start timer, log RLCD detection, guard setBacklightDuty with
supportsBacklightDuty() and fallback duty 255.
- DisplaySettings: add disableScreensaverWhenCharging bool, persisted,
with UI toggle in Display app (Settings->Display) using
PowerDevice::IsCharging check via findDevices callback.
When charging and flag enabled, screensaver activation skipped,
and if already dimmed, wake on charging.
- ES3C28P Power driver: GPIO9 ADC1_CH8 2x divider 2500-4200mV spec from
~/Downloads official docs, TP4054 CHRG not connected to GPIO, so
IsCharging inferred via voltage thresholds (<500mV no battery USB
or >5000mV wall powered, >=4150mV high) + rising trend.
Verified: flashed es3c28p to /dev/cu.usbmodem101 (192.168.68.113),
WiFi FamReynaMesh RSSI -59, dashboard 200, :6666/info now works,
/api/mcp returns disabled correctly until enabled, persists to SD.
- Fixed crash when returning to Setup app (from any of the steps)
- Fixed crash when returning to TimeDateSettings app (after locale selection)
- Fixed GuiService inconsistent behaviour: now always perform operations async (e.g. to show/hide apps). This fixes crashes in some onHide() calls where onHide() might be called before onShow() was called.
- Fix for incorrect WebServService path
- Remove CYD-4848S040C SD card functionality, but added a GPIO fix for releasing 3-wire SPI pin sharing.
- Fix for saving/loading settings for various apps
- Implement Setup app for device's first boot
- Implement device simple name and vendor name variables
- Remove region setting (locale setting is already available)
- Disable BlueTooth driver by default, to ensure it doesn't allocate memory
- Update BlueTooth settings app behaviour to make sure it starts/stops the devices
- Disable SPI RAM usage for ST7789 as it broke App Hub
- Reduce T-Display and T-Deck display buffers from 1/3rd to 1/10th of resolution
- Enabled dynamic buffers for MbedTLS to optimize memory
- TLS 1.3 did not work with dynamic buffers: downgrade to 1.2 for now
- WiFi is now enabled from the Boot app callback to the WiFi service, instead of the WiFi service start() function. This avoids a lockup when WiFi is started by the service while the Boot app is updating the WiFi settings.
- New drivers:
- SD SPI
- spi_peripheral
- touch_placeholder
- display_placeholder
- Devicetree compiler:
- Implement phandle-arrays
- Implement device addresses
- Add placeholder drivers to all devices with a SPI display
- SPI driver: add `cs-pins` and set them to high on driver start
- FileSystem: add `file_system_set_owner()` and `file_system_get_owner()`
- File locking is now checking if the related `FileSystem` is part of a shared SPI bus
- Add `device_get_child_count()`
- SDMMC driver: Remove default of `slot` value
- Fix for Crowpanel Basic 3.5" display (add delay to booting)
- Fix for LilyGO T-HMI SD card mounting (delayed mounting by disabling it initially in the dts)
- Add ScreensaverType::McpScreen to DisplaySettings enum, toString/fromString
- Add 'MCP Screen' option to the Display settings screensaver dropdown
- New McpScreensaver (Screensaver subclass): creates full-screen lv_canvas on
the overlay, allocates framebuffer in SPIRAM, registers canvas pointer in
McpSystemState, shows 'Waiting for LLM...' until first draw command arrives
- Wire McpScreensaver into DisplayIdle::activateScreensaver() switch
- McpSystem::ensureOverrideScreen() now calls displayidle::findService()->
startScreensaver() instead of launching McpOverrideApp — canvas appears
automatically on any LLM draw command
- Remove McpOverrideApp (replaced by screensaver), deregister from Tactility.cpp
- Remove mcpOverrideEnabled from McpSettings — no longer needed
- Simplify McpSettingsApp: remove Screen Override toggle, update info text to
direct users to Settings -> Display -> Screensaver -> MCP Screen
- Add McpSettings (load/save mcpEnabled, mcpOverrideEnabled to /data/service/mcp/settings.properties)
- Add McpSystem: global state, canvas drawing (RGB565, BMP, PBM, text), I2S audio (WAV, MP3 via minimp3, tone, record)
- Add McpHandler: unauthenticated POST /api/mcp (JSON-RPC 2.0, 13 tools) and POST /api/screen/raw endpoints
- Route MCP endpoints before Basic Auth check in WebServerService::handleApiPost
- Start HTTP server at boot if either webServerEnabled OR mcpEnabled is set
- Fix setEnabled: start unconditionally when called with true; only stop if both WS and MCP are disabled
- Add McpSettingsApp (Settings category): toggle MCP service + screen override, show live endpoint URL
- Add McpOverrideApp (appId one.tactility.mcpscreen): full-screen LVGL canvas for LLM-driven display override
- Register both new apps in Tactility.cpp
* Bluetooth LE addition
* fixes
* use the psram!
helps a little on S3 (t-deck)
* custom device name
* Update symbols.c
* Feedback + fixes
Fixes external app start/stop server (child devices)
Fixes BtManage causing a full system hang upon disabling bt when a device is connected to the host.
* updoot
* more updoot
* move back!
* Revert "move back!"
This reverts commit d3694365c634acc5db62ac59771c496cb971a727.
* fix some of the things
* Addressing feedback? hmm
* Fixes
Bug 1 — Reconnect loop / Reconnect not working fixed
Bug 2 — Name-only advertising overwrites HID advertising
Bug 3 — BleHidDeviceCtx leak on re-enable
Enhancement — HID device auto-start on radio re-enable
* stuff...
* update for consistency with others
* fix crashes
and some bonus symbols
* a few symbols, i2c speed, cdn message
100kHz i2c speed seems to be more compatible with m5stack modules...and probably in general.
cdn message no longer applies
* Hide BT Settings when bt not enabled
* Addressing things and device fixes
* Missed one!
* stuff
* Optional internal pull-ups for SD/MMC pins in DTS
* Selectable on‑chip LDO channel for SD/MMC power (can be disabled)
* Added several sensor/driver modules to generic ESP32 device configurations so that they become part of the SDKs
* SD card mount now prints card information for clearer diagnostics
* Fix for bug DTS boolean parsing. Improved tests to catch these issues.
* Expanded SDK integration test to include new modules and headers
* Modularized packaging to generate per‑module build files and include driver assets
- UiDensity moved to lvgl-module
- Deleted tt_hal and tt_hal_gpio (breaks apps, but will fix those right after merging)
- Added I2C 8 bit register operations
- Added device.properties to simulator
- Improved Tab5 hardware init, implement audio
- Add README.md to kernel
**New Features**
* Runtime font accessors and new symbol fonts for text, launcher, statusbar, and shared icons.
* Added font height base setting to device.properties
* Text fonts now have 3 sizes: small, default, large
**Improvements**
* Renamed `UiScale` to `UiDensity`
* Statusbar, toolbar and many UI components now compute heights and spacing from fonts/density.
* SSD1306 initialization sequence refined for more stable startup.
* Multiple image assets replaced by symbol-font rendering.
* Many layout improvements related to density, font scaling and icon scaling
* Updated folder name capitalization for newer style
* **New Features**
* Added Material Design symbol fonts and LVGL font aliases for launcher, status bar, and shared UI icons.
* **Style**
* Migrated app icons across the UI to the new symbol font system.
* Updated launcher button sizing, font styling, recoloring and icon text color for consistency.
* Default text/icon font macros set for consistent sizing across the UI.
* **Documentation**
* Updated third‑party notices to include Material Design Icons links.
Auto starts the web server in AP mode with generated SSID and Password.
For small devices.... or any i guess.
Hidden by default.
May need adjustments to suit even smaller screens than the waveshare GEEK.
And a few symbols for good measure. :)
* **Refactor**
* GPIO subsystem moved to a descriptor-based model for per-pin ownership and runtime pin management; many platform drivers now acquire/release descriptors.
* Device trees and drivers now use GPIO phandle-style pin specifications across all boards and all drivers.
* **Behavior**
* Device list now encodes per-device status (ok/disabled); boot will skip disabled devices accordingly.
* **Deprecation**
* Legacy GPIO HAL marked deprecated and replaced with descriptor-based interfaces.
* **Chores**
* Bindings and platform configs updated to the new GPIO pin-spec format.