Merge develop into main (#494)

* Updated runtime gating to enable LilyGO T-Deck specific apps and services
  * New device compatibility and model-detection APIs
  * Added a buffer-overflow error code and message
  * Updated GitHub Actions checkout to v4
  * Adjusted an LVGL-related library version
  * Device config now emits a T-Deck workaround flag when applicable
  * Removed internal developer comments and minor cleanups
This commit is contained in:
Ken Van Hoeylandt 2026-02-09 22:12:03 +01:00 committed by GitHub
parent 93efadd5e3
commit 25c3f19e5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 67 additions and 26 deletions

View File

@ -15,7 +15,7 @@ runs:
using: "composite" using: "composite"
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Install Linux Dependencies for SDL - name: Install Linux Dependencies for SDL

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: "Configure Project" - name: "Configure Project"
@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: "Install Python Dependencies" - name: "Install Python Dependencies"

View File

@ -5,7 +5,6 @@
#include <St7789Display.h> #include <St7789Display.h>
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() { static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
// Note for future changes: Reset pin is 48 and interrupt pin is 47
auto configuration = std::make_unique<Ft5x06Touch::Configuration>( auto configuration = std::make_unique<Ft5x06Touch::Configuration>(
I2C_NUM_0, I2C_NUM_0,
LCD_HORIZONTAL_RESOLUTION, LCD_HORIZONTAL_RESOLUTION,

View File

@ -5,7 +5,6 @@
#include <Ili9488Display.h> #include <Ili9488Display.h>
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() { static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
// Note for future changes: Reset pin is 48 and interrupt pin is 47
auto configuration = std::make_unique<Gt911Touch::Configuration>( auto configuration = std::make_unique<Gt911Touch::Configuration>(
I2C_NUM_0, I2C_NUM_0,
320, 320,

View File

@ -5,14 +5,15 @@
#include <St7789Display.h> #include <St7789Display.h>
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() { static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
// Note for future changes: Reset pin is 48 and interrupt pin is 47
auto configuration = std::make_unique<Gt911Touch::Configuration>( auto configuration = std::make_unique<Gt911Touch::Configuration>(
I2C_NUM_0, I2C_NUM_0,
240, 240,
320, 320,
true, true,
true, true,
false false,
GPIO_NUM_NC,
GPIO_NUM_16
); );
return std::make_shared<Gt911Touch>(std::move(configuration)); return std::make_shared<Gt911Touch>(std::move(configuration));

View File

@ -17,7 +17,6 @@ static void setBacklightDuty(uint8_t backlightDuty) {
} }
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() { static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
// Note for future changes: Reset pin is 48 and interrupt pin is 47
auto configuration = std::make_unique<Ft5x06Touch::Configuration>( auto configuration = std::make_unique<Ft5x06Touch::Configuration>(
I2C_NUM_0, I2C_NUM_0,
LCD_HORIZONTAL_RESOLUTION, LCD_HORIZONTAL_RESOLUTION,

View File

@ -12,7 +12,6 @@ constexpr auto LCD_VERTICAL_RESOLUTION = 320;
void setBacklightDuty(uint8_t level); void setBacklightDuty(uint8_t level);
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() { static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
// Note for future changes: Reset pin is 48 and interrupt pin is 47
auto configuration = std::make_unique<Axs5106Touch::Configuration>( auto configuration = std::make_unique<Axs5106Touch::Configuration>(
I2C_NUM_0, I2C_NUM_0,
172, 172,

View File

@ -6,6 +6,12 @@ menu "Tactility App"
config TT_DEVICE_ID config TT_DEVICE_ID
string "Device Identifier" string "Device Identifier"
default "" default ""
# T-Deck device-related code was directly referenced from Tactility in a pull request.
# This breaks other devices because the code does not exist in those implementations.
# Until we move it out into a proper driver, we have to have pre-processor definition for that.
config TT_TDECK_WORKAROUND
bool "Temporary work-around until we fix the T-Deck keyboard and trackball settings"
default n
config TT_SPLASH_DURATION config TT_SPLASH_DURATION
int "Splash Duration (ms)" int "Splash Duration (ms)"
default 1000 default 1000

View File

@ -54,7 +54,7 @@ dependencies:
version: "1.7.6~1" version: "1.7.6~1"
rules: rules:
- if: "target == esp32s3" - if: "target == esp32s3"
espressif/esp_lvgl_port: "2.7.0" espressif/esp_lvgl_port: "2.5.0"
lvgl/lvgl: "9.3.0" lvgl/lvgl: "9.3.0"
FastEPD: FastEPD:
git: https://github.com/bitbank2/FastEPD.git git: https://github.com/bitbank2/FastEPD.git

View File

@ -32,6 +32,7 @@
#include <tactility/lvgl_module.h> #include <tactility/lvgl_module.h>
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include "tactility/drivers/root.h"
#include <Tactility/InitEsp.h> #include <Tactility/InitEsp.h>
#endif #endif
@ -61,8 +62,6 @@ namespace service {
namespace statusbar { extern const ServiceManifest manifest; } namespace statusbar { extern const ServiceManifest manifest; }
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
namespace displayidle { extern const ServiceManifest manifest; } namespace displayidle { extern const ServiceManifest manifest; }
#endif
#if defined(ESP_PLATFORM) && defined(CONFIG_TT_DEVICE_LILYGO_TDECK)
namespace keyboardidle { extern const ServiceManifest manifest; } namespace keyboardidle { extern const ServiceManifest manifest; }
#endif #endif
#if TT_FEATURE_SCREENSHOT_ENABLED #if TT_FEATURE_SCREENSHOT_ENABLED
@ -112,11 +111,10 @@ namespace app {
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
namespace crashdiagnostics { extern const AppManifest manifest; } namespace crashdiagnostics { extern const AppManifest manifest; }
namespace webserversettings { extern const AppManifest manifest; } namespace webserversettings { extern const AppManifest manifest; }
#if CONFIG_TT_TDECK_WORKAROUND == 1
namespace keyboardsettings { extern const AppManifest manifest; } // T-Deck only for now
namespace trackballsettings { extern const AppManifest manifest; } // T-Deck only for now
#endif #endif
#if defined(ESP_PLATFORM) && defined(CONFIG_TT_DEVICE_LILYGO_TDECK)
namespace keyboardsettings { extern const AppManifest manifest; }
namespace trackballsettings { extern const AppManifest manifest; }
#endif #endif
#if TT_FEATURE_SCREENSHOT_ENABLED #if TT_FEATURE_SCREENSHOT_ENABLED
@ -162,12 +160,11 @@ static void registerInternalApps() {
addAppManifest(app::webserversettings::manifest); addAppManifest(app::webserversettings::manifest);
addAppManifest(app::crashdiagnostics::manifest); addAppManifest(app::crashdiagnostics::manifest);
addAppManifest(app::development::manifest); addAppManifest(app::development::manifest);
#endif #if defined(CONFIG_TT_TDECK_WORKAROUND)
#if defined(ESP_PLATFORM) && defined(CONFIG_TT_DEVICE_LILYGO_TDECK)
addAppManifest(app::keyboardsettings::manifest); addAppManifest(app::keyboardsettings::manifest);
addAppManifest(app::trackballsettings::manifest); addAppManifest(app::trackballsettings::manifest);
#endif #endif
#endif
#if defined(CONFIG_TINYUSB_MSC_ENABLED) && CONFIG_TINYUSB_MSC_ENABLED #if defined(CONFIG_TINYUSB_MSC_ENABLED) && CONFIG_TINYUSB_MSC_ENABLED
addAppManifest(app::usbsettings::manifest); addAppManifest(app::usbsettings::manifest);
@ -251,13 +248,13 @@ static void registerAndStartSecondaryServices() {
addService(service::loader::manifest); addService(service::loader::manifest);
addService(service::gui::manifest); addService(service::gui::manifest);
addService(service::statusbar::manifest); addService(service::statusbar::manifest);
#ifdef ESP_PLATFORM addService(service::memorychecker::manifest);
#if defined(ESP_PLATFORM)
addService(service::displayidle::manifest); addService(service::displayidle::manifest);
#endif #if defined(CONFIG_TT_TDECK_WORKAROUND)
#if defined(ESP_PLATFORM) && defined(CONFIG_TT_DEVICE_LILYGO_TDECK)
addService(service::keyboardidle::manifest); addService(service::keyboardidle::manifest);
#endif #endif
addService(service::memorychecker::manifest); #endif
#if TT_FEATURE_SCREENSHOT_ENABLED #if TT_FEATURE_SCREENSHOT_ENABLED
addService(service::screenshot::manifest); addService(service::screenshot::manifest);
#endif #endif

View File

@ -178,6 +178,14 @@ struct Device* device_get_parent(struct Device* device);
*/ */
bool device_is_ready(const struct Device* device); bool device_is_ready(const struct Device* device);
/**
* Indicates whether the device is compatible with the given compatible string.
* @param[in] device non-null device pointer
* @param[in] compatible compatible string
* @return true if the device is compatible
*/
bool device_is_compatible(const struct Device* device, const char* compatible);
/** /**
* Set the driver data for a device. * Set the driver data for a device.
* *

View File

@ -2,6 +2,8 @@
#pragma once #pragma once
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -10,6 +12,14 @@ struct RootConfig {
const char* model; const char* model;
}; };
/**
* Indicates whether the device's model matches the specified model.
* @param[in] device the device to check (non-null)
* @param[in] model the model to check against
* @return true if the device's model matches the specified model
*/
bool root_is_model(const struct Device* device, const char* model);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,6 +23,7 @@ typedef int error_t;
#define ERROR_OUT_OF_MEMORY 9 #define ERROR_OUT_OF_MEMORY 9
#define ERROR_NOT_SUPPORTED 10 #define ERROR_NOT_SUPPORTED 10
#define ERROR_NOT_ALLOWED 11 #define ERROR_NOT_ALLOWED 11
#define ERROR_BUFFER_OVERFLOW 12
/** Convert an error_t to a human-readable text. Useful for logging. */ /** Convert an error_t to a human-readable text. Useful for logging. */
const char* error_to_string(error_t error); const char* error_to_string(error_t error);

View File

@ -277,6 +277,11 @@ bool device_is_ready(const struct Device* device) {
return device->internal->state.started; return device->internal->state.started;
} }
bool device_is_compatible(const struct Device* device, const char* compatible) {
if (device->internal->driver == nullptr) return false;
return driver_is_compatible(device->internal->driver, compatible);
}
void device_set_driver_data(struct Device* device, void* driver_data) { void device_set_driver_data(struct Device* device, void* driver_data) {
device->internal->driver_data = driver_data; device->internal->driver_data = driver_data;
} }

View File

@ -1,10 +1,17 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#include <tactility/device.h>
#include <tactility/driver.h> #include <tactility/driver.h>
#include <tactility/drivers/root.h> #include <tactility/drivers/root.h>
#include <cstring>
extern "C" { extern "C" {
bool root_is_model(const struct Device* device, const char* buffer) {
auto* config = static_cast<const RootConfig*>(device->config);
return strcmp(config->model, buffer) == 0;
}
Driver root_driver = { Driver root_driver = {
.name = "root", .name = "root",
.compatible = (const char*[]) { "root", nullptr }, .compatible = (const char*[]) { "root", nullptr },
@ -12,7 +19,8 @@ Driver root_driver = {
.stop_device = nullptr, .stop_device = nullptr,
.api = nullptr, .api = nullptr,
.device_type = nullptr, .device_type = nullptr,
.owner = nullptr .owner = nullptr,
.internal = nullptr
}; };
} }

View File

@ -29,6 +29,8 @@ const char* error_to_string(error_t error) {
return "not supported"; return "not supported";
case ERROR_NOT_ALLOWED: case ERROR_NOT_ALLOWED:
return "not allowed"; return "not allowed";
case ERROR_BUFFER_OVERFLOW:
return "buffer overflow";
default: default:
return "unknown"; return "unknown";
} }

View File

@ -3,6 +3,7 @@
#include <tactility/drivers/gpio_controller.h> #include <tactility/drivers/gpio_controller.h>
#include <tactility/drivers/i2c_controller.h> #include <tactility/drivers/i2c_controller.h>
#include <tactility/drivers/i2s_controller.h> #include <tactility/drivers/i2s_controller.h>
#include <tactility/drivers/root.h>
#include <tactility/drivers/spi_controller.h> #include <tactility/drivers/spi_controller.h>
#include <tactility/drivers/uart_controller.h> #include <tactility/drivers/uart_controller.h>
#include <tactility/concurrent/dispatcher.h> #include <tactility/concurrent/dispatcher.h>
@ -36,6 +37,7 @@ const struct ModuleSymbol KERNEL_SYMBOLS[] = {
DEFINE_MODULE_SYMBOL(device_get_driver_data), DEFINE_MODULE_SYMBOL(device_get_driver_data),
DEFINE_MODULE_SYMBOL(device_is_added), DEFINE_MODULE_SYMBOL(device_is_added),
DEFINE_MODULE_SYMBOL(device_is_ready), DEFINE_MODULE_SYMBOL(device_is_ready),
DEFINE_MODULE_SYMBOL(device_is_compatible),
DEFINE_MODULE_SYMBOL(device_lock), DEFINE_MODULE_SYMBOL(device_lock),
DEFINE_MODULE_SYMBOL(device_try_lock), DEFINE_MODULE_SYMBOL(device_try_lock),
DEFINE_MODULE_SYMBOL(device_unlock), DEFINE_MODULE_SYMBOL(device_unlock),
@ -79,6 +81,8 @@ const struct ModuleSymbol KERNEL_SYMBOLS[] = {
DEFINE_MODULE_SYMBOL(i2s_controller_get_config), DEFINE_MODULE_SYMBOL(i2s_controller_get_config),
DEFINE_MODULE_SYMBOL(i2s_controller_reset), DEFINE_MODULE_SYMBOL(i2s_controller_reset),
DEFINE_MODULE_SYMBOL(I2S_CONTROLLER_TYPE), DEFINE_MODULE_SYMBOL(I2S_CONTROLLER_TYPE),
// drivers/root
DEFINE_MODULE_SYMBOL(root_is_model),
// drivers/spi_controller // drivers/spi_controller
DEFINE_MODULE_SYMBOL(spi_controller_lock), DEFINE_MODULE_SYMBOL(spi_controller_lock),
DEFINE_MODULE_SYMBOL(spi_controller_try_lock), DEFINE_MODULE_SYMBOL(spi_controller_try_lock),

View File

@ -105,6 +105,9 @@ def write_tactility_variables(output_file, device_properties: ConfigParser, devi
else: else:
output_file.write(f"CONFIG_TT_DEVICE_NAME=\"{board_vendor} {board_name}\"\n") output_file.write(f"CONFIG_TT_DEVICE_NAME=\"{board_vendor} {board_name}\"\n")
output_file.write(f"CONFIG_TT_DEVICE_ID=\"{device_id}\"\n") output_file.write(f"CONFIG_TT_DEVICE_ID=\"{device_id}\"\n")
if device_id == "lilygo-tdeck":
output_file.write("CONFIG_TT_TDECK_WORKAROUND=y\n")
def write_core_variables(output_file, device_properties: ConfigParser): def write_core_variables(output_file, device_properties: ConfigParser):
idf_target = get_property_or_exit(device_properties, "hardware", "target").lower() idf_target = get_property_or_exit(device_properties, "hardware", "target").lower()