From 0c50c03c12bf5bbedf03b3f5c1b7ca80950a1565 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 30 Aug 2025 19:33:00 +0200 Subject: [PATCH] Various improvements --- .../Source/LilygoTloraPager.cpp | 4 +- .../Source/hal/TpagerKeyboard.cpp | 1 - Documentation/ideas.md | 2 +- .../Tactility/hal/sdcard/SdCardMounting.h | 7 ++++ Tactility/Source/TactilityHeadless.cpp | 5 ++- Tactility/Source/app/boot/Boot.cpp | 7 ++-- Tactility/Source/hal/Hal.cpp | 35 +++------------- .../Source/hal/sdcard/SdCardMounting.cpp | 40 +++++++++++++++++++ Tactility/Source/hal/usb/Usb.cpp | 33 ++++++++------- Tactility/Source/lvgl/Lvgl.cpp | 17 +++++++- 10 files changed, 95 insertions(+), 56 deletions(-) create mode 100644 Tactility/Private/Tactility/hal/sdcard/SdCardMounting.h create mode 100644 Tactility/Source/hal/sdcard/SdCardMounting.cpp diff --git a/Boards/LilygoTLoraPager/Source/LilygoTloraPager.cpp b/Boards/LilygoTLoraPager/Source/LilygoTloraPager.cpp index 05f6ad09..3394eb0b 100644 --- a/Boards/LilygoTLoraPager/Source/LilygoTloraPager.cpp +++ b/Boards/LilygoTLoraPager/Source/LilygoTloraPager.cpp @@ -41,10 +41,10 @@ extern const Configuration lilygo_tlora_pager = { .createDevices = createDevices, .i2c = { i2c::Configuration { - .name = "Shared", + .name = "Internal", .port = I2C_NUM_0, .initMode = i2c::InitMode::ByTactility, - .isMutable = true, + .isMutable = false, .config = (i2c_config_t) { .mode = I2C_MODE_MASTER, .sda_io_num = GPIO_NUM_3, diff --git a/Boards/LilygoTLoraPager/Source/hal/TpagerKeyboard.cpp b/Boards/LilygoTLoraPager/Source/hal/TpagerKeyboard.cpp index 8e1e51bc..40c94162 100644 --- a/Boards/LilygoTLoraPager/Source/hal/TpagerKeyboard.cpp +++ b/Boards/LilygoTLoraPager/Source/hal/TpagerKeyboard.cpp @@ -43,7 +43,6 @@ void TpagerKeyboard::readCallback(lv_indev_t* indev, lv_indev_data_t* data) { char keypress = 0; if (xQueueReceive(keyboard->queue, &keypress, pdMS_TO_TICKS(50)) == pdPASS) { - TT_LOG_I(TAG, "Keypress: %c", keypress); data->key = keypress; data->state = LV_INDEV_STATE_PRESSED; } else { diff --git a/Documentation/ideas.md b/Documentation/ideas.md index e055f691..4cb1a80e 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -16,7 +16,7 @@ ## Lower Priority -- Support hot-plugging SD card +- Support hot-plugging SD card (note: this is not possible if they require the CS pin hack) - Create more unit tests for `tactility` - Explore LVGL9's FreeRTOS functionality - CrashHandler: use "corrupted" flag diff --git a/Tactility/Private/Tactility/hal/sdcard/SdCardMounting.h b/Tactility/Private/Tactility/hal/sdcard/SdCardMounting.h new file mode 100644 index 00000000..163e5a7e --- /dev/null +++ b/Tactility/Private/Tactility/hal/sdcard/SdCardMounting.h @@ -0,0 +1,7 @@ +#pragma once + +namespace tt::hal::sdcard { + +void mountAll(); + +} diff --git a/Tactility/Source/TactilityHeadless.cpp b/Tactility/Source/TactilityHeadless.cpp index a827e5ab..a74ff2bf 100644 --- a/Tactility/Source/TactilityHeadless.cpp +++ b/Tactility/Source/TactilityHeadless.cpp @@ -6,6 +6,7 @@ #include "Tactility/service/ServiceRegistration.h" #include +#include #include #ifdef ESP_PLATFORM @@ -14,7 +15,7 @@ namespace tt { -#define TAG "tactility" +constexpr auto* TAG = "Tactility"; namespace service::gps { extern const ServiceManifest manifest; } namespace service::wifi { extern const ServiceManifest manifest; } @@ -47,11 +48,11 @@ void initHeadless(const hal::Configuration& config) { hardwareConfig = &config; settings::initTimeZone(); hal::init(config); + hal::sdcard::mountAll(); network::ntp::init(); registerAndStartSystemServices(); } - Dispatcher& getMainDispatcher() { return mainDispatcher; } diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index f5d46196..631739d0 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -22,10 +22,10 @@ #define CONFIG_TT_SPLASH_DURATION 0 #endif -#define TAG "boot" - namespace tt::app::boot { +constexpr auto* TAG = "Boot"; + static std::shared_ptr getHalDisplay() { return hal::findFirstDevice(hal::Device::Type::Display); } @@ -60,6 +60,7 @@ class BootApp : public App { } } + static bool setupUsbBootMode() { if (!hal::usb::isUsbBootMode()) { return false; @@ -86,7 +87,7 @@ class BootApp : public App { kernel::publishSystemEvent(kernel::SystemEvent::BootSplash); - setupDisplay(); + setupDisplay(); // Set backlight if (!setupUsbBootMode()) { initFromBootApp(); diff --git a/Tactility/Source/hal/Hal.cpp b/Tactility/Source/hal/Hal.cpp index 1c4c781c..f46f00d0 100644 --- a/Tactility/Source/hal/Hal.cpp +++ b/Tactility/Source/hal/Hal.cpp @@ -8,13 +8,13 @@ #include -#define TAG "hal" - -#define TT_SDCARD_MOUNT_POINT "/sdcard" - namespace tt::hal { -void initDevices(const Configuration& configuration) { +constexpr auto* TAG = "hal"; + +void registerDevices(const Configuration& configuration) { + TT_LOG_I(TAG, "Registering devices"); + if (configuration.sdcard != nullptr) { registerDevice(configuration.sdcard); } @@ -35,29 +35,6 @@ void initDevices(const Configuration& configuration) { for (auto& device : devices) { registerDevice(device); } - - // TODO: Move - auto sdcards = hal::findDevices(Device::Type::SdCard); - if (!sdcards.empty()) { - if (sdcards.size() == 1) { - // Fixed mount path name - auto sdcard = sdcards[0]; - TT_LOG_I(TAG, "Mounting sdcard at %s", TT_SDCARD_MOUNT_POINT); - if (!sdcard->mount(TT_SDCARD_MOUNT_POINT)) { - TT_LOG_W(TAG, "SD card mount failed (init can continue)"); - } - } else { - // Numbered mount path name - for (int i = 0; i < sdcards.size(); i++) { - auto sdcard = sdcards[i]; - std::string mount_path = TT_SDCARD_MOUNT_POINT + std::to_string(i); - TT_LOG_I(TAG, "Mounting sdcard at %d", mount_path.c_str()); - if (!sdcard->mount(mount_path)) { - TT_LOG_W(TAG, "SD card mount failed (init can continue)"); - } - } - } - } } void init(const Configuration& configuration) { @@ -80,7 +57,7 @@ void init(const Configuration& configuration) { tt_check(configuration.initBoot(), "Init power failed"); } - initDevices(configuration); + registerDevices(configuration); kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd); } diff --git a/Tactility/Source/hal/sdcard/SdCardMounting.cpp b/Tactility/Source/hal/sdcard/SdCardMounting.cpp new file mode 100644 index 00000000..1a3079e0 --- /dev/null +++ b/Tactility/Source/hal/sdcard/SdCardMounting.cpp @@ -0,0 +1,40 @@ +#include +#include + +namespace tt::hal::sdcard { + +constexpr auto* TAG = "SdCardMounting"; +constexpr auto* TT_SDCARD_MOUNT_POINT = "/sdcard"; + +static void mount(const std::shared_ptr& sdcard, const std::string& path) { + sdcard->getLock()->withLock([&sdcard, &path] { + TT_LOG_I(TAG, "Mounting sdcard at %s", path.c_str()); + if (!sdcard->mount(path)) { + TT_LOG_W(TAG, "SD card mount failed for %s (init can continue)", path.c_str()); + } + }); +} + +void mountAll() { + auto sdcards = hal::findDevices(Device::Type::SdCard); + if (!sdcards.empty()) { + if (sdcards.size() == 1) { + // Fixed mount path name + auto sdcard = sdcards[0]; + if (!sdcard->isMounted()) { + mount(sdcard, TT_SDCARD_MOUNT_POINT); + } + } else { + // Numbered mount path name + for (int i = 0; i < sdcards.size(); i++) { + auto sdcard = sdcards[i]; + if (!sdcard->isMounted()) { + std::string mount_path = TT_SDCARD_MOUNT_POINT + std::to_string(i); + mount(sdcard, mount_path); + } + } + } + } +} + +} diff --git a/Tactility/Source/hal/usb/Usb.cpp b/Tactility/Source/hal/usb/Usb.cpp index ce522b3c..009507dd 100644 --- a/Tactility/Source/hal/usb/Usb.cpp +++ b/Tactility/Source/hal/usb/Usb.cpp @@ -21,30 +21,29 @@ static Mode currentMode = Mode::Default; static RTC_NOINIT_ATTR BootMode bootMode; sdmmc_card_t* _Nullable getCard() { - auto sdcard = getConfiguration()->sdcard; - if (sdcard == nullptr) { - TT_LOG_W(TAG, "No SD card configuration found"); + auto sdcards = findDevices(Device::Type::SdCard); + + std::shared_ptr usable_sdcard; + for (auto& sdcard : sdcards) { + auto sdcard_candidate = std::static_pointer_cast(sdcard); + if (sdcard_candidate != nullptr && sdcard_candidate->isMounted() && sdcard_candidate->getCard() != nullptr) { + usable_sdcard = sdcard_candidate; + break; + } + } + + if (usable_sdcard == nullptr) { + TT_LOG_W(TAG, "Couldn't find a mounted SpiSdCard"); return nullptr; } - if (!sdcard->isMounted()) { - TT_LOG_W(TAG, "SD card not mounted"); - return nullptr; - } - - auto spi_sdcard = std::static_pointer_cast(sdcard); - if (spi_sdcard == nullptr) { - TT_LOG_W(TAG, "SD card interface is not supported (must be SpiSdCard)"); - return nullptr; - } - - auto* card = spi_sdcard->getCard(); - if (card == nullptr) { + auto* sdmmc_card = usable_sdcard->getCard(); + if (sdmmc_card == nullptr) { TT_LOG_W(TAG, "SD card has no card object available"); return nullptr; } - return card; + return sdmmc_card; } static bool canStartNewMode() { diff --git a/Tactility/Source/lvgl/Lvgl.cpp b/Tactility/Source/lvgl/Lvgl.cpp index ddfeaddb..9f77098a 100644 --- a/Tactility/Source/lvgl/Lvgl.cpp +++ b/Tactility/Source/lvgl/Lvgl.cpp @@ -178,7 +178,7 @@ void start() { } void stop() { - TT_LOG_I(TAG, "Stop LVGL"); + TT_LOG_I(TAG, "Stopping LVGL"); if (!started) { TT_LOG_W(TAG, "Can't stop LVGL: not started"); @@ -195,6 +195,7 @@ void stop() { // Stop keyboards + TT_LOG_I(TAG, "Stopping keyboards"); auto keyboards = hal::findDevices(hal::Device::Type::Keyboard); for (auto keyboard : keyboards) { if (keyboard->getLvglIndev() != nullptr) { @@ -204,6 +205,7 @@ void stop() { // Stop touch + TT_LOG_I(TAG, "Stopping touch"); // The display generally stops their own touch devices, but we'll clean up anything that didn't auto touch_devices = hal::findDevices(hal::Device::Type::Touch); for (auto touch_device : touch_devices) { @@ -212,8 +214,19 @@ void stop() { } } + // Stop encoders + + TT_LOG_I(TAG, "Stopping encoders"); + // The display generally stops their own touch devices, but we'll clean up anything that didn't + auto encoder_devices = hal::findDevices(hal::Device::Type::Encoder); + for (auto encoder_device : encoder_devices) { + if (encoder_device->getLvglIndev() != nullptr) { + encoder_device->stopLvgl(); + } + } // Stop displays (and their touch devices) + TT_LOG_I(TAG, "Stopping displays"); auto displays = hal::findDevices(hal::Device::Type::Display); for (auto display : displays) { if (display->supportsLvgl() && display->getLvglDisplay() != nullptr && !display->stopLvgl()) { @@ -224,6 +237,8 @@ void stop() { started = false; kernel::publishSystemEvent(kernel::SystemEvent::LvglStopped); + + TT_LOG_I(TAG, "Stopped LVGL"); } } // namespace