Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8e7f997
Rename system_event api functions and add subscribe mechanism
KenVanHoeylandt Aug 4, 2026
f61a307
Add app loading and window manager modules
KenVanHoeylandt Aug 6, 2026
c628668
Update
KenVanHoeylandt Aug 8, 2026
1ae6e77
Fixes and improvements
KenVanHoeylandt Aug 8, 2026
ba59437
Fixes
KenVanHoeylandt Aug 8, 2026
a2056e8
Fixes
KenVanHoeylandt Aug 8, 2026
e5d05a3
Fixes
KenVanHoeylandt Aug 8, 2026
ca7cb9f
Updated apps
KenVanHoeylandt Aug 8, 2026
fc98bb6
Merge branch 'main' into develop
KenVanHoeylandt Aug 8, 2026
994aa31
Fix PC builds
KenVanHoeylandt Aug 8, 2026
87f4985
Fixes and updates
KenVanHoeylandt Aug 8, 2026
e1fb827
Fixes
KenVanHoeylandt Aug 8, 2026
a96fd77
Fix for macOS build
KenVanHoeylandt Aug 8, 2026
26a8aa2
Fixes and cleanup
KenVanHoeylandt Aug 8, 2026
68aae65
Fix for SDK test
KenVanHoeylandt Aug 8, 2026
22192dd
Fix for macOS build
KenVanHoeylandt Aug 8, 2026
3c783c1
Fixes
KenVanHoeylandt Aug 8, 2026
e02766c
Fix for syntax
KenVanHoeylandt Aug 8, 2026
52f90ae
Fix
KenVanHoeylandt Aug 8, 2026
6b68e9f
Update integration app
KenVanHoeylandt Aug 8, 2026
9c54ac4
Fix for keyboard
KenVanHoeylandt Aug 8, 2026
24860be
Cleanup
KenVanHoeylandt Aug 8, 2026
e618086
Cleanup
KenVanHoeylandt Aug 8, 2026
884a008
Fix Setup
KenVanHoeylandt Aug 8, 2026
c5a8c99
Fix for file overwrite
KenVanHoeylandt Aug 8, 2026
07a571f
Fix for installing and running apps
KenVanHoeylandt Aug 9, 2026
52c1ec7
Add missing symbols
KenVanHoeylandt Aug 9, 2026
0e8d642
Fixes and improvements
KenVanHoeylandt Aug 9, 2026
7aac44b
Fix for touch
KenVanHoeylandt Aug 9, 2026
8a75bc5
Fixes for keyboard
KenVanHoeylandt Aug 9, 2026
9487441
Fix for duplicate wifi events on P4
KenVanHoeylandt Aug 9, 2026
a9340ae
Fix for resuming windows when lvgl was stopped and started again
KenVanHoeylandt Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Buildscripts/TactilitySDK/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ idf_component_register(
INCLUDE_DIRS
"Libraries/TactilityC/include"
"Libraries/TactilityKernel/include"
"Libraries/TactilityFreeRtos/include"
"Libraries/TactilityFreeRtos/Include"
"Libraries/lvgl/include"
"Libraries/minmea/include"
"Libraries/minitar/include"
"Modules/lvgl-module/include"
# DRIVER_INCLUDE_DIRS_PLACEHOLDER
REQUIRES esp_timer
REQUIRES esp_timer app-module crypt-module gps-module lvgl-module lvgl-window-manager-module service-module
)

# Regular and core features
add_prebuilt_library(TactilityC Libraries/TactilityC/binary/libTactilityC.a)
add_prebuilt_library(TactilityKernel Libraries/TactilityKernel/binary/libTactilityKernel.a)
add_prebuilt_library(lvgl Libraries/lvgl/binary/liblvgl.a)
add_prebuilt_library(minmea Libraries/minmea/binary/libminmea.a)
add_prebuilt_library(minitar Libraries/minitar/binary/libminitar.a)

target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityKernel)
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
target_link_libraries(${COMPONENT_LIB} INTERFACE minmea)
target_link_libraries(${COMPONENT_LIB} INTERFACE minitar)
12 changes: 8 additions & 4 deletions Buildscripts/TactilitySDK/TactilitySDK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ macro(tactility_project project_name)
endif()

set(EXTRA_COMPONENT_DIRS
"Libraries/TactilityFreeRtos"
"Modules"
"Drivers"
"${TACTILITY_SDK_PATH}/Libraries/TactilityFreeRtos"
"${TACTILITY_SDK_PATH}/Modules"
)

set(COMPONENTS
TactilityFreeRtos
# DRIVER_COMPONENTS_PLACEHOLDER
app-module
crypt-module
gps-module
lvgl-module
lvgl-window-manager-module
service-module
)

endmacro()
63 changes: 16 additions & 47 deletions Buildscripts/release-sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,43 +111,13 @@ def add_module(target_path, module_name):
cmakelists_content = create_module_cmakelists(module_name)
write_module_cmakelists(os.path.join(target_path, f"Modules/{module_name}/CMakeLists.txt"), cmakelists_content)

def discover_all_drivers():
"""
Discover all *-module directories under Drivers/ (not Modules/ - those are handled
separately via add_module). Sorted for deterministic output across OS/filesystem order.
"""
pattern = os.path.join('Drivers', '*-module')
return sorted(
os.path.basename(p) for p in glob.glob(pattern) if os.path.isdir(p)
)

def generate_tactility_sdk_cmake(target_path, available_drivers):
def generate_tactility_sdk_cmake(target_path):
src = os.path.join('Buildscripts', 'TactilitySDK', 'TactilitySDK.cmake')
with open(src) as f:
content = f.read()
placeholder = " # DRIVER_COMPONENTS_PLACEHOLDER"
assert placeholder in content, \
f"Placeholder '{placeholder.strip()}' not found in {src} - template drifted, generator needs updating"
components = "\n".join(f" {d}" for d in available_drivers)
new_content = content.replace(placeholder, components)
assert placeholder not in new_content, \
f"Placeholder '{placeholder.strip()}' still present after replacement in {src}"
with open(os.path.join(target_path, 'TactilitySDK.cmake'), 'w') as f:
f.write(new_content)

def generate_tactility_sdk_top_cmakelists(target_path, available_drivers):
shutil.copy2(src, os.path.join(target_path, 'TactilitySDK.cmake'))

def generate_tactility_sdk_top_cmakelists(target_path):
src = os.path.join('Buildscripts', 'TactilitySDK', 'CMakeLists.txt')
with open(src) as f:
content = f.read()
placeholder = " # DRIVER_INCLUDE_DIRS_PLACEHOLDER"
assert placeholder in content, \
f"Placeholder '{placeholder.strip()}' not found in {src} - template drifted, generator needs updating"
include_dirs = "\n".join(f' "Drivers/{d}/include"' for d in available_drivers)
new_content = content.replace(placeholder, include_dirs)
assert placeholder not in new_content, \
f"Placeholder '{placeholder.strip()}' still present after replacement in {src}"
with open(os.path.join(target_path, 'CMakeLists.txt'), 'w') as f:
f.write(new_content)
shutil.copy2(src, os.path.join(target_path, 'CMakeLists.txt'))

def main():
if len(sys.argv) < 2:
Expand All @@ -167,7 +137,7 @@ def main():
{'src': 'TactilityC/CMakeLists.txt', 'dst': 'Libraries/TactilityC/'},
{'src': 'TactilityC/LICENSE*.*', 'dst': 'Libraries/TactilityC/'},
# TactilityFreeRtos
{'src': 'TactilityFreeRtos/Include/**', 'dst': 'Libraries/TactilityFreeRtos/include/'},
{'src': 'TactilityFreeRtos/Include/**', 'dst': 'Libraries/TactilityFreeRtos/Include/'},
{'src': 'TactilityFreeRtos/CMakeLists.txt', 'dst': 'Libraries/TactilityFreeRtos/'},
{'src': 'TactilityFreeRtos/LICENSE*.*', 'dst': 'Libraries/TactilityFreeRtos/'},
# TactilityKernel
Expand All @@ -185,6 +155,10 @@ def main():
# elf_loader
{'src': 'Libraries/elf_loader/elf_loader.cmake', 'dst': 'Libraries/elf_loader/'},
{'src': 'Libraries/elf_loader/license.txt', 'dst': 'Libraries/elf_loader/'},
# minitar
{'src': 'build/esp-idf/minitar/libminitar.a', 'dst': 'Libraries/minitar/binary/'},
{'src': 'Libraries/minitar/minitar/minitar.h', 'dst': 'Libraries/minitar/include/'},
{'src': 'Libraries/minitar/minitar/LICENSE*', 'dst': 'Libraries/minitar/'},
# minmea
{'src': 'build/esp-idf/minmea/libminmea.a', 'dst': 'Libraries/minmea/binary/'},
{'src': 'Libraries/minmea/Include/**', 'dst': 'Libraries/minmea/include/'},
Expand All @@ -197,21 +171,16 @@ def main():
map_copy(mappings, target_path)

# Modules
add_module(target_path, "lvgl-module")
add_module(target_path, "app-module")
add_module(target_path, "crypt-module")
add_module(target_path, "gps-module")
add_module(target_path, "lvgl-module")
add_module(target_path, "lvgl-window-manager-module")
add_module(target_path, "service-module")

# Drivers - only ones actually built for this target (chip-restricted drivers like
# sc2356-module won't have a .a outside ESP32-P4)
available_drivers = [d for d in discover_all_drivers() if driver_is_available(d)]
for driver_name in available_drivers:
add_driver(target_path, driver_name)

# Final scripts - generated (not copied verbatim) so COMPONENTS/INCLUDE_DIRS only list
# drivers actually available for this target
generate_tactility_sdk_cmake(target_path, available_drivers)
generate_tactility_sdk_top_cmakelists(target_path, available_drivers)
# Final scripts - copied verbatim
generate_tactility_sdk_cmake(target_path)
generate_tactility_sdk_top_cmakelists(target_path)

# Output ESP-IDF SDK version to file
esp_idf_version = os.environ.get("ESP_IDF_VERSION", "")
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION})
add_subdirectory(Modules/crypt-module)
add_subdirectory(Modules/gps-module)
add_subdirectory(Modules/service-module)
add_subdirectory(Modules/app-module)
add_subdirectory(Modules/lvgl-window-manager-module)
add_subdirectory(Drivers/gps-generic-module)
add_subdirectory(Drivers/gps-meshtastic-module)

Expand Down
7 changes: 0 additions & 7 deletions Devices/generic-esp32/devicetree.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32.dts
7 changes: 0 additions & 7 deletions Devices/generic-esp32c6/devicetree.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32c6.dts
8 changes: 0 additions & 8 deletions Devices/generic-esp32p4/devicetree.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
- Drivers/sc2356-module
dts: generic,esp32p4.dts
7 changes: 0 additions & 7 deletions Devices/generic-esp32s3/devicetree.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32s3.dts
5 changes: 5 additions & 0 deletions Devices/lilygo-tdeck-plus/device.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ cdn.infoMessage=To put the device into bootloader mode: <br/>1. Press the trackb
lvgl.colorDepth=16

sdkconfig.CONFIG_CODEC_DUMMY_SUPPORT=y

# Fix error "PSRAM space not enough for the Flash instructions" on boot:
sdkconfig.CONFIG_SPIRAM_FETCH_INSTRUCTIONS=n
sdkconfig.CONFIG_SPIRAM_RODATA=n
sdkconfig.CONFIG_SPIRAM_XIP_FROM_PSRAM=n
4 changes: 2 additions & 2 deletions Devices/lilygo-tlora-pager/source/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ static void on_boot_completed(struct SystemEvent* /*event*/, void* /*context*/)
}

static error_t start() {
system_event_subscribe(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed, nullptr);
system_event_callback_add(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed, nullptr);
return ERROR_NONE;
}

static error_t stop() {
system_event_unsubscribe(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed);
system_event_callback_remove(KERNEL_EVENT_BOOT_COMPLETED, on_boot_completed);
return ERROR_NONE;
}

Expand Down
5 changes: 5 additions & 0 deletions Devices/m5stack-tab5/Source/devices/devices_v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ static void create_gt911_touch(Device* i2c0) {
// Reset is pulsed via io_expander0 (detect.cpp's pulse_display_reset_pins), not a direct SoC GPIO.
.pin_reset = GPIO_PIN_SPEC_NONE,
.pin_interrupt = GPIO_PIN_SPEC_NONE,
.reset_pulses = 0, // no-op: pin_reset is NONE, so reset_controller_pin() skips anyway
.x_offset = 0,
.y_offset = 0,
.x_scale = 1000,
.y_scale = 1000,
};
gt911_device.config = &gt911_config;

Expand Down
1 change: 1 addition & 0 deletions Devices/m5stack-tab5/Source/devices/tab5_keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ static error_t tab5_keyboard_read_key(Device* device, KeyboardKeyData* data) {

static const KeyboardApi tab5_keyboard_api = {
.read_key = tab5_keyboard_read_key,
.is_present = tab5_keyboard_is_attached,
};

// Defined in module.cpp - this driver is registered directly by m5stack-tab5's own module,
Expand Down
19 changes: 19 additions & 0 deletions Documentation/ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@

## Higher Priority

- Devices with a keyboard attached should always highlight the first widget (~Cardputer navigation issue), same for LV_INDEV_TYPE_ENCODER being present
- Make it more clear to end-users that an SD card is required to run Tactility
- Move "# Fix error "PSRAM space not enough for the Flash instructions" on boot:" fix from T-Deck and others to device.py
- Make it possible to override stack size for an app via config file (loaded at boot), and make it possible to set preferred memory location (e.g. internal/external)
- Put task stacks in PSRAM when possible.
- Wrap file operations like fopen/fclose with file_mutex
- Add bold fonts for e-ink readability improvement
- Split up Claude instructions: https://code.claude.com/docs/en/memory#import-additional-files
and add https://github.com/multica-ai/andrej-karpathy-skills/blob/main/CLAUDE.md
- Move test projects to their relevant subproject
- tt_alertdialog start() etc is broken as it can't fetch the app instance id. Fetch automatically via thread context?
- Migrate Tactility/Paths.cpp functions to TactilityKernel
- app_manager_find_manifest() should make a copy, not return a pointer.
- Httpd.cpp: warn if running on same CPU core (or task) as UI/LVGL/window manager.
- Improve Setup: Show "Step done" screen
- Improve Setup: Add keyboard/keypad navigation explanation
- display.h API: get_backlight does not change ref counting, but it should
- bluetooth: various getters for child devices do not change ref counting, but they should
- Improve kernel_init.cpp (and other modules): create driver_ensure_added() and driver_ensure_destructed()
Expand All @@ -38,6 +54,9 @@

## Medium Priority

- Consider moving certain drivers into separate modules: audio, bt, wifi, etc
- Consider using https://github.com/Graphify-Labs/graphify
- Consider implementing LVGL gridnav in apps https://lvgl.io/docs/open/9.3/details/auxiliary-modules/gridnav.html
- Implement a LED kernel driver (single colour and RGB, plain GPIO and PWM)
- Make USB host driver disabled by default, so it doesn't consume memory
- Filtering for apps in App Hub:
Expand Down
2 changes: 2 additions & 0 deletions Firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ else ()
Tactility
TactilityFreeRtos
lvgl-module
lvgl-window-manager-module
app-module
crypt-module
gps-module
gps-generic-module
Expand Down
5 changes: 5 additions & 0 deletions Libraries/QRCode/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ else()
target_include_directories(QRCode
PUBLIC src
)

# qrcode.h polyfills bool/true/false for pre-C23 compilers - on a host compiler that
# defaults to C23 (where bool is a keyword), that polyfill itself fails to compile. Pin to
# C11 for the simulator build only; ESP-IDF's own toolchain default is unaffected.
set_target_properties(QRCode PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
endif()
11 changes: 11 additions & 0 deletions Modules/app-esp32-module/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.20)

include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")

file(GLOB_RECURSE SOURCE_FILES "source/*.c*")

tactility_add_module(app-esp32-module
SRCS ${SOURCE_FILES}
INCLUDE_DIRS include/
REQUIRES TactilityKernel app-module service-module elf_loader
)
Loading
Loading