From 4579ef8648eda7f0e137eaf7848a6ac0933f6664 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Fri, 29 Aug 2025 21:53:52 +0200 Subject: [PATCH] Various fixes and improvements --- App/idf_component.yml | 2 +- Boards/LilygoTLoraPager/CMakeLists.txt | 2 +- Boards/LilygoTLoraPager/Source/Init.cpp | 18 ++-- .../Source/hal/TpagerPower.cpp | 22 ++-- .../LilygoTLoraPager/Source/hal/TpagerPower.h | 3 +- Data/data/settings.properties | 2 +- Data/system/app/Launcher/i18n/en-GB.i18n | 3 - Data/system/app/Launcher/i18n/en-US.i18n | 3 - Data/system/app/Launcher/i18n/fr-FR.i18n | 3 - Data/system/app/Launcher/i18n/nl-BE.i18n | 3 - Data/system/app/Launcher/i18n/nl-NL.i18n | 3 - Drivers/BQ25896/CMakeLists.txt | 5 + Drivers/BQ25896/README.md | 5 + Drivers/BQ25896/Source/Bq25896.cpp | 13 +++ Drivers/BQ25896/Source/Bq25896.h | 20 ++++ Drivers/ST7796/README.md | 1 + Drivers/ST7796/Source/St7796Display.cpp | 17 +-- Drivers/ST7796/Source/St7796Display.h | 1 - .../Include/Tactility/hal/power/PowerDevice.h | 3 + Tactility/Source/Tactility.cpp | 12 +-- Tactility/Source/app/launcher/Launcher.cpp | 99 +++++++++--------- .../Source/app/screenshot/Screenshot.cpp | 2 +- Tactility/Source/hal/i2c/I2cDevice.cpp | 14 +-- Tactility/Source/lvgl/Statusbar.cpp | 12 +-- Translations/Translations.ods | Bin 13804 -> 13652 bytes sdkconfig.board.lilygo-tlora-pager | 2 + 26 files changed, 150 insertions(+), 120 deletions(-) delete mode 100644 Data/system/app/Launcher/i18n/en-GB.i18n delete mode 100644 Data/system/app/Launcher/i18n/en-US.i18n delete mode 100644 Data/system/app/Launcher/i18n/fr-FR.i18n delete mode 100644 Data/system/app/Launcher/i18n/nl-BE.i18n delete mode 100644 Data/system/app/Launcher/i18n/nl-NL.i18n create mode 100644 Drivers/BQ25896/CMakeLists.txt create mode 100644 Drivers/BQ25896/README.md create mode 100644 Drivers/BQ25896/Source/Bq25896.cpp create mode 100644 Drivers/BQ25896/Source/Bq25896.h diff --git a/App/idf_component.yml b/App/idf_component.yml index fdb96675..f6067125 100644 --- a/App/idf_component.yml +++ b/App/idf_component.yml @@ -13,7 +13,7 @@ dependencies: rules: - if: "target in [esp32s3, esp32p4]" espressif/esp_lcd_st7796: - version: "1.3.2" + version: "1.3.4" espressif/esp_lcd_panel_io_additions: "1.0.1" espressif/esp_tinyusb: version: "1.7.6~1" diff --git a/Boards/LilygoTLoraPager/CMakeLists.txt b/Boards/LilygoTLoraPager/CMakeLists.txt index 5746b57d..58b0977e 100644 --- a/Boards/LilygoTLoraPager/CMakeLists.txt +++ b/Boards/LilygoTLoraPager/CMakeLists.txt @@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*) idf_component_register( SRCS ${SOURCE_FILES} INCLUDE_DIRS "Source" - REQUIRES Tactility esp_lcd ST7796 BQ27220 TCA8418 PwmBacklight driver esp_adc + REQUIRES Tactility esp_lcd ST7796 BQ25896 BQ27220 TCA8418 PwmBacklight driver esp_adc ) diff --git a/Boards/LilygoTLoraPager/Source/Init.cpp b/Boards/LilygoTLoraPager/Source/Init.cpp index 72a70096..429d007c 100644 --- a/Boards/LilygoTLoraPager/Source/Init.cpp +++ b/Boards/LilygoTLoraPager/Source/Init.cpp @@ -1,22 +1,23 @@ -#include "PwmBacklight.h" -#include "Tactility/kernel/SystemEvents.h" -#include "Tactility/service/gps/GpsService.h" - #include +#include +#include #include #include +#include +#include #include #include -#define TAG "tpager" +#define TAG "TLoraPager" // Power on -#define TDECK_POWERON_GPIO GPIO_NUM_10 +constexpr auto TDECK_POWERON_GPIO = GPIO_NUM_10; std::shared_ptr bq27220; std::shared_ptr tca8418; +std::shared_ptr bq25896; bool tpagerInit() { ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START); @@ -35,6 +36,10 @@ bool tpagerInit() { tca8418 = std::make_shared(I2C_NUM_0); tt::hal::registerDevice(tca8418); + bq25896 = std::make_shared(I2C_NUM_0); + tt::hal::registerDevice(bq25896); + bq25896->powerOn(); + tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent event) { bq27220->configureCapacity(1500, 1500); @@ -51,5 +56,6 @@ bool tpagerInit() { } } }); + return true; } diff --git a/Boards/LilygoTLoraPager/Source/hal/TpagerPower.cpp b/Boards/LilygoTLoraPager/Source/hal/TpagerPower.cpp index d39e3216..5eaee439 100644 --- a/Boards/LilygoTLoraPager/Source/hal/TpagerPower.cpp +++ b/Boards/LilygoTLoraPager/Source/hal/TpagerPower.cpp @@ -1,5 +1,6 @@ #include "TpagerPower.h" +#include #include #define TAG "power" @@ -46,7 +47,6 @@ bool TpagerPower::getMetric(MetricType type, MetricData& data) { return true; } return false; - break; case Current: if (gauge->getCurrent(s16)) { data.valueAsInt32 = s16; @@ -54,7 +54,6 @@ bool TpagerPower::getMetric(MetricType type, MetricData& data) { } else { return false; } - break; case BatteryVoltage: if (gauge->getVoltage(u16)) { data.valueAsUint32 = u16; @@ -62,7 +61,6 @@ bool TpagerPower::getMetric(MetricType type, MetricData& data) { } else { return false; } - break; case ChargeLevel: if (gauge->getStateOfCharge(u16)) { data.valueAsUint8 = u16; @@ -70,13 +68,25 @@ bool TpagerPower::getMetric(MetricType type, MetricData& data) { } else { return false; } - break; default: return false; - break; + } +} + +void TpagerPower::powerOff() { + auto device = tt::hal::findDevice([](auto device) { + return device->getName() == "BQ25896"; + }); + + if (device == nullptr) { + TT_LOG_E(TAG, "BQ25896 not found"); + return; } - return false; // Safety guard for when new enum values are introduced + auto bq25896 = std::reinterpret_pointer_cast(device); + if (bq25896 != nullptr) { + bq25896->powerOff(); + } } static std::shared_ptr power; diff --git a/Boards/LilygoTLoraPager/Source/hal/TpagerPower.h b/Boards/LilygoTLoraPager/Source/hal/TpagerPower.h index a215d3e7..9ee3015f 100644 --- a/Boards/LilygoTLoraPager/Source/hal/TpagerPower.h +++ b/Boards/LilygoTLoraPager/Source/hal/TpagerPower.h @@ -20,7 +20,8 @@ public: bool supportsMetric(MetricType type) const override; bool getMetric(MetricType type, MetricData& data) override; -private: + bool supportsPowerOff() const override { return true; } + void powerOff() override; }; std::shared_ptr tpager_get_power(); diff --git a/Data/data/settings.properties b/Data/data/settings.properties index 0b905db8..cacfd596 100644 --- a/Data/data/settings.properties +++ b/Data/data/settings.properties @@ -1,2 +1,2 @@ -language=en-US +language=nl-NL timeFormat24h=true \ No newline at end of file diff --git a/Data/system/app/Launcher/i18n/en-GB.i18n b/Data/system/app/Launcher/i18n/en-GB.i18n deleted file mode 100644 index 5226a6e5..00000000 --- a/Data/system/app/Launcher/i18n/en-GB.i18n +++ /dev/null @@ -1,3 +0,0 @@ -Apps -Files -Settings diff --git a/Data/system/app/Launcher/i18n/en-US.i18n b/Data/system/app/Launcher/i18n/en-US.i18n deleted file mode 100644 index 5226a6e5..00000000 --- a/Data/system/app/Launcher/i18n/en-US.i18n +++ /dev/null @@ -1,3 +0,0 @@ -Apps -Files -Settings diff --git a/Data/system/app/Launcher/i18n/fr-FR.i18n b/Data/system/app/Launcher/i18n/fr-FR.i18n deleted file mode 100644 index 663a29ea..00000000 --- a/Data/system/app/Launcher/i18n/fr-FR.i18n +++ /dev/null @@ -1,3 +0,0 @@ -Appli -Fichiers -Réglages diff --git a/Data/system/app/Launcher/i18n/nl-BE.i18n b/Data/system/app/Launcher/i18n/nl-BE.i18n deleted file mode 100644 index 89a1e21f..00000000 --- a/Data/system/app/Launcher/i18n/nl-BE.i18n +++ /dev/null @@ -1,3 +0,0 @@ -Apps -Bestanden -Instellingen diff --git a/Data/system/app/Launcher/i18n/nl-NL.i18n b/Data/system/app/Launcher/i18n/nl-NL.i18n deleted file mode 100644 index 89a1e21f..00000000 --- a/Data/system/app/Launcher/i18n/nl-NL.i18n +++ /dev/null @@ -1,3 +0,0 @@ -Apps -Bestanden -Instellingen diff --git a/Drivers/BQ25896/CMakeLists.txt b/Drivers/BQ25896/CMakeLists.txt new file mode 100644 index 00000000..8074f3b3 --- /dev/null +++ b/Drivers/BQ25896/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "Source" + INCLUDE_DIRS "Source" + REQUIRES Tactility +) diff --git a/Drivers/BQ25896/README.md b/Drivers/BQ25896/README.md new file mode 100644 index 00000000..5e77d4c7 --- /dev/null +++ b/Drivers/BQ25896/README.md @@ -0,0 +1,5 @@ +# BQ25896 Power Management IC + +[Product page](https://www.ti.com/product/BQ25896) +[Data sheet](https://www.ti.com/lit/gpn/bq25896) +[Refence implementation](https://github.com/lewisxhe/XPowersLib/blob/73b92a6641b72c0aca2be989207689cb05da9788/src/PowersBQ25896.tpp) diff --git a/Drivers/BQ25896/Source/Bq25896.cpp b/Drivers/BQ25896/Source/Bq25896.cpp new file mode 100644 index 00000000..27c66d5e --- /dev/null +++ b/Drivers/BQ25896/Source/Bq25896.cpp @@ -0,0 +1,13 @@ +#include "Bq25896.h" + +#define TAG "BQ27220" + +void Bq25896::powerOff() { + TT_LOG_I(TAG, "Power off"); + bitOn(0x09, BIT(5)); +} + +void Bq25896::powerOn() { + TT_LOG_I(TAG, "Power on"); + bitOff(0x09, BIT(5)); +} diff --git a/Drivers/BQ25896/Source/Bq25896.h b/Drivers/BQ25896/Source/Bq25896.h new file mode 100644 index 00000000..1d3c428e --- /dev/null +++ b/Drivers/BQ25896/Source/Bq25896.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +constexpr auto BQ25896_ADDRESS = 0x6b; + +class Bq25896 final : public tt::hal::i2c::I2cDevice { + +public: + + std::string getName() const override { return "BQ25896"; } + + std::string getDescription() const override { return "I2C 1 cell 3A buck battery charger with power path and PSEL"; } + + explicit Bq25896(i2c_port_t port) : I2cDevice(port, BQ25896_ADDRESS) {} + + void powerOff(); + + void powerOn(); +}; diff --git a/Drivers/ST7796/README.md b/Drivers/ST7796/README.md index eae8f783..5c8a5ee2 100644 --- a/Drivers/ST7796/README.md +++ b/Drivers/ST7796/README.md @@ -1,3 +1,4 @@ # ST7796 A basic ESP32 LVGL driver for ST7796 displays. + diff --git a/Drivers/ST7796/Source/St7796Display.cpp b/Drivers/ST7796/Source/St7796Display.cpp index 04cfd9b1..3cf465d2 100644 --- a/Drivers/ST7796/Source/St7796Display.cpp +++ b/Drivers/ST7796/Source/St7796Display.cpp @@ -67,27 +67,12 @@ bool St7796Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lc const esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = configuration->resetPin, // Set to -1 if not use -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) - .color_space = ESP_LCD_COLOR_SPACE_RGB, -#else .color_space = LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, -#endif .bits_per_pixel = 16, .vendor_config = &vendor_config }; - /* - const esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = configuration->resetPin, - .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, - .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, - .bits_per_pixel = 16, - .flags = { - .reset_active_high = false - }, - .vendor_config = nullptr - }; - */ + if (esp_lcd_new_panel_st7796(ioHandle, &panel_config, &panelHandle) != ESP_OK) { TT_LOG_E(TAG, "Failed to create panel"); return false; diff --git a/Drivers/ST7796/Source/St7796Display.h b/Drivers/ST7796/Source/St7796Display.h index a5ee3ef9..cbee3753 100644 --- a/Drivers/ST7796/Source/St7796Display.h +++ b/Drivers/ST7796/Source/St7796Display.h @@ -4,7 +4,6 @@ #include #include -#include #include class St7796Display final : public EspLcdDisplay { diff --git a/Tactility/Include/Tactility/hal/power/PowerDevice.h b/Tactility/Include/Tactility/hal/power/PowerDevice.h index 2525289d..392f971e 100644 --- a/Tactility/Include/Tactility/hal/power/PowerDevice.h +++ b/Tactility/Include/Tactility/hal/power/PowerDevice.h @@ -39,6 +39,9 @@ public: virtual bool supportsChargeControl() const { return false; } virtual bool isAllowedToCharge() const { return false; } virtual void setAllowedToCharge(bool canCharge) { /* NO-OP*/ } + + virtual bool supportsPowerOff() const { return false; } + virtual void powerOff() { /* NO-OP*/ } }; } // namespace tt diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index 5250348c..ec9568e5 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -1,16 +1,16 @@ -#include "Tactility/Tactility.h" - -#include "Tactility/app/AppRegistration.h" -#include "Tactility/lvgl/LvglPrivate.h" -#include "Tactility/service/ServiceManifest.h" +#include +#include +#include #include +#include +#include #include #include namespace tt { -#define TAG "tactility" +#define TAG "Tactility" static const Configuration* config_instance = nullptr; diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index 1c994cc7..502eeb4e 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -1,5 +1,4 @@ #include "Tactility/app/AppContext.h" -#include "Tactility/app/launcher/TextResources.h" #include "Tactility/app/AppRegistration.h" #include "Tactility/service/loader/Loader.h" @@ -7,54 +6,49 @@ #include #include +#include namespace tt::app::launcher { constexpr auto* TAG = "Launcher"; +constexpr auto BUTTON_SIZE = 64; static void onAppPressed(TT_UNUSED lv_event_t* e) { - auto* appId = (const char*)lv_event_get_user_data(e); + auto* appId = static_cast(lv_event_get_user_data(e)); service::loader::startApp(appId); } -static lv_obj_t* createAppButton(lv_obj_t* parent, const char* title, const char* imageFile, const char* appId, int32_t buttonPaddingLeft) { - auto* wrapper = lv_obj_create(parent); - lv_obj_set_size(wrapper, LV_SIZE_CONTENT, LV_SIZE_CONTENT); - lv_obj_set_style_pad_ver(wrapper, 0, 0); - lv_obj_set_style_pad_left(wrapper, buttonPaddingLeft, 0); - lv_obj_set_style_pad_right(wrapper, 0, 0); - lv_obj_set_style_border_width(wrapper, 0, 0); - - auto* apps_button = lv_button_create(wrapper); - lv_obj_set_style_pad_hor(apps_button, 0, 0); - lv_obj_set_style_pad_top(apps_button, 0, 0); - lv_obj_set_style_pad_bottom(apps_button, 8, 0); - lv_obj_set_style_shadow_width(apps_button, 0, 0); - lv_obj_set_style_border_width(apps_button, 0, 0); +static lv_obj_t* createAppButton(lv_obj_t* parent, const char* imageFile, const char* appId, int32_t horizontalMargin) { + auto* apps_button = lv_button_create(parent); + lv_obj_set_style_pad_all(apps_button, 0, LV_STATE_DEFAULT); + lv_obj_set_style_margin_hor(apps_button, horizontalMargin, LV_STATE_DEFAULT); + lv_obj_set_style_shadow_width(apps_button, 0, LV_STATE_DEFAULT); + lv_obj_set_style_border_width(apps_button, 0, LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(apps_button, 0, LV_PART_MAIN); auto* button_image = lv_image_create(apps_button); lv_image_set_src(button_image, imageFile); lv_obj_set_style_image_recolor(button_image, lv_theme_get_color_primary(parent), LV_STATE_DEFAULT); lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, LV_STATE_DEFAULT); - // Ensure buttons are still tappable when asset fails to load + // Ensure buttons are still tappable when the asset fails to load // Icon images are 40x40, so we get some extra padding too - lv_obj_set_size(button_image, 64, 64); + lv_obj_set_size(button_image, BUTTON_SIZE, BUTTON_SIZE); - auto* label = lv_label_create(wrapper); - lv_label_set_text(label, title); - lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 0); - - lv_obj_add_event_cb(wrapper, onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)appId); lv_obj_add_event_cb(apps_button, onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)appId); - lv_obj_add_event_cb(label, onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)appId); - return wrapper; + return apps_button; } class LauncherApp : public App { - tt::i18n::TextResources textResources = tt::i18n::TextResources("/system/app/Launcher/i18n"); + static void onPowerOffPressed(lv_event_t* e) { + auto power = hal::findFirstDevice(hal::Device::Type::Power); + if (power != nullptr && power->supportsPowerOff()) { + power->powerOff(); + } + } + +public: void onCreate(TT_UNUSED AppContext& app) override { BootProperties boot_properties; if (loadBootProperties(boot_properties) && !boot_properties.autoStartAppId.empty()) { @@ -64,41 +58,42 @@ class LauncherApp : public App { } void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { - textResources.load(); + auto* buttons_wrapper = lv_obj_create(parent); - auto* wrapper = lv_obj_create(parent); + lv_obj_align(buttons_wrapper, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_pad_all(buttons_wrapper, 0, LV_STATE_DEFAULT); + lv_obj_set_size(buttons_wrapper, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_style_border_width(buttons_wrapper, 0, LV_STATE_DEFAULT); + lv_obj_set_flex_grow(buttons_wrapper, 1); - lv_obj_align(wrapper, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_style_pad_all(wrapper, 0, 0); - lv_obj_set_size(wrapper, LV_SIZE_CONTENT, LV_SIZE_CONTENT); - lv_obj_set_style_border_width(wrapper, 0, 0); - lv_obj_set_flex_grow(wrapper, 1); - - auto* display = lv_obj_get_display(parent); - auto horizontal_px = lv_display_get_horizontal_resolution(display); - auto vertical_px = lv_display_get_vertical_resolution(display); - bool is_landscape_display = horizontal_px >= vertical_px; + const auto* display = lv_obj_get_display(parent); + const auto horizontal_px = lv_display_get_horizontal_resolution(display); + const auto vertical_px = lv_display_get_vertical_resolution(display); + const bool is_landscape_display = horizontal_px >= vertical_px; if (is_landscape_display) { - lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_flow(buttons_wrapper, LV_FLEX_FLOW_ROW); } else { - lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_flow(buttons_wrapper, LV_FLEX_FLOW_COLUMN); } - int32_t available_width = lv_display_get_horizontal_resolution(display) - (3 * 80); - int32_t padding = is_landscape_display ? std::min(available_width / 4, (int32_t)64) : 0; + const int32_t available_width = lv_display_get_horizontal_resolution(display) - (3 * BUTTON_SIZE); + const int32_t margin = is_landscape_display ? std::min(available_width / 16, BUTTON_SIZE) : 0; - auto paths = app.getPaths(); - auto apps_icon_path = paths->getSystemPathLvgl("icon_apps.png"); - auto files_icon_path = paths->getSystemPathLvgl("icon_files.png"); - auto settings_icon_path = paths->getSystemPathLvgl("icon_settings.png"); + const auto paths = app.getPaths(); + const auto apps_icon_path = paths->getSystemPathLvgl("icon_apps.png"); + const auto files_icon_path = paths->getSystemPathLvgl("icon_files.png"); + const auto settings_icon_path = paths->getSystemPathLvgl("icon_settings.png"); - const auto& apps_title = textResources[i18n::Text::APPS]; - const auto& files_title = textResources[i18n::Text::FILES]; - const auto& settings_title = textResources[i18n::Text::SETTINGS]; + createAppButton(buttons_wrapper, apps_icon_path.c_str(), "AppList", margin); + createAppButton(buttons_wrapper, files_icon_path.c_str(), "Files", margin); + createAppButton(buttons_wrapper, settings_icon_path.c_str(), "Settings", margin); - createAppButton(wrapper, apps_title.c_str(), apps_icon_path.c_str(), "AppList", 0); - createAppButton(wrapper, files_title.c_str(), files_icon_path.c_str(), "Files", padding); - createAppButton(wrapper, settings_title.c_str(), settings_icon_path.c_str(), "Settings", padding); + auto* power_button = lv_btn_create(parent); + lv_obj_set_style_pad_all(power_button, 8, 0); + lv_obj_align(power_button, LV_ALIGN_BOTTOM_MID, 0, -10); + lv_obj_add_event_cb(power_button, onPowerOffPressed, LV_EVENT_SHORT_CLICKED, nullptr); + auto* power_label = lv_label_create(power_button); + lv_label_set_text(power_label, LV_SYMBOL_POWER); } }; diff --git a/Tactility/Source/app/screenshot/Screenshot.cpp b/Tactility/Source/app/screenshot/Screenshot.cpp index a87b22c2..3844f82b 100644 --- a/Tactility/Source/app/screenshot/Screenshot.cpp +++ b/Tactility/Source/app/screenshot/Screenshot.cpp @@ -37,7 +37,7 @@ class ScreenshotApp final : public App { public: ScreenshotApp(); - ~ScreenshotApp(); + ~ScreenshotApp() override; void onShow(AppContext& app, lv_obj_t* parent) override; void onStartPressed(); diff --git a/Tactility/Source/hal/i2c/I2cDevice.cpp b/Tactility/Source/hal/i2c/I2cDevice.cpp index 1e96f8d5..3cc44080 100644 --- a/Tactility/Source/hal/i2c/I2cDevice.cpp +++ b/Tactility/Source/hal/i2c/I2cDevice.cpp @@ -5,11 +5,11 @@ namespace tt::hal::i2c { bool I2cDevice::read(uint8_t* data, size_t dataSize, TickType_t timeout) { - return tt::hal::i2c::masterRead(port, address, data, dataSize, timeout); + return masterRead(port, address, data, dataSize, timeout); } bool I2cDevice::write(const uint8_t* data, uint16_t dataSize, TickType_t timeout) { - return tt::hal::i2c::masterWrite(port, address, data, dataSize, timeout); + return masterWrite(port, address, data, dataSize, timeout); } bool I2cDevice::writeRead(const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) { @@ -22,7 +22,7 @@ bool I2cDevice::writeRegister(uint8_t reg, const uint8_t* data, uint16_t dataSiz bool I2cDevice::readRegister12(uint8_t reg, float& out) const { std::uint8_t data[2] = {0}; - if (tt::hal::i2c::masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { + if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { out = (data[0] & 0x0F) << 8 | data[1]; return true; } else { @@ -32,7 +32,7 @@ bool I2cDevice::readRegister12(uint8_t reg, float& out) const { bool I2cDevice::readRegister14(uint8_t reg, float& out) const { std::uint8_t data[2] = {0}; - if (tt::hal::i2c::masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { + if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { out = (data[0] & 0x3F) << 8 | data[1]; return true; } else { @@ -42,7 +42,7 @@ bool I2cDevice::readRegister14(uint8_t reg, float& out) const { bool I2cDevice::readRegister16(uint8_t reg, uint16_t& out) const { std::uint8_t data[2] = {0}; - if (tt::hal::i2c::masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { + if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) { out = data[0] << 8 | data[1]; return true; } else { @@ -51,11 +51,11 @@ bool I2cDevice::readRegister16(uint8_t reg, uint16_t& out) const { } bool I2cDevice::readRegister8(uint8_t reg, uint8_t& result) const { - return tt::hal::i2c::masterWriteRead(port, address, ®, 1, &result, 1, DEFAULT_TIMEOUT); + return masterWriteRead(port, address, ®, 1, &result, 1, DEFAULT_TIMEOUT); } bool I2cDevice::writeRegister8(uint8_t reg, uint8_t value) const { - return tt::hal::i2c::masterWriteRegister(port, address, reg, &value, 1, DEFAULT_TIMEOUT); + return masterWriteRegister(port, address, reg, &value, 1, DEFAULT_TIMEOUT); } bool I2cDevice::bitOn(uint8_t reg, uint8_t bitmask) const { diff --git a/Tactility/Source/lvgl/Statusbar.cpp b/Tactility/Source/lvgl/Statusbar.cpp index 68ca0deb..0e27a870 100644 --- a/Tactility/Source/lvgl/Statusbar.cpp +++ b/Tactility/Source/lvgl/Statusbar.cpp @@ -111,7 +111,7 @@ static const lv_obj_class_t statusbar_class = { static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) { TT_LOG_D(TAG, "event"); auto* statusbar = static_cast(obj); - if (lock(kernel::millisToTicks(100))) { + if (lock(portMAX_DELAY)) { update_main(statusbar); lv_obj_invalidate(&statusbar->obj); unlock(); @@ -119,7 +119,7 @@ static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) { } static void onTimeChanged(TT_UNUSED kernel::SystemEvent event) { - if (statusbar_data.mutex.lock(100 / portTICK_PERIOD_MS)) { + if (statusbar_data.mutex.lock()) { statusbar_data.time_update_timer->stop(); statusbar_data.time_update_timer->start(5); @@ -136,7 +136,7 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) statusbar->pubsub_subscription = statusbar_data.pubsub->subscribe(&statusbar_pubsub_event, statusbar); if (!statusbar_data.time_update_timer->isRunning()) { - statusbar_data.time_update_timer->start(50 / portTICK_PERIOD_MS); + statusbar_data.time_update_timer->start(200 / portTICK_PERIOD_MS); statusbar_data.systemEventSubscription = kernel::subscribeSystemEvent( kernel::SystemEvent::Time, onTimeChanged @@ -210,7 +210,7 @@ static void update_time(Statusbar* statusbar) { static void update_main(Statusbar* statusbar) { update_time(statusbar); - if (statusbar_lock(50 / portTICK_PERIOD_MS)) { + if (statusbar_lock(200 / portTICK_PERIOD_MS)) { for (int i = 0; i < STATUSBAR_ICON_LIMIT; ++i) { update_icon(statusbar->icons[i], &(statusbar_data.icons[i])); } @@ -270,7 +270,7 @@ void statusbar_icon_remove(int8_t id) { void statusbar_icon_set_image(int8_t id, const std::string& image) { TT_LOG_D(TAG, "id %d: set image %s", id, image.empty() ? "(none)" : image.c_str()); tt_check(id >= 0 && id < STATUSBAR_ICON_LIMIT); - if (statusbar_lock(50 / portTICK_PERIOD_MS)) { + if (statusbar_lock()) { StatusbarIcon* icon = &statusbar_data.icons[id]; tt_check(icon->claimed); icon->image = image; @@ -282,7 +282,7 @@ void statusbar_icon_set_image(int8_t id, const std::string& image) { void statusbar_icon_set_visibility(int8_t id, bool visible) { TT_LOG_D(TAG, "id %d: set visibility %d", id, visible); tt_check(id >= 0 && id < STATUSBAR_ICON_LIMIT); - if (statusbar_lock(50 / portTICK_PERIOD_MS)) { + if (statusbar_lock()) { StatusbarIcon* icon = &statusbar_data.icons[id]; tt_check(icon->claimed); icon->visible = visible; diff --git a/Translations/Translations.ods b/Translations/Translations.ods index 3ce333cdb1c527796c70bc09d411fc7401decf78..44298ecf4a93479bf0ce92f79c0f6f6640808618 100644 GIT binary patch delta 4310 zcmaJ_WmuDK8{P)!Ml(Se-8rRUAOi%H5h4vriXzfVIMM;qAjqbKNW%yz>26R!x?VbE zI$ERz^#kAde7_&x_2apZ=Zf=s;yCW}I`4JIQ3onrEfP|C000aCxQ4LBQR$JKE;xRW z==r}~xOJfHnJ+Gt3zsNKN%33uX^0D_BT4UC|=(uZp;F$v-2~zm_{P z=fPm`S>tkZkQ?Ndc^%9A!6?VPtTC#qkAuzeVW><~vpz;M>o~I9ex63}t&E(dg>s{4 z&8^F8AfNSPlbVTGL(88B7i52u=xUt@yP4#~;2;3NJOTjt^S%Ct7obD}&syT_sMs)O zv--<2^i5j^UNcG5jk?;$*w!e| zm1YDNHFdCcXk&NBFuMOJd-wB1cWeElmO?tzHL|VgjqxgHAet;=W^3BSDt0LK`{s5S z$)fjY2s@n%Jz(NJgE`5>IKtX|PX&S@uj!J11l5?kV5&E^i~x*{xZDhGai5;ENVbH^ zUP8Yl5}S~t^6PRstnZ3yrlG^=CQAgK+MdZ#K>Zj?TLqq-oZFOdQZ4OzpvLt>yqbx| zvve@CvAKDRx01|oh)K_qkGBQ)F^nvH|ScWSqe8lyO?S5TYmxIOG#7N_*VVR zgb3&)-(FvRwv&izV=$qZhl^f6LH!6pVHCjl(GV=z30~srkw(!OQ)2w3zc>;eub5C? zLWkRKzy%gy5sBKPAy&WXiwZ;j2G`0x}&;cw`LfBP4ii4Xm&YgRs~^89ujj7b#Mf+8%z2n(Rh0`lq!`V^M(m5k+dnJ0!hr{3Q$x)89Bx< z(`oIWLj}s%^pPR=KI`ewwv$*FxcVjvl}bj#aL|+RI}z4S#R4Dr?dXK@(KV(}X|_^( z+b>DLk-6`j_wL-@^py0_V&Q`&HpO2}%6ph)zg;0gIY~;VJ4%=o(|%(IxmQjI%ImIs zMYUsyxftPdk(kpoptC8-)&eu+f^b<=WxH-EYK`tEZ%#LQ$Le=b%p@^bUzQN75-d*g z`r<5hpNiP zWvX{+E#g}wgYebf^C>S=btxFBRy^3<$n_fZJS}IQkmPKy7*UMcsub1SLw={6Qr1bp zz%zZ?M+oBY7mT7t8rGZ>sr!>P?Av=3Vy|Omt|ooN60fWqEZUq)n0)55=e$ozAVy7Z zUNAqmr7+9z^?+h|i?M57GtZ} z!4FL(s4s8nU7B<5h#QTMyLx2~(lzB~VVL>qua4{!lGbAaj-<$6!E1w;HZTK1HNkE3 zbPe>az~-1&`%8-#4q!&7ppgbt9d)Cos>`c&H)qb{3ybFaW;ymC*$PMZ#|~1D;dFBw zO3aQS#Rz|K9NV@dX0V~K|G`$UTUvNmpU>`6xejUW$@Sr8msAZ5qfJm2AR2(Niu|GA zy@C9c{XIAW8Q;?9;0y1okHL5Mm+A}E+6}&f_#V4vR>{wfux4m%e{P@SSNvQbiN{WT zeG}<>oFS)alXy(GpZr)2;mluD!c^iFYNf6O-wN?zEV{0meWJBIZ1v#&liAmd_-0Ih z+Un0p|3jrSc6{K}$xS#10APBN|3i;vfZyzN5&$^cdfd6}Op1yQW<=wpI;lv zyQ&+=gMtH1QpwGutEz(Q)_%_fZz}_DyP77Iq$9PBS+r?gg#8}fJe*2<@Z)sYIS&@J z^nQ^81OW6%{@>rF1ORXw7ilo_21_W~C(X@mJ@p`>e*KHGkUSA|jXr5(y*~?FX{8e4wf znRw7Jz-HnnoGuV}Ll9G8Y(=yM=U!BI_DmLdmcZ!>VsFzuGV6ln;w=YK_D0c(vS96B3S$3YwUJn|(N0>bN z1|Z4gUVTFZ3-Vw~C2ZtMIQ_)y?Gk356}d0-(%c8EeH<;+WSEJ&q3neNbvO0RX4^7$ zSp7ae>|3)XyV6gw8d)NOS_wo8#Q{Q%O?ttam#IDcunRiY8LsTg{iJ>*|UH~E704=t+Lhx~!F2lts*Jb9%UcLovRGZU4a z3!!1tyPE7t2O4ddltHBg)h6z44Ag-is^83CZ5dQUl3#n5+`sR5jC8Da(udd#JfTU_ zjeQL9OwdK2U3Q_w=dAoKmoJY{WRJHAZ}sI@@_xaDW$&jLPw5@UO#MWUrXG0e!$mYh zG+>uKkEt^37dkD)#{}re z5O~ZHgBW8rjHikwUBJl!;Ggco%_czU3)9vRWN{lYWZ>y8Xk1DaU83Ss-vTZ3>hh~L zy1@IZFEC5yaG@)W#GZp_3?D1s|Io%nA0cQ(km|)h^*rpe$>nZfyJ7L8#i&nWgUl;M z(>Y!La4ty1_mqPnM*}BJ;y~En_Afsv-nM5NKawY-w(POpmOrZhDkeD2hW3 z+xh1ErD|>;l|esVIpVzil-;KQF-~B+F5H#jy*oY$c!)Acg9t#i30P0>!=?dVcd7S^ zWErFk?)n>L3*3o8(+00IHc;$DuQ=Erl)U$s9)V30Wh)r!+rHgs3De$1Cl<13V^pfU z-mc7JYkB297E>HDxs7dopoIC*`QE~P7)4m$!pGPg%jM1YYo@k}cf*?AzZ7y<-uq#< z@F?2d&_0;Lqk6xj=WEHNY~D-7pm<2)c^-)5bLhaz3J8P3m98LLwkDgzK&^=DIg1-2I z&_H>&L*;n_7R2IF@x;p@tAu4SDQJHOrp}*m&3sPiEBAJDrb_iBiS~(LBKPvSY!oFX zVNSWZwTaV~`|*r39c?cNbgv<$!wMR3a5VS&eAFL*v2Ps zT@%&9QXC!SCp$5^zhAOy2rZknk6Xwu3QHWLzU{81@{F-L(SGH7eBLq5*%k{lHM%ZD z1^_&h`g@E0OC*eOVQWvKs!GaqSr^g9P(f%W;-%7H8A_2I5 zN#S3bG){sA)B(VSN(%nEJ&T?Ia0-7#PXT~3xIGDhe{!9GxMGPvb5DbyY#@$P;v(*e z1noZ=Q)ezg&eI3_7qxTzM)Lpw6cqQ62MPqy1Ly&N>14BC3i`T~*e@h+DOu_>h`$Gi zUL>wbO2p{Q^*h;|4GjM^pVPyHzsCn%t$(Bc{{2pg=r=RMDN3{aYHBXc0;*xbIk7T} i{BL<0TV#RwDZ{}@0RV>IiU9yyT$8lmxk<4z=YIen!jj+s delta 4521 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 diff --git a/sdkconfig.board.lilygo-tlora-pager b/sdkconfig.board.lilygo-tlora-pager index f68156ed..d31a9405 100644 --- a/sdkconfig.board.lilygo-tlora-pager +++ b/sdkconfig.board.lilygo-tlora-pager @@ -59,3 +59,5 @@ CONFIG_LV_THEME_DEFAULT_DARK=y # USB CONFIG_TINYUSB_MSC_ENABLED=y CONFIG_TINYUSB_MSC_MOUNT_PATH="/sdcard" +# Boot optimization +CONFIG_SPIRAM_MEMTEST=n