diff --git a/Devices/lilygo-thmi-s3/CMakeLists.txt b/Devices/lilygo-thmi-s3/CMakeLists.txt new file mode 100644 index 000000000..5f1b69dcf --- /dev/null +++ b/Devices/lilygo-thmi-s3/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 XPT2046SoftSPI PwmBacklight EstimatedPower ST7789-i8080 driver vfs fatfs +) diff --git a/Devices/lilygo-thmi-s3/Source/Configuration.cpp b/Devices/lilygo-thmi-s3/Source/Configuration.cpp new file mode 100644 index 000000000..817da37e7 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/Configuration.cpp @@ -0,0 +1,24 @@ +#include "devices/Power.h" +#include "devices/SdCard.h" +#include "devices/Display.h" + +#include +#include + +bool initBoot(); + +using namespace tt::hal; + +static std::vector> createDevices() { + return { + createPower(), + createSdCard(), + createDisplay(), + ButtonControl::createOneButtonControl(0) + }; +} + +extern const Configuration hardwareConfiguration = { + .initBoot = initBoot, + .createDevices = createDevices +}; diff --git a/Devices/lilygo-thmi-s3/Source/Init.cpp b/Devices/lilygo-thmi-s3/Source/Init.cpp new file mode 100644 index 000000000..f64d64c37 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/Init.cpp @@ -0,0 +1,47 @@ +#include "devices/Power.h" +#include "devices/Display.h" + +#include "PwmBacklight.h" +#include "Tactility/kernel/SystemEvents.h" +#include + +#define TAG "thmi-s3" + +static bool powerOn() { + gpio_config_t power_signal_config = { + .pin_bit_mask = (1ULL << THMI_S3_POWERON_GPIO) | (1ULL << THMI_S3_POWEREN_GPIO), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + + if (gpio_config(&power_signal_config) != ESP_OK) { + return false; + } + + if (gpio_set_level(THMI_S3_POWERON_GPIO, 1) != ESP_OK) { + return false; + } + + if (gpio_set_level(THMI_S3_POWEREN_GPIO, 1) != ESP_OK) { + return false; + } + + return true; +} + +bool initBoot() { + ESP_LOGI(TAG, "Powering on the board..."); + if (!powerOn()) { + ESP_LOGE(TAG, "Failed to power on the board."); + return false; + } + + if (!driver::pwmbacklight::init(DISPLAY_BL, 30000)) { + ESP_LOGE(TAG, "Failed to initialize backlight."); + return false; + } + + return true; +} \ No newline at end of file diff --git a/Devices/lilygo-thmi-s3/Source/devices/Display.cpp b/Devices/lilygo-thmi-s3/Source/devices/Display.cpp new file mode 100644 index 000000000..73da119d4 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/Display.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include "Display.h" +#include "PwmBacklight.h" +#include "St7789i8080Display.h" + +static bool touchSpiInitialized = false; + +static std::shared_ptr createTouch() { + auto config = std::make_unique( + TOUCH_MOSI_PIN, + TOUCH_MISO_PIN, + TOUCH_SCK_PIN, + TOUCH_CS_PIN, + DISPLAY_HORIZONTAL_RESOLUTION, + DISPLAY_VERTICAL_RESOLUTION + ); + + return std::make_shared(std::move(config)); +} + +std::shared_ptr createDisplay() { + // Create configuration + auto config = St7789i8080Display::Configuration( + DISPLAY_CS, // CS + DISPLAY_DC, // DC + DISPLAY_WR, // WR + DISPLAY_RD, // RD + { DISPLAY_I80_D0, DISPLAY_I80_D1, DISPLAY_I80_D2, DISPLAY_I80_D3, + DISPLAY_I80_D4, DISPLAY_I80_D5, DISPLAY_I80_D6, DISPLAY_I80_D7 }, // D0..D7 + DISPLAY_RST, // RST + DISPLAY_BL // BL + ); + + // Set resolution explicitly + config.horizontalResolution = DISPLAY_HORIZONTAL_RESOLUTION; + config.verticalResolution = DISPLAY_VERTICAL_RESOLUTION; + config.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; + config.touch = createTouch(); + config.invertColor = false; + + auto display = std::make_shared(config); + return display; +} diff --git a/Devices/lilygo-thmi-s3/Source/devices/Display.h b/Devices/lilygo-thmi-s3/Source/devices/Display.h new file mode 100644 index 000000000..2ea592bbf --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/Display.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include + +#include "driver/spi_common.h" + +class St7789i8080Display; + +constexpr auto DISPLAY_CS = GPIO_NUM_6; +constexpr auto DISPLAY_DC = GPIO_NUM_7; +constexpr auto DISPLAY_WR = GPIO_NUM_8; +constexpr auto DISPLAY_RD = GPIO_NUM_NC; +constexpr auto DISPLAY_RST = GPIO_NUM_NC; +constexpr auto DISPLAY_BL = GPIO_NUM_38; +constexpr auto DISPLAY_I80_D0 = GPIO_NUM_48; +constexpr auto DISPLAY_I80_D1 = GPIO_NUM_47; +constexpr auto DISPLAY_I80_D2 = GPIO_NUM_39; +constexpr auto DISPLAY_I80_D3 = GPIO_NUM_40; +constexpr auto DISPLAY_I80_D4 = GPIO_NUM_41; +constexpr auto DISPLAY_I80_D5 = GPIO_NUM_42; +constexpr auto DISPLAY_I80_D6 = GPIO_NUM_45; +constexpr auto DISPLAY_I80_D7 = GPIO_NUM_46; +constexpr auto DISPLAY_HORIZONTAL_RESOLUTION = 240; +constexpr auto DISPLAY_VERTICAL_RESOLUTION = 320; + +// Touch (XPT2046, resistive, shared SPI with display) +constexpr auto TOUCH_MISO_PIN = GPIO_NUM_4; +constexpr auto TOUCH_MOSI_PIN = GPIO_NUM_3; +constexpr auto TOUCH_SCK_PIN = GPIO_NUM_1; +constexpr auto TOUCH_CS_PIN = GPIO_NUM_2; +constexpr auto TOUCH_IRQ_PIN = GPIO_NUM_9; + +// Factory function for registration +std::shared_ptr createDisplay(); diff --git a/Devices/lilygo-thmi-s3/Source/devices/Power.cpp b/Devices/lilygo-thmi-s3/Source/devices/Power.cpp new file mode 100644 index 000000000..febacad19 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/Power.cpp @@ -0,0 +1,12 @@ +#include "Power.h" + +#include +#include + +std::shared_ptr createPower() { + ChargeFromAdcVoltage::Configuration configuration; + // 2.0 ratio, but +.11 added as display voltage sag compensation. + configuration.adcMultiplier = 2.11; + + return std::make_shared(configuration); +} \ No newline at end of file diff --git a/Devices/lilygo-thmi-s3/Source/devices/Power.h b/Devices/lilygo-thmi-s3/Source/devices/Power.h new file mode 100644 index 000000000..f54de9355 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/Power.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +#include + +constexpr auto THMI_S3_POWEREN_GPIO = GPIO_NUM_10; +constexpr auto THMI_S3_POWERON_GPIO = GPIO_NUM_14; + +std::shared_ptr createPower(); diff --git a/Devices/lilygo-thmi-s3/Source/devices/SdCard.cpp b/Devices/lilygo-thmi-s3/Source/devices/SdCard.cpp new file mode 100644 index 000000000..03137e90b --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/SdCard.cpp @@ -0,0 +1,23 @@ +#include "SdCard.h" + +#include +#include + +using tt::hal::sdcard::SdmmcDevice; + +std::shared_ptr createSdCard() { + auto configuration = std::make_unique( + SD_DIO_SCLK, //CLK + SD_DIO_CMD, //CMD + SD_DIO_DATA0, //D0 + SD_DIO_NC, //D1 + SD_DIO_NC, //D2 + SD_DIO_NC, //D3 + SdCardDevice::MountBehaviour::AtBoot, + SD_DIO_BUS_WIDTH + ); + + return std::make_shared( + std::move(configuration) + ); +} diff --git a/Devices/lilygo-thmi-s3/Source/devices/SdCard.h b/Devices/lilygo-thmi-s3/Source/devices/SdCard.h new file mode 100644 index 000000000..ab4ec439f --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/devices/SdCard.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include "Tactility/hal/sdcard/SdCardDevice.h" + +using tt::hal::sdcard::SdCardDevice; + +constexpr auto SD_DIO_CMD = GPIO_NUM_11; +constexpr auto SD_DIO_SCLK = GPIO_NUM_12; +constexpr auto SD_DIO_DATA0 = GPIO_NUM_13; +constexpr auto SD_DIO_NC = GPIO_NUM_NC; +constexpr auto SD_DIO_BUS_WIDTH = 1; + +std::shared_ptr createSdCard(); \ No newline at end of file diff --git a/Devices/lilygo-thmi-s3/Source/module.cpp b/Devices/lilygo-thmi-s3/Source/module.cpp new file mode 100644 index 000000000..5952d11b1 --- /dev/null +++ b/Devices/lilygo-thmi-s3/Source/module.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { + +static error_t start() { + // Empty for now + return ERROR_NONE; +} + +static error_t stop() { + // Empty for now + return ERROR_NONE; +} + +/** @warning The variable name must be exactly "device_module" */ +struct Module device_module = { + .name = "lilygo-thmi-s3", + .start = start, + .stop = stop, + .symbols = nullptr, + .internal = nullptr +}; + +} diff --git a/Devices/lilygo-thmi-s3/device.properties b/Devices/lilygo-thmi-s3/device.properties new file mode 100644 index 000000000..9e70d045c --- /dev/null +++ b/Devices/lilygo-thmi-s3/device.properties @@ -0,0 +1,23 @@ +[general] +vendor=LilyGO +name=T-HMI S3 + +[apps] +launcherAppId=Launcher + +[hardware] +target=ESP32S3 +flashSize=16MB +spiRam=true +spiRamMode=OCT +spiRamSpeed=120M +tinyUsb=true +esptoolFlashFreq=120M + +[display] +size=2.8" +shape=rectangle +dpi=125 + +[lvgl] +colorDepth=16 diff --git a/Devices/lilygo-thmi-s3/devicetree.yaml b/Devices/lilygo-thmi-s3/devicetree.yaml new file mode 100644 index 000000000..0474b6950 --- /dev/null +++ b/Devices/lilygo-thmi-s3/devicetree.yaml @@ -0,0 +1,3 @@ +dependencies: + - Platforms/platform-esp32 +dts: lilygo,thmi-s3.dts diff --git a/Devices/lilygo-thmi-s3/lilygo,thmi-s3.dts b/Devices/lilygo-thmi-s3/lilygo,thmi-s3.dts new file mode 100644 index 000000000..8bc85203a --- /dev/null +++ b/Devices/lilygo-thmi-s3/lilygo,thmi-s3.dts @@ -0,0 +1,16 @@ +/dts-v1/; + +#include +#include +#include +#include + +/ { + compatible = "root"; + model = "LilyGO T-HMI S3"; + + gpio0 { + compatible = "espressif,esp32-gpio"; + gpio-count = <49>; + }; +}; diff --git a/changes.diff b/changes.diff new file mode 100644 index 000000000..e69de29bb