From 6366765162799f5e8ddcc3531924be4445cc1c38 Mon Sep 17 00:00:00 2001 From: Thomas Langewouters Date: Thu, 16 Oct 2025 09:34:39 +0200 Subject: [PATCH 1/2] Add initial Lilygo T-RGB-2.8 support This is a round 2.8" IPS TFT with capacitive touch. Non conclusive list of known issues: * The screen is distorted when WiFi throughput is high. * When connected to a power only USB cable, the screen remains black until the device is reflashed --- src/drv/tft/tft_driver_arduinogfx.cpp | 148 +++++++++++++++++- .../esp32s3/esp32-s3-lilygo-t-rgb-2.8.ini | 92 +++++++++++ 2 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 user_setups/esp32s3/esp32-s3-lilygo-t-rgb-2.8.ini diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp index 7170464e8..085f8132a 100644 --- a/src/drv/tft/tft_driver_arduinogfx.cpp +++ b/src/drv/tft/tft_driver_arduinogfx.cpp @@ -8,7 +8,132 @@ #include "Arduino_RGBPanel_mod.h" #include "Arduino_RGB_Display_mod.h" #include "Arduino_PCA9535SWSPI.h" - +#if defined(ST7701_TRGB_28) +/* sequence from the T-RGB 2.8 SDK */ +const uint8_t st7701_type9_init_operations_trgb28[297] = { + BEGIN_WRITE, + + WRITE_COMMAND_8, 0xFF, + WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x13, + + WRITE_C8_D8, 0xEF, 0x08, + + WRITE_COMMAND_8, 0xFF, + WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x10, + + WRITE_C8_D16, 0xC0, 0x3B, 0x00, + WRITE_C8_D16, 0xC1, 0x10, 0x0C, + WRITE_C8_D16, 0xC2, 0x07, 0x0A, + WRITE_C8_D8, 0xC7, 0x00, + WRITE_C8_D8, 0xC7, 0x10, + WRITE_C8_D8, 0xCD, 0x08, + + WRITE_COMMAND_8, 0xB0, // Positive Voltage Gamma Control + WRITE_BYTES, 16, + 0x05, 0x12, 0x98, 0x0e, 0x0F, + 0x07, 0x07, 0x09, 0x09, 0x23, + 0x05, 0x52, 0x0F, 0x67, 0x2C, + 0x11, + + + + WRITE_COMMAND_8, 0xB1, // Negative Voltage Gamma Control + WRITE_BYTES, 16, + 0x0B, 0x11, 0x97, 0x0C, 0x12, + 0x06, 0x06, 0x08, 0x08, 0x22, + 0x03, 0x51, 0x11, 0x66, 0x2B, + 0x0F, + + WRITE_COMMAND_8, 0xFF, + WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x11, + + WRITE_C8_D8, 0xB0, 0x5D, + WRITE_C8_D8, 0xB1, 0x2D, + WRITE_C8_D8, 0xB2, 0x81, + WRITE_C8_D8, 0xB3, 0x80, + WRITE_C8_D8, 0xB5, 0x4E, + WRITE_C8_D8, 0xB7, 0x85, + WRITE_C8_D8, 0xB8, 0x20, + WRITE_C8_D8, 0xC1, 0x78, + WRITE_C8_D8, 0xC2, 0x78, + + WRITE_C8_D8, 0xD0, 0x88, + + WRITE_COMMAND_8, 0xE0, + WRITE_BYTES, 4, + 0x00, 0x00, 0x02, + + WRITE_COMMAND_8, 0xE1, + WRITE_BYTES, 16, + 0x06, 0x30, 0x08, 0x30, 0x05, + 0x30, 0x07, 0x30, 0x00, 0x33, + 0x33, + + WRITE_COMMAND_8, 0xE2, + WRITE_BYTES, 16, + 0x11, 0x11, 0x33, 0x33, 0xf4, + 0x00, 0x00, 0x00, 0xf4, 0x00, + 0x00, 0x00, + + WRITE_COMMAND_8, 0xE3, + WRITE_BYTES, 4, 0x00, 0x00, 0x11, 0x11, + + WRITE_C8_D16, 0xE4, 0x44, 0x44, + + WRITE_COMMAND_8, 0xE5, + WRITE_BYTES, 16, + 0x0d, 0xf5, 0x30, 0xf0, 0x0f, + 0xf7, 0x30, 0xf0, 0x09, 0xf1, + 0x30, 0xf0, 0x0b, 0xf3, 0x30, 0xf0, + + WRITE_COMMAND_8, 0xE6, + WRITE_BYTES, 4, 0x00, 0x00, 0x11, 0x11, + + WRITE_C8_D16, 0xE7, 0x44, 0x44, + + WRITE_COMMAND_8, 0xE8, + WRITE_BYTES, 16, + 0x0c, 0xf4, 0x30, 0xf0, + 0x0e, 0xf6, 0x30, 0xf0, + 0x08, 0xf0, 0x30, 0xf0, + 0x0a, 0xf2, 0x30, 0xf0, + + WRITE_C8_D8, 0xe9, 0x36, + + WRITE_COMMAND_8, 0xEB, + WRITE_BYTES, 7, + 0x00, 0x01, 0xe4, 0xe4, + 0x44, 0x88, 0x40, + + WRITE_COMMAND_8, 0xED, + WRITE_BYTES, 16, + 0xff, 0x10, 0xaf, 0x76, + 0x54, 0x2b, 0xcf, 0xff, + 0xff, 0xfc, 0xb2, 0x45, + 0x67, 0xfa, 0x01, 0xff, + + WRITE_COMMAND_8, 0xEF, + WRITE_BYTES, 6, + 0x08, 0x08, 0x08, 0x45, + 0x3f, 0x54, + + WRITE_COMMAND_8, 0xFF, + WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x00, + + WRITE_COMMAND_8, 0x11, // Sleep Out + END_WRITE, + + DELAY, 150, + + BEGIN_WRITE, + WRITE_C8_D8, 0x3A, 0x66, + WRITE_C8_D8, 0x36, 0x08, + WRITE_C8_D8, 0x35, 0x00, + WRITE_COMMAND_8, 0x29, // Display On + END_WRITE, + DELAY, 20 +}; +#endif namespace dev { void tftPinInfo(const __FlashStringHelper* pinfunction, int8_t pin) @@ -106,6 +231,25 @@ void ArduinoGfx::init(int w, int h) st7701_4848S040_init_operations, sizeof(st7701_4848S040_init_operations)); tft->begin(GFX_NOT_DEFINED); // Used for RFB displays + +#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) && defined(ST7701_TRGB_28) + /* SPI to the TFT is done over an I2C port expander */ + Arduino_DataBus *bus = new Arduino_XL9535SWSPI(8 /* SDA */, 48 /* SCL */, 2 /* XL PWD */, 3 /* XL CS */, 5 /* XL SCK */, 4 /* XL MOSI */); + + Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel( + 45 /* DE */, 41 /* VSYNC */, 47 /* HSYNC */, 42 /* PCLK */, + 21 /* R0 */, 18 /* R1 */, 17 /* R2 */, 16 /* R3 */, 15 /* R4 */, + 14 /* G0 */, 13 /* G1 */, 12 /* G2 */, 11 /* G3 */, 10 /* G4 */, 9 /* G5 */, + 7 /* B0 */, 6 /* B1 */, 5 /* B2 */, 3 /* B3 */, 2 /* B4 */, + 1 /* hsync_polarity */, 50 /* hsync_front_porch */, 1 /* hsync_pulse_width */, 30 /* hsync_back_porch */, + 1 /* vsync_polarity */, 20 /* vsync_front_porch */, 1 /* vsync_pulse_width */, 30 /* vsync_back_porch */, + 1 /* pclk_active_neg */); + + tft = new Arduino_RGB_Display( + 480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */, + bus, GFX_NOT_DEFINED /* RST */, st7701_type9_init_operations_trgb28, sizeof(st7701_type9_init_operations_trgb28)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays + #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) /* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */ Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); @@ -494,4 +638,4 @@ uint32_t ArduinoGfx::get_tft_driver() } // namespace dev dev::ArduinoGfx haspTft; -#endif \ No newline at end of file +#endif diff --git a/user_setups/esp32s3/esp32-s3-lilygo-t-rgb-2.8.ini b/user_setups/esp32s3/esp32-s3-lilygo-t-rgb-2.8.ini new file mode 100644 index 000000000..e6d957ffc --- /dev/null +++ b/user_setups/esp32s3/esp32-s3-lilygo-t-rgb-2.8.ini @@ -0,0 +1,92 @@ +;***************************************************; +; Lilygo T-RGB 2.8 ; +; - Custom esp32-s3 board ; +; - round st7701s TFT ; +; - TFT SPI control is over I2C expander ; +; - gt911 touch controller ; +;***************************************************; + +[esp32-s3-lilygo-t-rgb-28] +extends = arduino_esp32s3_v2 +board = esp32-s3-devkitc-1 +board_build.arduino.memory_type = qio_opi + +build_flags = + -D HASP_MODEL="ESP32-S3 T-RGB-2.8" + ${arduino_esp32s3_v2.build_flags} + ${esp32s3.ps_ram} +; -DARDUINO_USB_CDC_ON_BOOT +; -DUSE_USB_CDC_CONSOLE + +;region -- ArduinoGFX build options ------------------------ + -D HASP_USE_ARDUINOGFX=1 + -D ST7701_DRIVER=1 + -D ST7701_TRGB_28=1 + -D TFT_WIDTH=480 + -D TFT_HEIGHT=480 + ; Bus Settings + -D TFT_CS=-1 + -D TFT_SCLK=-1 + -D TFT_MOSI=-1 + -D TFT_DE=45 + -D TFT_VSYNC=41 + -D TFT_HSYNC=47 + -D TFT_PCLK=42 + -D TFT_R0=21 + -D TFT_R1=18 + -D TFT_R2=17 + -D TFT_R3=16 + -D TFT_R4=15 + -D TFT_G0=14 + -D TFT_G1=13 + -D TFT_G2=12 + -D TFT_G3=11 + -D TFT_G4=10 + -D TFT_G5=9 + -D TFT_B0=7 + -D TFT_B1=6 + -D TFT_B2=5 + -D TFT_B3=3 + -D TFT_B4=2 + -D TFT_DC=-1 + -D TFT_MISO=-1 + -D TFT_RST=-1 + -D TFT_BUSY=-1 + -D TFT_BCKL=46 + -D BACKLIGHT_FREQUENCY=100 + ; Panel Settings +; -D TFT_HSYNC_POLARITY=1 + -D TFT_HSYNC_FRONT_PORCH=10 + -D TFT_HSYNC_PULSE_WIDTH=8 + -D TFT_HSYNC_BACK_PORCH=50 + -D TFT_VSYNC_POLARITY=1 + -D TFT_VSYNC_FRONT_PORCH=10 + -D TFT_VSYNC_PULSE_WIDTH=8 + -D TFT_VSYNC_BACK_PORCH=20 + -D TFT_PCLK_ACTIVE_NEG=1 + -D TFT_PREFER_SPEED=12000000 + -D TFT_AUTO_FLUSH=1 + ; Touch Settings + -D TOUCH_DRIVER=0x911 + -D TOUCH_WIDTH=480 + -D TOUCH_HEIGHT=480 + -D TOUCH_SDA=8 + -D TOUCH_SCL=48 + -D TOUCH_RST=-1 + -D TOUCH_IRQ=-1 + -D I2C_TOUCH_FREQUENCY=400000 + -D I2C_TOUCH_ADDRESS=0x5D ; or 0x14 + -D I2C_TOUCH_PORT=1 + ; USB GPIO - Only need to define these so that the pins do not + ; show up in the list of available GPIO + -D USB_TXD=19 + -D USB_RXD=20 +;endregion + +lib_deps = + ${arduino_esp32s3_v2.lib_deps} + ${arduinogfx.lib_deps} + ${goodix.lib_deps} + +[env:esp32-s3-lilygo-t-rgb-28_16MB] +extends = esp32-s3-lilygo-t-rgb-28, flash_16mb From d137038bdc1b8099449b8b7888aab57f64e7bbf5 Mon Sep 17 00:00:00 2001 From: Thomas Langewouters Date: Sun, 26 Oct 2025 00:18:48 +0200 Subject: [PATCH 2/2] lilygo t-rgb-2.8": Initialize wire and add reset sequence from SDK --- src/drv/tft/tft_driver_arduinogfx.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp index 085f8132a..1bdc42ab5 100644 --- a/src/drv/tft/tft_driver_arduinogfx.cpp +++ b/src/drv/tft/tft_driver_arduinogfx.cpp @@ -234,7 +234,8 @@ void ArduinoGfx::init(int w, int h) #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) && defined(ST7701_TRGB_28) /* SPI to the TFT is done over an I2C port expander */ - Arduino_DataBus *bus = new Arduino_XL9535SWSPI(8 /* SDA */, 48 /* SCL */, 2 /* XL PWD */, 3 /* XL CS */, 5 /* XL SCK */, 4 /* XL MOSI */); + Wire.begin(8 /* SDA */, 48 /* SCL */, 800000L /* speed */); + Arduino_XL9535SWSPI *bus = new Arduino_XL9535SWSPI(8 /* SDA */, 48 /* SCL */, 2 /* XL PWD */, 3 /* XL CS */, 5 /* XL SCK */, 4 /* XL MOSI */); Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel( 45 /* DE */, 41 /* VSYNC */, 47 /* HSYNC */, 42 /* PCLK */, @@ -248,6 +249,16 @@ void ArduinoGfx::init(int w, int h) tft = new Arduino_RGB_Display( 480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */, bus, GFX_NOT_DEFINED /* RST */, st7701_type9_init_operations_trgb28, sizeof(st7701_type9_init_operations_trgb28)); + + // reset sequence from T-RGB SDK + const uint8_t reset = 1; + bus->begin(); // will be repeated by Arduino_RGB_Display::begin(), checked this is safe at the time of writing + bus->pinMode(reset, OUTPUT); + bus->digitalWrite(reset, LOW); + delay(20); + bus->digitalWrite(reset, HIGH); + delay(10); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER)