diff --git a/.github/workflows/build-firmware.yml b/.github/workflows/build-firmware.yml index c7625f7e..1ccf1c10 100644 --- a/.github/workflows/build-firmware.yml +++ b/.github/workflows/build-firmware.yml @@ -207,3 +207,21 @@ jobs: with: board_id: waveshare-s3-touch-lcd-147 arch: esp32s3 + waveshare-s3-touch-lcd-128: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: "Build" + uses: ./.github/actions/build-firmware + with: + board_id: waveshare-s3-touch-lcd-128 + arch: esp32s3 + waveshare-s3-lcd-13: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: "Build" + uses: ./.github/actions/build-firmware + with: + board_id: waveshare-s3-lcd-13 + arch: esp32s3 diff --git a/App/Kconfig b/App/Kconfig index 18b6ad4d..ad1f7ac0 100644 --- a/App/Kconfig +++ b/App/Kconfig @@ -55,6 +55,10 @@ menu "Tactility App" bool "Waveshare ESP32 S3 Touch LCD 4.3" config TT_BOARD_WAVESHARE_S3_TOUCH_LCD_147 bool "Waveshare ESP32 S3 Touch LCD 1.47" + config TT_BOARD_WAVESHARE_S3_TOUCH_LCD_128 + bool "Waveshare ESP32 S3 Touch LCD 1.28" + config TT_BOARD_WAVESHARE_S3_LCD_13 + bool "Waveshare ESP32 S3 LCD 1.3" help Select a board/hardware configuration. Use TT_BOARD_CUSTOM if you will manually configure the board in your project. diff --git a/App/Source/Boards.h b/App/Source/Boards.h index fbdd4430..c7f4ff89 100644 --- a/App/Source/Boards.h +++ b/App/Source/Boards.h @@ -71,6 +71,12 @@ #elif defined(CONFIG_TT_BOARD_WAVESHARE_S3_TOUCH_LCD_147) #include "WaveshareS3TouchLcd147.h" #define TT_BOARD_HARDWARE &waveshare_s3_touch_lcd_147 +#elif defined(CONFIG_TT_BOARD_WAVESHARE_S3_TOUCH_LCD_128) +#include "WaveshareS3TouchLcd128.h" +#define TT_BOARD_HARDWARE &waveshare_s3_touch_lcd_128 +#elif defined(CONFIG_TT_BOARD_WAVESHARE_S3_LCD_13) +#include "WaveshareS3Lcd13.h" +#define TT_BOARD_HARDWARE &waveshare_s3_lcd_13 #else #define TT_BOARD_HARDWARE NULL #error Replace TT_BOARD_HARDWARE in main.c with your own. Or copy one of the ./sdkconfig.board.* files into ./sdkconfig. diff --git a/App/idf_component.yml b/App/idf_component.yml index f6067125..7911da66 100644 --- a/App/idf_component.yml +++ b/App/idf_component.yml @@ -14,6 +14,7 @@ dependencies: - if: "target in [esp32s3, esp32p4]" espressif/esp_lcd_st7796: version: "1.3.4" + espressif/esp_lcd_gc9a01: "2.0.3" espressif/esp_lcd_panel_io_additions: "1.0.1" espressif/esp_tinyusb: version: "1.7.6~1" diff --git a/Boards/WaveshareS3Lcd13/CMakeLists.txt b/Boards/WaveshareS3Lcd13/CMakeLists.txt new file mode 100644 index 00000000..c3a0c54b --- /dev/null +++ b/Boards/WaveshareS3Lcd13/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCE_FILES Source/*.c*) + +idf_component_register( + SRCS ${SOURCE_FILES} + INCLUDE_DIRS "Source" + REQUIRES Tactility esp_lvgl_port ST7789 CST816S PwmBacklight driver +) diff --git a/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp new file mode 100644 index 00000000..0f78d97e --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp @@ -0,0 +1,94 @@ +#include "devices/Display.h" +#include "devices/SdCard.h" + +#include +#include +#include + +using namespace tt::hal; + +static DeviceVector createDevices() { + return { + createDisplay(), + createSdCard() + }; +} + +static bool initBoot() { + return driver::pwmbacklight::init(GPIO_NUM_20, 256); +} + +extern const Configuration waveshare_s3_lcd_13 = { + .initBoot = initBoot, + .createDevices = createDevices, + .i2c = { + //IMU + i2c::Configuration { + .name = "Main", + .port = I2C_NUM_0, + .initMode = i2c::InitMode::ByTactility, + .isMutable = false, + .config = (i2c_config_t) { + .mode = I2C_MODE_MASTER, + .sda_io_num = GPIO_NUM_47, + .scl_io_num = GPIO_NUM_48, + .sda_pullup_en = true, + .scl_pullup_en = true, + .master = { + .clk_speed = 400000 + }, + .clk_flags = 0 + } + } + }, + .spi { + // Display + spi::Configuration { + .device = SPI2_HOST, + .dma = SPI_DMA_DISABLED, + .config = { + .mosi_io_num = GPIO_NUM_41, + .miso_io_num = GPIO_NUM_NC, + .sclk_io_num = GPIO_NUM_40, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_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 = ((240 * (240 / 10)) * LV_COLOR_DEPTH / 8), + .flags = 0, + .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, + .intr_flags = 0 + }, + .initMode = spi::InitMode::ByTactility, + .isMutable = false, + .lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display + }, + // SD card + spi::Configuration { + .device = SPI3_HOST, + .dma = SPI_DMA_CH_AUTO, + .config = { + .mosi_io_num = GPIO_NUM_18, + .miso_io_num = GPIO_NUM_16, + .sclk_io_num = GPIO_NUM_21, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_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 = 32768, + .flags = 0, + .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, + .intr_flags = 0 + }, + .initMode = spi::InitMode::ByTactility, + .isMutable = false, + .lock = nullptr // No custom lock needed + } + } +}; diff --git a/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.h b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.h new file mode 100644 index 00000000..b3a5c491 --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern const tt::hal::Configuration waveshare_s3_lcd_13; diff --git a/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp b/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp new file mode 100644 index 00000000..d555483c --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp @@ -0,0 +1,27 @@ +#include "Display.h" + +#include +#include + +std::shared_ptr createDisplay() { + + auto configuration = std::make_unique( + SPI2_HOST, + GPIO_NUM_39, + GPIO_NUM_38, + 240, + 240, + nullptr, + false, + false, + false, + true + ); + + + configuration->resetPin = GPIO_NUM_42; + configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; + + auto display = std::make_shared(std::move(configuration)); + return std::reinterpret_pointer_cast(display); +} diff --git a/Boards/WaveshareS3Lcd13/Source/devices/Display.h b/Boards/WaveshareS3Lcd13/Source/devices/Display.h new file mode 100644 index 00000000..b3ce9fb5 --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/devices/Display.h @@ -0,0 +1,5 @@ +#pragma once + +#include "Tactility/hal/display/DisplayDevice.h" + +std::shared_ptr createDisplay(); \ No newline at end of file diff --git a/Boards/WaveshareS3Lcd13/Source/devices/SdCard.cpp b/Boards/WaveshareS3Lcd13/Source/devices/SdCard.cpp new file mode 100644 index 00000000..e0f2c39c --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/devices/SdCard.cpp @@ -0,0 +1,23 @@ +#include "SdCard.h" + +#include +#include + +using tt::hal::sdcard::SpiSdCardDevice; + +std::shared_ptr createSdCard() { + auto configuration = std::make_unique( + GPIO_NUM_17, + GPIO_NUM_NC, + GPIO_NUM_NC, + GPIO_NUM_NC, + SdCardDevice::MountBehaviour::AtBoot, + std::make_shared(tt::Mutex::Type::Recursive), + std::vector(), + SPI3_HOST + ); + + return std::make_shared( + std::move(configuration) + ); +} diff --git a/Boards/WaveshareS3Lcd13/Source/devices/SdCard.h b/Boards/WaveshareS3Lcd13/Source/devices/SdCard.h new file mode 100644 index 00000000..5cb65a73 --- /dev/null +++ b/Boards/WaveshareS3Lcd13/Source/devices/SdCard.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Tactility/hal/sdcard/SdCardDevice.h" + +using tt::hal::sdcard::SdCardDevice; + +std::shared_ptr createSdCard(); diff --git a/Boards/WaveshareS3TouchLcd128/CMakeLists.txt b/Boards/WaveshareS3TouchLcd128/CMakeLists.txt new file mode 100644 index 00000000..875eee8e --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCE_FILES Source/*.c*) + +idf_component_register( + SRCS ${SOURCE_FILES} + INCLUDE_DIRS "Source" + REQUIRES Tactility esp_lvgl_port GC9A01 CST816S PwmBacklight driver +) diff --git a/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.cpp b/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.cpp new file mode 100644 index 00000000..691d0065 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.cpp @@ -0,0 +1,97 @@ +#include "devices/Display.h" +#include "devices/SdCard.h" + +#include +#include +#include + +using namespace tt::hal; + +constexpr auto* TAG = "Waveshare"; + +static DeviceVector createDevices() { + return { + createDisplay(), + createSdCard() + }; +} + +static bool initBoot() { + return driver::pwmbacklight::init(GPIO_NUM_2, 256); +} + +extern const Configuration waveshare_s3_touch_lcd_128 = { + .initBoot = initBoot, + .createDevices = createDevices, + .i2c = { + i2c::Configuration { + .name = "Main", + .port = I2C_NUM_0, + .initMode = i2c::InitMode::ByTactility, + .isMutable = false, + .config = (i2c_config_t) { + .mode = I2C_MODE_MASTER, + .sda_io_num = GPIO_NUM_6, + .scl_io_num = GPIO_NUM_7, + .sda_pullup_en = false, + .scl_pullup_en = false, + .master = { + .clk_speed = 400000 + }, + .clk_flags = 0 + } + } + }, + .spi { + // Display + spi::Configuration { + .device = SPI2_HOST, + .dma = SPI_DMA_DISABLED, + .config = { + .mosi_io_num = GPIO_NUM_11, + .miso_io_num = GPIO_NUM_12, + .sclk_io_num = GPIO_NUM_10, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_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 = ((240 * (240 / 10)) * LV_COLOR_DEPTH / 8), + .flags = 0, + .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, + .intr_flags = 0 + }, + .initMode = spi::InitMode::ByTactility, + .isMutable = false, + .lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display + }, + // SD card available via external sd card module and uses VSYS (5V) / GND / IO15 / IO16 / IO17 / IO18 pins. + // Common micro sd card module you'd find on aliexpress with voltage regulator onboard. Others may work. + // JST SH 1.0 Header, GND / VSYS (5V) / RESET / BOOT / GND / 3.3V / IO15 / IO16 / IO17 / IO18 / IO21 / IO33 + spi::Configuration { + .device = SPI3_HOST, + .dma = SPI_DMA_CH_AUTO, + .config = { + .mosi_io_num = GPIO_NUM_16, + .miso_io_num = GPIO_NUM_15, + .sclk_io_num = GPIO_NUM_17, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_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 = 32768, + .flags = 0, + .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, + .intr_flags = 0 + }, + .initMode = spi::InitMode::ByTactility, + .isMutable = false, + .lock = nullptr // No custom lock needed + } + } +}; diff --git a/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.h b/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.h new file mode 100644 index 00000000..54e24375 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/WaveshareS3TouchLcd128.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern const tt::hal::Configuration waveshare_s3_touch_lcd_128; diff --git a/Boards/WaveshareS3TouchLcd128/Source/devices/Display.cpp b/Boards/WaveshareS3TouchLcd128/Source/devices/Display.cpp new file mode 100644 index 00000000..cb9b2824 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/devices/Display.cpp @@ -0,0 +1,45 @@ +#include "Display.h" + +#include +#include +#include + +std::shared_ptr _Nullable createTouch() { + auto configuration = std::make_unique( + I2C_NUM_0, + 240, + 240, + false, + true, + false, + GPIO_NUM_13, + GPIO_NUM_5 + ); + + return std::make_shared(std::move(configuration)); +} + +std::shared_ptr createDisplay() { + auto touch = createTouch(); + + auto configuration = std::make_unique( + SPI2_HOST, + GPIO_NUM_9, + GPIO_NUM_8, + 240, + 240, + touch, + false, + false, + true, + true, + 0, + LCD_RGB_ELEMENT_ORDER_BGR + ); + + configuration->resetPin = GPIO_NUM_14; + configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; + + auto display = std::make_shared(std::move(configuration)); + return std::reinterpret_pointer_cast(display); +} diff --git a/Boards/WaveshareS3TouchLcd128/Source/devices/Display.h b/Boards/WaveshareS3TouchLcd128/Source/devices/Display.h new file mode 100644 index 00000000..b3ce9fb5 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/devices/Display.h @@ -0,0 +1,5 @@ +#pragma once + +#include "Tactility/hal/display/DisplayDevice.h" + +std::shared_ptr createDisplay(); \ No newline at end of file diff --git a/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.cpp b/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.cpp new file mode 100644 index 00000000..cd0d08a8 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.cpp @@ -0,0 +1,23 @@ +#include "SdCard.h" + +#include +#include + +using tt::hal::sdcard::SpiSdCardDevice; + +std::shared_ptr createSdCard() { + auto configuration = std::make_unique( + GPIO_NUM_18, + GPIO_NUM_NC, + GPIO_NUM_NC, + GPIO_NUM_NC, + SdCardDevice::MountBehaviour::AtBoot, + std::make_shared(tt::Mutex::Type::Recursive), + std::vector(), + SPI3_HOST + ); + + return std::make_shared( + std::move(configuration) + ); +} diff --git a/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.h b/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.h new file mode 100644 index 00000000..5cb65a73 --- /dev/null +++ b/Boards/WaveshareS3TouchLcd128/Source/devices/SdCard.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Tactility/hal/sdcard/SdCardDevice.h" + +using tt::hal::sdcard::SdCardDevice; + +std::shared_ptr createSdCard(); diff --git a/Buildscripts/board.cmake b/Buildscripts/board.cmake index d099f794..d317df60 100644 --- a/Buildscripts/board.cmake +++ b/Buildscripts/board.cmake @@ -65,6 +65,10 @@ function(INIT_TACTILITY_GLOBALS SDKCONFIG_FILE) set(TACTILITY_BOARD_PROJECT WaveshareS3Touch43) elseif (board_id STREQUAL "waveshare-s3-touch-lcd-147") set(TACTILITY_BOARD_PROJECT WaveshareS3TouchLcd147) + elseif (board_id STREQUAL "waveshare-s3-touch-lcd-128") + set(TACTILITY_BOARD_PROJECT WaveshareS3TouchLcd128) + elseif (board_id STREQUAL "waveshare-s3-lcd-13") + set(TACTILITY_BOARD_PROJECT WaveshareS3Lcd13) else () set(TACTILITY_BOARD_PROJECT "") endif () diff --git a/Buildscripts/build-and-release-all.sh b/Buildscripts/build-and-release-all.sh index 6f8ca398..b7609d63 100755 --- a/Buildscripts/build-and-release-all.sh +++ b/Buildscripts/build-and-release-all.sh @@ -81,6 +81,12 @@ release waveshare-s3-touch-43 build waveshare-s3-touch-lcd-147 release waveshare-s3-touch-lcd-147 +build waveshare-s3-touch-lcd-128 +release waveshare-s3-touch-lcd-128 + +build waveshare-s3-lcd-13 +release waveshare-s3-lcd-13 + build unphone release unphone diff --git a/Drivers/GC9A01/CMakeLists.txt b/Drivers/GC9A01/CMakeLists.txt new file mode 100644 index 00000000..4f64a8c1 --- /dev/null +++ b/Drivers/GC9A01/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "Source" + INCLUDE_DIRS "Source" + REQUIRES Tactility driver esp_lcd_gc9a01 EspLcdCompat +) diff --git a/Drivers/GC9A01/README.md b/Drivers/GC9A01/README.md new file mode 100644 index 00000000..4b8db2e7 --- /dev/null +++ b/Drivers/GC9A01/README.md @@ -0,0 +1,3 @@ +# GC9A01 + +A basic ESP32 LVGL driver for GC9A01 displays. diff --git a/Drivers/GC9A01/Source/Gc9a01Display.cpp b/Drivers/GC9A01/Source/Gc9a01Display.cpp new file mode 100644 index 00000000..e6f17f8f --- /dev/null +++ b/Drivers/GC9A01/Source/Gc9a01Display.cpp @@ -0,0 +1,122 @@ +#include "Gc9a01Display.h" + +#include + +#include +#include +#include + +constexpr auto TAG = "GC9A01"; + +bool Gc9a01Display::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { + TT_LOG_I(TAG, "Starting"); + + const esp_lcd_panel_io_spi_config_t panel_io_config = { + .cs_gpio_num = configuration->csPin, + .dc_gpio_num = configuration->dcPin, + .spi_mode = 0, + .pclk_hz = configuration->pixelClockFrequency, + .trans_queue_depth = configuration->transactionQueueDepth, + .on_color_trans_done = nullptr, + .user_ctx = nullptr, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + .cs_ena_pretrans = 0, + .cs_ena_posttrans = 0, + .flags = { + .dc_high_on_cmd = 0, + .dc_low_on_data = 0, + .dc_low_on_param = 0, + .octal_mode = 0, + .quad_mode = 0, + .sio_mode = 0, + .lsb_first = 0, + .cs_high_active = 0 + } + }; + + if (esp_lcd_new_panel_io_spi(configuration->spiHostDevice, &panel_io_config, &outHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create panel"); + return false; + } + + return true; +} + +bool Gc9a01Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) { + const esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = configuration->resetPin, + .rgb_ele_order = configuration->rgbElementOrder, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = 16, + .flags = { + .reset_active_high = false + }, + .vendor_config = nullptr + }; + + if (esp_lcd_new_panel_gc9a01(ioHandle, &panel_config, &panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create panel"); + return false; + } + + if (esp_lcd_panel_reset(panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to reset panel"); + return false; + } + + if (esp_lcd_panel_init(panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to init panel"); + return false; + } + + if (esp_lcd_panel_swap_xy(panelHandle, configuration->swapXY) != ESP_OK) { + TT_LOG_E(TAG, "Failed to swap XY "); + return false; + } + + if (esp_lcd_panel_mirror(panelHandle, configuration->mirrorX, configuration->mirrorY) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to mirror"); + return false; + } + + if (esp_lcd_panel_invert_color(panelHandle, configuration->invertColor) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to invert"); + return false; + } + + if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) { + TT_LOG_E(TAG, "Failed to turn display on"); + return false; + } + + return true; +} + +lvgl_port_display_cfg_t Gc9a01Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { + return lvgl_port_display_cfg_t { + .io_handle = ioHandle, + .panel_handle = panelHandle, + .control_handle = nullptr, + .buffer_size = configuration->bufferSize, + .double_buffer = true, + .trans_size = 0, + .hres = configuration->horizontalResolution, + .vres = configuration->verticalResolution, + .monochrome = false, + .rotation = { + .swap_xy = configuration->swapXY, + .mirror_x = configuration->mirrorX, + .mirror_y = configuration->mirrorY, + }, + .color_format = LV_COLOR_FORMAT_RGB565, + .flags = { + .buff_dma = true, + .buff_spiram = false, + .sw_rotate = false, + .swap_bytes = true, + .full_refresh = false, + .direct_mode = false + } + }; +} diff --git a/Drivers/GC9A01/Source/Gc9a01Display.h b/Drivers/GC9A01/Source/Gc9a01Display.h new file mode 100644 index 00000000..d5dc6478 --- /dev/null +++ b/Drivers/GC9A01/Source/Gc9a01Display.h @@ -0,0 +1,108 @@ +#pragma once + +#include "Tactility/hal/spi/Spi.h" + +#include +#include + +#include +#include +#include +#include +#include + +class Gc9a01Display final : public EspLcdDisplay { + + std::shared_ptr lock; + +public: + + class Configuration { + + public: + + Configuration( + spi_host_device_t spiHostDevice, + gpio_num_t csPin, + gpio_num_t dcPin, + unsigned int horizontalResolution, + unsigned int verticalResolution, + std::shared_ptr touch, + bool swapXY = false, + bool mirrorX = false, + bool mirrorY = false, + bool invertColor = false, + uint32_t bufferSize = 0, // Size in pixel count. 0 means default, which is 1/10 of the screen size + lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB + ) : spiHostDevice(spiHostDevice), + csPin(csPin), + dcPin(dcPin), + horizontalResolution(horizontalResolution), + verticalResolution(verticalResolution), + swapXY(swapXY), + mirrorX(mirrorX), + mirrorY(mirrorY), + invertColor(invertColor), + bufferSize(bufferSize), + rgbElementOrder(rgbElementOrder), + touch(std::move(touch)) + { + if (this->bufferSize == 0) { + this->bufferSize = horizontalResolution * verticalResolution / 10; + } + } + + spi_host_device_t spiHostDevice; + gpio_num_t csPin; + gpio_num_t dcPin; + gpio_num_t resetPin = GPIO_NUM_NC; + unsigned int pixelClockFrequency = 80'000'000; // Hertz + size_t transactionQueueDepth = 10; + unsigned int horizontalResolution; + unsigned int verticalResolution; + bool swapXY = false; + bool mirrorX = false; + bool mirrorY = false; + bool invertColor = false; + uint32_t bufferSize = 0; // Size in pixel count. 0 means default, which is 1/10 of the screen size + lcd_rgb_element_order_t rgbElementOrder; + std::shared_ptr touch; + std::function _Nullable backlightDutyFunction = nullptr; + }; + +private: + + std::unique_ptr configuration; + + bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; + + bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) override; + + lvgl_port_display_cfg_t getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) override; + +public: + + explicit Gc9a01Display(std::unique_ptr inConfiguration) : + EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)), + configuration(std::move(inConfiguration) + ) { + assert(configuration != nullptr); + assert(getLock() != nullptr); + } + + std::string getName() const override { return "GC9A01"; } + + std::string getDescription() const override { return "GC9A01 display"; } + + std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } + + void setBacklightDuty(uint8_t backlightDuty) override { + if (configuration->backlightDutyFunction != nullptr) { + configuration->backlightDutyFunction(backlightDuty); + } + } + + bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } +}; + +std::shared_ptr createDisplay(); diff --git a/sdkconfig.board.waveshare-s3-lcd-13 b/sdkconfig.board.waveshare-s3-lcd-13 new file mode 100644 index 00000000..d2e964e6 --- /dev/null +++ b/sdkconfig.board.waveshare-s3-lcd-13 @@ -0,0 +1,56 @@ +# Software defaults +# Increase stack size for WiFi (fixes crash after scan) +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +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 + +# 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_WAVESHARE_S3_LCD_13=y +CONFIG_TT_BOARD_NAME="Waveshare ESP32 S3 LCD 1.3" +CONFIG_TT_BOARD_ID="waveshare-s3-lcd-13" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_FLASHMODE_QIO=y +# Hardware: SPI RAM +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_120M=y +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# SPI Flash (can set back to 80MHz after ESP-IDF bug is resolved) +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +# LVGL +# TODO: Update DPI +CONFIG_LV_DPI_DEF=143 +CONFIG_LV_DISP_DEF_REFR_PERIOD=10 diff --git a/sdkconfig.board.waveshare-s3-touch-lcd-128 b/sdkconfig.board.waveshare-s3-touch-lcd-128 new file mode 100644 index 00000000..fa2382c9 --- /dev/null +++ b/sdkconfig.board.waveshare-s3-touch-lcd-128 @@ -0,0 +1,56 @@ +# Software defaults +# Increase stack size for WiFi (fixes crash after scan) +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +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 + +# 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_WAVESHARE_S3_TOUCH_LCD_128=y +CONFIG_TT_BOARD_NAME="Waveshare ESP32 S3 Touch LCD 1.28" +CONFIG_TT_BOARD_ID="waveshare-s3-touch-lcd-128" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_FLASHMODE_QIO=y +# Hardware: SPI RAM +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_SPEED_120M=y +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# SPI Flash (can set back to 80MHz after ESP-IDF bug is resolved) +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +# LVGL +# TODO: Update DPI +CONFIG_LV_DPI_DEF=143 +CONFIG_LV_DISP_DEF_REFR_PERIOD=10