#include #include "TCA9554PWR.h" #include "Display_ST7701.h" #include "Touch_CST820.h" // Display dimensions #define DISPLAY_WIDTH 480 #define DISPLAY_HEIGHT 480 // Color definitions #define COLOR_BLACK 0x0000 #define COLOR_BLUE 0x001F #define COLOR_RED 0xF800 #define COLOR_WHITE 0xFFFF // Custom ST7701 Display Driver that uses existing initialization class Arduino_ST7701 : public Arduino_GFX { public: Arduino_ST7701(Arduino_ESP32RGBPanel *panel, int16_t w = DISPLAY_WIDTH, int16_t h = DISPLAY_HEIGHT) : Arduino_GFX(w, h), _panel(panel) {} bool begin(int32_t speed = GFX_NOT_DEFINED) override { _panel->begin(); LCD_Init(); return true; } protected: void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override { esp_lcd_panel_draw_bitmap(panel_handle, x, y, x + 1, y + 1, &color); } void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override { if (h < 0) { y += h + 1; h = -h; } uint16_t *line = (uint16_t *)malloc(h * sizeof(uint16_t)); if (line) { for (int16_t i = 0; i < h; i++) { line[i] = color; } esp_lcd_panel_draw_bitmap(panel_handle, x, y, x + 1, y + h, line); free(line); } } void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override { if (w < 0) { x += w + 1; w = -w; } uint16_t *line = (uint16_t *)malloc(w * sizeof(uint16_t)); if (line) { for (int16_t i = 0; i < w; i++) { line[i] = color; } esp_lcd_panel_draw_bitmap(panel_handle, x, y, x + w, y + 1, line); free(line); } } void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override { if (w < 0) { x += w + 1; w = -w; } if (h < 0) { y += h + 1; h = -h; } uint16_t *buffer = (uint16_t *)malloc(w * h * sizeof(uint16_t)); if (buffer) { for (int32_t i = 0; i < w * h; i++) { buffer[i] = color; } esp_lcd_panel_draw_bitmap(panel_handle, x, y, x + w, y + h, buffer); free(buffer); } } private: Arduino_ESP32RGBPanel* _panel; }; // Error handling enum InitStatus { INIT_OK = 0, INIT_I2C_FAILED, INIT_IO_EXPANDER_FAILED, INIT_DISPLAY_FAILED, INIT_TOUCH_FAILED }; // Create RGB Panel instance Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel( ESP_PANEL_LCD_PIN_NUM_RGB_DATA0, // B0 ESP_PANEL_LCD_PIN_NUM_RGB_DATA1, // B1 ESP_PANEL_LCD_PIN_NUM_RGB_DATA2, // B2 ESP_PANEL_LCD_PIN_NUM_RGB_DATA3, // B3 ESP_PANEL_LCD_PIN_NUM_RGB_DATA4, // B4 ESP_PANEL_LCD_PIN_NUM_RGB_DATA5, // G0 ESP_PANEL_LCD_PIN_NUM_RGB_DATA6, // G1 ESP_PANEL_LCD_PIN_NUM_RGB_DATA7, // G2 ESP_PANEL_LCD_PIN_NUM_RGB_DATA8, // G3 ESP_PANEL_LCD_PIN_NUM_RGB_DATA9, // G4 ESP_PANEL_LCD_PIN_NUM_RGB_DATA10, // G5 ESP_PANEL_LCD_PIN_NUM_RGB_DATA11, // R0 ESP_PANEL_LCD_PIN_NUM_RGB_DATA12, // R1 ESP_PANEL_LCD_PIN_NUM_RGB_DATA13, // R2 ESP_PANEL_LCD_PIN_NUM_RGB_DATA14, // R3 ESP_PANEL_LCD_PIN_NUM_RGB_DATA15, // R4 ESP_PANEL_LCD_PIN_NUM_RGB_PCLK, // PCLK ESP_PANEL_LCD_PIN_NUM_RGB_VSYNC, // VSYNC ESP_PANEL_LCD_PIN_NUM_RGB_HSYNC, // HSYNC ESP_PANEL_LCD_PIN_NUM_RGB_DE, // DE DISPLAY_WIDTH, // Width DISPLAY_HEIGHT, // Height 16, // hsync_polarity 10, // hsync_front_porch 8, // hsync_pulse_width 50, // hsync_back_porch 3, // vsync_polarity 8, // vsync_front_porch 8, // vsync_pulse_width 8 // vsync_back_porch ); // Create display driver instance Arduino_ST7701 *gfx = new Arduino_ST7701(rgbpanel); // Touch variables volatile bool touch_enabled = false; uint32_t last_touch_time = 0; const uint32_t TOUCH_DEBOUNCE_MS = 50; // Function prototypes InitStatus initializeHardware(); void handleTouch(); void drawTouchPoint(uint16_t x, uint16_t y, bool pressed); void IRAM_ATTR touchISR(); InitStatus initializeHardware() { // Initialize I2C Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); delay(100); // Initialize IO Expander TCA9554PWR_Init(0x00); uint8_t io_status = Read_EXIOS(TCA9554_OUTPUT_REG); if (io_status == 0xFF) { Serial.println("IO Expander initialization failed!"); return INIT_IO_EXPANDER_FAILED; } // Enable display power Set_EXIO(EXIO_PIN8, Low); delay(10); // Initialize display using Arduino_GFX begin() if (!static_cast(gfx)->begin()) { Serial.println("Display initialization failed!"); return INIT_DISPLAY_FAILED; } // Initialize touch controller if (!Touch_Init()) { Serial.println("Touch controller initialization failed!"); return INIT_TOUCH_FAILED; } // Set up touch interrupt pinMode(CST820_INT_PIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(CST820_INT_PIN), touchISR, FALLING); touch_enabled = true; return INIT_OK; } void drawTouchPoint(uint16_t x, uint16_t y, bool pressed) { const uint16_t radius = 5; uint16_t color = pressed ? COLOR_RED : COLOR_BLUE; if (!pressed) { gfx->fillCircle(x, y, radius + 1, COLOR_BLUE); return; } gfx->fillCircle(x, y, radius, color); gfx->drawCircle(x, y, radius + 1, COLOR_WHITE); } void handleTouch() { if (!touch_enabled) return; uint32_t current_time = millis(); if (current_time - last_touch_time < TOUCH_DEBOUNCE_MS) return; last_touch_time = current_time; Touch_Read_Data(); if (touch_data.points > 0) { uint16_t x = constrain(touch_data.x, 0, DISPLAY_WIDTH - 1); uint16_t y = constrain(touch_data.y, 0, DISPLAY_HEIGHT - 1); drawTouchPoint(x, y, true); char buf[32]; snprintf(buf, sizeof(buf), "Touch: %d,%d ", x, y); gfx->setTextColor(COLOR_WHITE, COLOR_BLUE); gfx->setCursor(10, 10); gfx->print(buf); if (touch_data.gesture != NONE) { gfx->setCursor(10, 30); gfx->print("Gesture: "); gfx->print(Touch_GestureName()); gfx->print(" "); } } } void IRAM_ATTR touchISR() { Touch_CST820_ISR(); } void setup() { Serial.begin(115200); Serial.println("ESP32-S3 Touch LCD Hello World"); InitStatus status = initializeHardware(); if (status != INIT_OK) { Serial.print("Initialization failed with status: "); Serial.println(status); while (1) { delay(1000); Serial.print("."); } } gfx->setRotation(0); gfx->fillScreen(COLOR_BLUE); gfx->setTextColor(COLOR_WHITE); gfx->setTextSize(3); const char* text = "Touch the screen!"; int16_t x1, y1; uint16_t w, h; gfx->getTextBounds(text, 0, 0, &x1, &y1, &w, &h); int x = (DISPLAY_WIDTH - w) / 2; int y = (DISPLAY_HEIGHT - h) / 2; gfx->setCursor(x, y); gfx->println(text); Serial.println("Setup complete!"); } void loop() { handleTouch(); delay(10); }