From e63d9d9a56d6ad436908e2bb83970d55da125b53 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Thu, 14 Aug 2025 22:12:40 +0200 Subject: [PATCH] Work in progress on native display driver and the ability to stop&restart lvgl driver --- Boards/LilygoTdeck/CMakeLists.txt | 2 +- Drivers/EspLcdNativeDisplay/CMakeLists.txt | 5 ++ Drivers/EspLcdNativeDisplay/README.md | 3 ++ .../Source/EspLcdNativeDisplay.h | 33 ++++++++++++ Drivers/ST7789/CMakeLists.txt | 2 +- Drivers/ST7789/Source/St7789Display.cpp | 45 ++++++++++------ Drivers/ST7789/Source/St7789Display.h | 54 +++++++++++++++---- Tactility/Include/Tactility/hal/Device.h | 2 +- .../Tactility/hal/display/DisplayDevice.h | 10 ++++ .../Tactility/hal/display/NativeDisplay.h | 24 +++++++++ Tactility/Source/lvgl/Init.cpp | 8 +-- 11 files changed, 155 insertions(+), 33 deletions(-) create mode 100644 Drivers/EspLcdNativeDisplay/CMakeLists.txt create mode 100644 Drivers/EspLcdNativeDisplay/README.md create mode 100644 Drivers/EspLcdNativeDisplay/Source/EspLcdNativeDisplay.h create mode 100644 Tactility/Include/Tactility/hal/display/NativeDisplay.h diff --git a/Boards/LilygoTdeck/CMakeLists.txt b/Boards/LilygoTdeck/CMakeLists.txt index d1096554..dea29fde 100644 --- a/Boards/LilygoTdeck/CMakeLists.txt +++ b/Boards/LilygoTdeck/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_lvgl_port esp_lcd ST7789 GT911 PwmBacklight driver esp_adc + REQUIRES Tactility EspLcdNativeDisplay esp_lvgl_port esp_lcd ST7789 GT911 PwmBacklight driver esp_adc ) diff --git a/Drivers/EspLcdNativeDisplay/CMakeLists.txt b/Drivers/EspLcdNativeDisplay/CMakeLists.txt new file mode 100644 index 00000000..4d5d5ddd --- /dev/null +++ b/Drivers/EspLcdNativeDisplay/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "Source" + INCLUDE_DIRS "Source" + REQUIRES Tactility esp_lcd +) diff --git a/Drivers/EspLcdNativeDisplay/README.md b/Drivers/EspLcdNativeDisplay/README.md new file mode 100644 index 00000000..13358dc4 --- /dev/null +++ b/Drivers/EspLcdNativeDisplay/README.md @@ -0,0 +1,3 @@ +# EspLcdNativeDisplay + +An implementation of `tt::hal::display::NativeDisplay` for display drivers that are built around the `esp_lcd` library. diff --git a/Drivers/EspLcdNativeDisplay/Source/EspLcdNativeDisplay.h b/Drivers/EspLcdNativeDisplay/Source/EspLcdNativeDisplay.h new file mode 100644 index 00000000..934d0096 --- /dev/null +++ b/Drivers/EspLcdNativeDisplay/Source/EspLcdNativeDisplay.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace tt::hal::display { + +class EspLcdNativeDisplay final : public NativeDisplay { + + esp_lcd_panel_handle_t panelHandle; + ColorFormat colorFormat; + uint16_t pixelWidth; + uint16_t pixelHeight; + +public: + EspLcdNativeDisplay( + esp_lcd_panel_handle_t panelHandle, + ColorFormat colorFormat, + uint16_t pixelWidth, + uint16_t pixelHeight + ) : panelHandle(panelHandle), colorFormat(colorFormat), pixelWidth(pixelWidth), pixelHeight(pixelHeight) {} + + ColorFormat getColorFormat() const override { return colorFormat; } + + bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) override { + return esp_lcd_panel_draw_bitmap(panelHandle, xStart, yStart, xEnd, yEnd, pixelData) == ESP_OK; + } + + uint16_t getPixelWidth() const override { return pixelWidth; } + uint16_t getPixelHeight() const override { return pixelHeight; } +}; + +} diff --git a/Drivers/ST7789/CMakeLists.txt b/Drivers/ST7789/CMakeLists.txt index 2dd2736d..f70ae702 100644 --- a/Drivers/ST7789/CMakeLists.txt +++ b/Drivers/ST7789/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( SRC_DIRS "Source" INCLUDE_DIRS "Source" - REQUIRES Tactility esp_lvgl_port esp_lcd driver + REQUIRES Tactility esp_lvgl_port esp_lcd driver EspLcdNativeDisplay ) diff --git a/Drivers/ST7789/Source/St7789Display.cpp b/Drivers/ST7789/Source/St7789Display.cpp index c7e49a21..27006e07 100644 --- a/Drivers/ST7789/Source/St7789Display.cpp +++ b/Drivers/ST7789/Source/St7789Display.cpp @@ -7,7 +7,7 @@ #include #include -#define TAG "st7789" +#define TAG "ST7789" bool St7789Display::start() { TT_LOG_I(TAG, "Starting"); @@ -86,6 +86,29 @@ bool St7789Display::start() { TT_LOG_E(TAG, "Failed to turn display on"); return false; } + + TT_LOG_I(TAG, "Finished"); + return displayHandle != nullptr; +} + +bool St7789Display::stop() { + if (getLvglDisplay() != nullptr) { + stopLvgl(); + } + + if (esp_lcd_panel_del(panelHandle) != ESP_OK) { + return false; + } + + if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) { + return false; + } + + displayHandle = nullptr; + return true; +} + +bool St7789Display::startLvgl() { uint32_t buffer_size; if (configuration->bufferSize == 0) { buffer_size = configuration->horizontalResolution * configuration->verticalResolution / 10; @@ -120,26 +143,16 @@ bool St7789Display::start() { }; displayHandle = lvgl_port_add_disp(&disp_cfg); - - TT_LOG_I(TAG, "Finished"); return displayHandle != nullptr; } -bool St7789Display::stop() { - assert(displayHandle != nullptr); - - lvgl_port_remove_disp(displayHandle); - - if (esp_lcd_panel_del(panelHandle) != ESP_OK) { +bool St7789Display::stopLvgl() { + if (displayHandle == nullptr) { return false; + } else { + lvgl_port_remove_disp(displayHandle); + return true; } - - if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) { - return false; - } - - displayHandle = nullptr; - return true; } /** diff --git a/Drivers/ST7789/Source/St7789Display.h b/Drivers/ST7789/Source/St7789Display.h index 8296d255..92079e95 100644 --- a/Drivers/ST7789/Source/St7789Display.h +++ b/Drivers/ST7789/Source/St7789Display.h @@ -1,6 +1,8 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include + +#include #include #include @@ -72,27 +74,57 @@ public: assert(configuration != nullptr); } - std::string getName() const final { return "ST7789"; } - std::string getDescription() const final { return "ST7789 display"; } + std::string getName() const override { return "ST7789"; } + std::string getDescription() const override { return "ST7789 display"; } - bool start() final; + bool start() override; - bool stop() final; + bool stop() override; - std::shared_ptr _Nullable createTouch() final { return configuration->touch; } + std::shared_ptr _Nullable createTouch() override { return configuration->touch; } - void setBacklightDuty(uint8_t backlightDuty) final { + void setBacklightDuty(uint8_t backlightDuty) override { if (configuration->backlightDutyFunction != nullptr) { configuration->backlightDutyFunction(backlightDuty); } } - bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; } + bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } - void setGammaCurve(uint8_t index) final; - uint8_t getGammaCurveCount() const final { return 4; }; + void setGammaCurve(uint8_t index) override; + uint8_t getGammaCurveCount() const override { return 4; }; - lv_display_t* _Nullable getLvglDisplay() const final { return displayHandle; } + // region LVGL + + bool supportsLvgl() const override { return true; } + + bool startLvgl() override; + + bool stopLvgl() override; + + lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; } + + // endregion + + // region NativedDisplay + + bool supportsNativeDisplay() const override { return true; } + + std::shared_ptr getNativeDisplay() override { + assert(displayHandle == nullptr); // Still attached to LVGL context. Call stopLvgl() first. + + uint16_t width = configuration->swapXY ? configuration->verticalResolution : configuration->horizontalResolution; + uint16_t height = configuration->swapXY ? configuration->horizontalResolution : configuration->verticalResolution; + + return std::make_shared( + panelHandle, + tt::hal::display::ColorFormat::RGB565, + width, + height + ); + } + + // endregion }; std::shared_ptr createDisplay(); diff --git a/Tactility/Include/Tactility/hal/Device.h b/Tactility/Include/Tactility/hal/Device.h index 0f01fe18..864550ca 100644 --- a/Tactility/Include/Tactility/hal/Device.h +++ b/Tactility/Include/Tactility/hal/Device.h @@ -36,7 +36,7 @@ public: virtual ~Device() = default; /** Unique identifier */ - inline Id getId() const { return id; } + Id getId() const { return id; } /** The type of device */ virtual Type getType() const = 0; diff --git a/Tactility/Include/Tactility/hal/display/DisplayDevice.h b/Tactility/Include/Tactility/hal/display/DisplayDevice.h index ea3080fa..15a4e7a8 100644 --- a/Tactility/Include/Tactility/hal/display/DisplayDevice.h +++ b/Tactility/Include/Tactility/hal/display/DisplayDevice.h @@ -10,12 +10,15 @@ class TouchDevice; namespace tt::hal::display { +class NativeDisplay; + class DisplayDevice : public Device { public: Type getType() const override { return Type::Display; } + /** Starts the driver */ virtual bool start() = 0; virtual bool stop() = 0; @@ -35,6 +38,13 @@ public: /** After start() returns true, this should return a valid pointer until stop() is called and returns true */ virtual lv_display_t* _Nullable getLvglDisplay() const = 0; + + virtual bool supportsLvgl() const { return false; } + virtual bool startLvgl() { return false; } + virtual bool stopLvgl() { return false; } + + virtual bool supportsNativeDisplay() const { return false; } + virtual std::shared_ptr getNativeDisplay() { return nullptr; } }; } // namespace tt::hal::display diff --git a/Tactility/Include/Tactility/hal/display/NativeDisplay.h b/Tactility/Include/Tactility/hal/display/NativeDisplay.h new file mode 100644 index 00000000..1624371c --- /dev/null +++ b/Tactility/Include/Tactility/hal/display/NativeDisplay.h @@ -0,0 +1,24 @@ +#pragma once + +namespace tt::hal::display { + +enum class ColorFormat { + Monochrome, // 1 bpp + BGR565, + RGB565, + RGB888 +}; + +class NativeDisplay { + +public: + + virtual ~NativeDisplay() = default; + + virtual ColorFormat getColorFormat() const = 0; + virtual uint16_t getPixelWidth() const = 0; + virtual uint16_t getPixelHeight() const = 0; + virtual bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) = 0; +}; + +} \ No newline at end of file diff --git a/Tactility/Source/lvgl/Init.cpp b/Tactility/Source/lvgl/Init.cpp index 39a01137..b032c19b 100644 --- a/Tactility/Source/lvgl/Init.cpp +++ b/Tactility/Source/lvgl/Init.cpp @@ -31,9 +31,11 @@ static std::shared_ptr initDisplay(const hal::Confi display->setBacklightDuty(0); } - lv_display_rotation_t rotation = app::display::getRotation(); - if (rotation != lv_display_get_rotation(lv_display_get_default())) { - lv_display_set_rotation(lv_display_get_default(), rotation); + if (display->supportsLvgl() && display->startLvgl()) { + lv_display_rotation_t rotation = app::display::getRotation(); + if (rotation != lv_display_get_rotation(lv_display_get_default())) { + lv_display_set_rotation(lv_display_get_default(), rotation); + } } return display;