From 0d8c0a37cc3b84f5e4126bb6e92ce8ed107837d4 Mon Sep 17 00:00:00 2001 From: Shadowtrance Date: Mon, 3 Nov 2025 01:56:03 +1000 Subject: [PATCH] LilyGo T-Display (#406) + expose lvglSwapBytes setting for the St7789Display driver. + updated all relevant boards accordingly. --- .github/workflows/build-firmware.yml | 1 + .../Source/devices/Display.cpp | 3 +- Boards/cyd-e32r32p/Source/devices/Display.cpp | 1 + .../Source/devices/Display.cpp | 3 +- .../Source/devices/Display.cpp | 3 +- .../lilygo-tdeck/Source/devices/Display.cpp | 3 +- Boards/lilygo-tdisplay/CMakeLists.txt | 7 +++ .../lilygo-tdisplay/Source/Configuration.cpp | 50 +++++++++++++++++ .../Source/devices/Display.cpp | 32 +++++++++++ .../lilygo-tdisplay/Source/devices/Display.h | 19 +++++++ .../Source/devices/Display.cpp | 3 +- .../Source/devices/Display.cpp | 3 +- .../Source/devices/Display.cpp | 3 +- .../Source/devices/Display.cpp | 3 +- .../Source/devices/Display.cpp | 3 +- Buildscripts/CDN/devices.properties | 5 ++ Drivers/ST7789/Source/St7789Display.cpp | 2 +- Drivers/ST7789/Source/St7789Display.h | 1 + Firmware/Kconfig | 2 + sdkconfig.board.lilygo-tdisplay | 56 +++++++++++++++++++ 20 files changed, 193 insertions(+), 10 deletions(-) create mode 100644 Boards/lilygo-tdisplay/CMakeLists.txt create mode 100644 Boards/lilygo-tdisplay/Source/Configuration.cpp create mode 100644 Boards/lilygo-tdisplay/Source/devices/Display.cpp create mode 100644 Boards/lilygo-tdisplay/Source/devices/Display.h create mode 100644 sdkconfig.board.lilygo-tdisplay diff --git a/.github/workflows/build-firmware.yml b/.github/workflows/build-firmware.yml index 99c49d10..d240760f 100644 --- a/.github/workflows/build-firmware.yml +++ b/.github/workflows/build-firmware.yml @@ -35,6 +35,7 @@ jobs: { id: lilygo-tdongle-s3, arch: esp32s3 }, { id: lilygo-tdisplay-s3, arch: esp32s3 }, { id: lilygo-tlora-pager, arch: esp32s3 }, + { id: lilygo-tdisplay, arch: esp32 }, { id: m5stack-cardputer, arch: esp32s3 }, { id: m5stack-cardputer-adv, arch: esp32s3 }, { id: m5stack-core2, arch: esp32 }, diff --git a/Boards/cyd-2432s028rv3/Source/devices/Display.cpp b/Boards/cyd-2432s028rv3/Source/devices/Display.cpp index 7a9c9484..8948885c 100644 --- a/Boards/cyd-2432s028rv3/Source/devices/Display.cpp +++ b/Boards/cyd-2432s028rv3/Source/devices/Display.cpp @@ -34,7 +34,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = createTouch(), .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = GPIO_NUM_NC + .resetPin = GPIO_NUM_NC, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/cyd-e32r32p/Source/devices/Display.cpp b/Boards/cyd-e32r32p/Source/devices/Display.cpp index 506133d5..2371943a 100644 --- a/Boards/cyd-e32r32p/Source/devices/Display.cpp +++ b/Boards/cyd-e32r32p/Source/devices/Display.cpp @@ -35,6 +35,7 @@ std::shared_ptr createDisplay() { .touch = createTouch(), .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, .resetPin = GPIO_NUM_NC, + .lvglSwapBytes = false, .rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR // BGR for this display }; diff --git a/Boards/cyd-jc2432w328c/Source/devices/Display.cpp b/Boards/cyd-jc2432w328c/Source/devices/Display.cpp index 64018d02..1cb7d189 100644 --- a/Boards/cyd-jc2432w328c/Source/devices/Display.cpp +++ b/Boards/cyd-jc2432w328c/Source/devices/Display.cpp @@ -27,7 +27,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = createTouch(), .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = GPIO_NUM_NC + .resetPin = GPIO_NUM_NC, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/elecrow-crowpanel-advance-28/Source/devices/Display.cpp b/Boards/elecrow-crowpanel-advance-28/Source/devices/Display.cpp index 6d0d984e..1b79ebb0 100644 --- a/Boards/elecrow-crowpanel-advance-28/Source/devices/Display.cpp +++ b/Boards/elecrow-crowpanel-advance-28/Source/devices/Display.cpp @@ -31,7 +31,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = createTouch(), .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = GPIO_NUM_NC + .resetPin = GPIO_NUM_NC, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/lilygo-tdeck/Source/devices/Display.cpp b/Boards/lilygo-tdeck/Source/devices/Display.cpp index a724b59d..275654b0 100644 --- a/Boards/lilygo-tdeck/Source/devices/Display.cpp +++ b/Boards/lilygo-tdeck/Source/devices/Display.cpp @@ -31,7 +31,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = createTouch(), .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = GPIO_NUM_NC + .resetPin = GPIO_NUM_NC, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/lilygo-tdisplay/CMakeLists.txt b/Boards/lilygo-tdisplay/CMakeLists.txt new file mode 100644 index 00000000..4e7c077a --- /dev/null +++ b/Boards/lilygo-tdisplay/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCE_FILES Source/*.c*) + +idf_component_register( + SRCS ${SOURCE_FILES} + INCLUDE_DIRS "Source" + REQUIRES Tactility ButtonControl esp_lvgl_port ST7789 PwmBacklight driver +) diff --git a/Boards/lilygo-tdisplay/Source/Configuration.cpp b/Boards/lilygo-tdisplay/Source/Configuration.cpp new file mode 100644 index 00000000..125bf3e5 --- /dev/null +++ b/Boards/lilygo-tdisplay/Source/Configuration.cpp @@ -0,0 +1,50 @@ +#include "devices/Display.h" + +#include +#include +#include +#include + +using namespace tt::hal; + +static bool initBoot() { + return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT); +} + +static std::vector> createDevices() { + return { + createDisplay(), + ButtonControl::createTwoButtonControl(35, 0) + }; +} + +extern const Configuration hardwareConfiguration = { + .initBoot = initBoot, + .uiScale = UiScale::Smallest, + .createDevices = createDevices, + .i2c = {}, + .spi { + spi::Configuration { + .device = SPI2_HOST, + .dma = SPI_DMA_CH_AUTO, + .config = { + .mosi_io_num = GPIO_NUM_19, + .miso_io_num = GPIO_NUM_NC, + .sclk_io_num = GPIO_NUM_18, + .quadwp_io_num = GPIO_NUM_NC, + .data4_io_num = GPIO_NUM_NC, + .data5_io_num = GPIO_NUM_NC, + .data6_io_num = GPIO_NUM_NC, + .data7_io_num = GPIO_NUM_NC, + .data_io_default_level = false, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, + .flags = 0, + .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, + .intr_flags = 0 + }, + .initMode = spi::InitMode::ByTactility, + .isMutable = false, + .lock = tt::lvgl::getSyncLock() + } + } +}; diff --git a/Boards/lilygo-tdisplay/Source/devices/Display.cpp b/Boards/lilygo-tdisplay/Source/devices/Display.cpp new file mode 100644 index 00000000..45069b35 --- /dev/null +++ b/Boards/lilygo-tdisplay/Source/devices/Display.cpp @@ -0,0 +1,32 @@ +#include "Display.h" + +#include +#include + +std::shared_ptr createDisplay() { + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 52, + .gapY = 40, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = nullptr, + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = LCD_PIN_RESET, + .lvglSwapBytes = true + }; + + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 62'500'000, + .transactionQueueDepth = 10 + }); + + return std::make_shared(panel_configuration, spi_configuration); +} \ No newline at end of file diff --git a/Boards/lilygo-tdisplay/Source/devices/Display.h b/Boards/lilygo-tdisplay/Source/devices/Display.h new file mode 100644 index 00000000..a11933b3 --- /dev/null +++ b/Boards/lilygo-tdisplay/Source/devices/Display.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include +#include + +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_5; +constexpr auto LCD_PIN_DC = GPIO_NUM_16; +constexpr auto LCD_PIN_RESET = GPIO_NUM_23; +constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_4; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 135; +constexpr auto LCD_VERTICAL_RESOLUTION = 240; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 3; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; + +std::shared_ptr createDisplay(); diff --git a/Boards/m5stack-cardputer-adv/Source/devices/Display.cpp b/Boards/m5stack-cardputer-adv/Source/devices/Display.cpp index 45c002e7..1af30732 100644 --- a/Boards/m5stack-cardputer-adv/Source/devices/Display.cpp +++ b/Boards/m5stack-cardputer-adv/Source/devices/Display.cpp @@ -16,7 +16,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = nullptr, .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = LCD_PIN_RESET + .resetPin = LCD_PIN_RESET, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/m5stack-cardputer/Source/devices/Display.cpp b/Boards/m5stack-cardputer/Source/devices/Display.cpp index 45c002e7..1af30732 100644 --- a/Boards/m5stack-cardputer/Source/devices/Display.cpp +++ b/Boards/m5stack-cardputer/Source/devices/Display.cpp @@ -16,7 +16,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = nullptr, .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = LCD_PIN_RESET + .resetPin = LCD_PIN_RESET, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/m5stack-stickc-plus/Source/devices/Display.cpp b/Boards/m5stack-stickc-plus/Source/devices/Display.cpp index 801db69d..c05719ff 100644 --- a/Boards/m5stack-stickc-plus/Source/devices/Display.cpp +++ b/Boards/m5stack-stickc-plus/Source/devices/Display.cpp @@ -50,7 +50,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = nullptr, .backlightDutyFunction = setBrightness, - .resetPin = LCD_PIN_RESET + .resetPin = LCD_PIN_RESET, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/m5stack-stickc-plus2/Source/devices/Display.cpp b/Boards/m5stack-stickc-plus2/Source/devices/Display.cpp index f4573233..5b732b06 100644 --- a/Boards/m5stack-stickc-plus2/Source/devices/Display.cpp +++ b/Boards/m5stack-stickc-plus2/Source/devices/Display.cpp @@ -16,7 +16,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = nullptr, .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = LCD_PIN_RESET + .resetPin = LCD_PIN_RESET, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Boards/waveshare-s3-lcd-13/Source/devices/Display.cpp b/Boards/waveshare-s3-lcd-13/Source/devices/Display.cpp index f72283ac..97d92f76 100644 --- a/Boards/waveshare-s3-lcd-13/Source/devices/Display.cpp +++ b/Boards/waveshare-s3-lcd-13/Source/devices/Display.cpp @@ -16,7 +16,8 @@ std::shared_ptr createDisplay() { .bufferSize = LCD_BUFFER_SIZE, .touch = nullptr, .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, - .resetPin = GPIO_NUM_42 + .resetPin = GPIO_NUM_42, + .lvglSwapBytes = false }; auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { diff --git a/Buildscripts/CDN/devices.properties b/Buildscripts/CDN/devices.properties index 3ce37b97..9d5a2519 100644 --- a/Buildscripts/CDN/devices.properties +++ b/Buildscripts/CDN/devices.properties @@ -92,6 +92,11 @@ boardName=T-Deck,T-Deck Plus incubating=false infoMessage=If two serial devices are visible, try them both.

To put the device into bootloader mode:
1. Press the trackball and then the reset button at the same time,
2. Let go of the reset button, then the trackball.

When this website reports that flashing is finished, you likely have to press the reset button. +[lilygo-tdisplay] +vendor=LilyGO +boardName=T-Display +incubating=true + [lilygo-tdisplay-s3] vendor=LilyGO boardName=T-Display S3 diff --git a/Drivers/ST7789/Source/St7789Display.cpp b/Drivers/ST7789/Source/St7789Display.cpp index 260073a1..05c4ea52 100644 --- a/Drivers/ST7789/Source/St7789Display.cpp +++ b/Drivers/ST7789/Source/St7789Display.cpp @@ -18,7 +18,7 @@ std::shared_ptr St7789Display::createEspLcdConfiguration(co .backlightDutyFunction = configuration.backlightDutyFunction, .resetPin = configuration.resetPin, .lvglColorFormat = LV_COLOR_FORMAT_RGB565, - .lvglSwapBytes = false, + .lvglSwapBytes = configuration.lvglSwapBytes, .rgbElementOrder = configuration.rgbElementOrder, .bitsPerPixel = 16, }); diff --git a/Drivers/ST7789/Source/St7789Display.h b/Drivers/ST7789/Source/St7789Display.h index 32a14240..79bca3bd 100644 --- a/Drivers/ST7789/Source/St7789Display.h +++ b/Drivers/ST7789/Source/St7789Display.h @@ -26,6 +26,7 @@ public: std::shared_ptr touch; std::function _Nullable backlightDutyFunction; gpio_num_t resetPin; + bool lvglSwapBytes; lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB; }; diff --git a/Firmware/Kconfig b/Firmware/Kconfig index 7c84d55a..0cf9c635 100644 --- a/Firmware/Kconfig +++ b/Firmware/Kconfig @@ -49,6 +49,8 @@ menu "Tactility App" bool "LilyGo T-Dongle S3" config TT_BOARD_LILYGO_TLORA_PAGER bool "LilyGo T-Lora Pager" + config TT_BOARD_LILYGO_TDISPLAY + bool "LilyGo T-Display" config TT_BOARD_M5STACK_CARDPUTER bool "M5Stack Cardputer" config TT_BOARD_M5STACK_CARDPUTER_ADV diff --git a/sdkconfig.board.lilygo-tdisplay b/sdkconfig.board.lilygo-tdisplay new file mode 100644 index 00000000..fa2149de --- /dev/null +++ b/sdkconfig.board.lilygo-tdisplay @@ -0,0 +1,56 @@ +# Software defaults +# Increase stack size for WiFi (fixes crash after scan) +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144 +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_FONT_MONTSERRAT_18=y +CONFIG_LV_USE_USER_DATA=y +CONFIG_LV_USE_FS_STDIO=y +CONFIG_LV_FS_STDIO_LETTER=65 +CONFIG_LV_FS_STDIO_PATH="" +CONFIG_LV_FS_STDIO_CACHE_SIZE=4096 +CONFIG_LV_USE_LODEPNG=y +CONFIG_LV_USE_BUILTIN_MALLOC=n +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_MSGBOX=n +CONFIG_LV_USE_SPINNER=n +CONFIG_LV_USE_WIN=n +CONFIG_LV_USE_SNAPSHOT=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 +CONFIG_FREERTOS_SMP=n +CONFIG_FREERTOS_UNICORE=n +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=5120 +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FATFS_LFN_HEAP=y +CONFIG_FATFS_VOLUME_COUNT=3 +CONFIG_FATFS_SECTOR_512=y +CONFIG_WL_SECTOR_SIZE_512=y +CONFIG_WL_SECTOR_SIZE=512 +CONFIG_WL_SECTOR_MODE_SAFE=y +CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y + +# Hardware: Main +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16mb.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions-16mb.csv" +CONFIG_TT_BOARD_LILYGO_TDISPLAY=y +CONFIG_TT_BOARD_NAME="LilyGo T-Display" +CONFIG_TT_BOARD_ID="lilygo-tdisplay" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_IDF_TARGET="esp32" +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_FLASHMODE_QIO=y +# LVGL +CONFIG_LV_DISP_DEF_REFR_PERIOD=10 +CONFIG_LV_DPI_DEF=186 +CONFIG_LV_THEME_DEFAULT_DARK=y +# Fix for IRAM +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH=y +CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y \ No newline at end of file