#include "touch.h" #include /** * 2.8": XPT2046 resistive SoftSPI bus (CS33). * 3.5C (3248S035C): GT911 capacitive on I2C Wire SDA33/SCL32/INT21/RST25. * Feed coords are always native panel 320x480 for LVGL ROTATION_270. * (DHT11 is 1-wire on GPIO22 — Wire is free for GT911.) */ static int16_t clampi(int32_t v, int32_t lo, int32_t hi) { if (v < lo) return (int16_t)lo; if (v > hi) return (int16_t)hi; return (int16_t)v; } #if defined(CYD_BOARD_3248S035) #include /* Native panel size — not UI landscape SCREEN_* (480x320). */ static constexpr int16_t PANEL_W = 320; static constexpr int16_t PANEL_H = 480; #define CYD_GT911_SDA 33 #define CYD_GT911_SCL 32 #define CYD_GT911_INT 21 #define CYD_GT911_RST 25 /* Minimal GT911 — no config rewrite (TAMC setResolution can hang Wire). */ static uint8_t s_gt_addr = 0x5D; static constexpr uint16_t GT_POINT_INFO = 0x814E; static constexpr uint16_t GT_POINT_1 = 0x814F; static bool gt_write8(uint16_t reg, uint8_t val) { Wire.beginTransmission(s_gt_addr); Wire.write((uint8_t)(reg >> 8)); Wire.write((uint8_t)(reg & 0xFF)); Wire.write(val); return Wire.endTransmission() == 0; } static bool gt_read(uint16_t reg, uint8_t *buf, uint8_t len) { Wire.beginTransmission(s_gt_addr); Wire.write((uint8_t)(reg >> 8)); Wire.write((uint8_t)(reg & 0xFF)); if (Wire.endTransmission(false) != 0) { return false; } const uint8_t n = Wire.requestFrom(s_gt_addr, len); if (n != len) { return false; } for (uint8_t i = 0; i < len; i++) { buf[i] = Wire.read(); } return true; } static bool gt_probe(uint8_t addr) { Wire.beginTransmission(addr); return Wire.endTransmission() == 0; } /* TAMC-compatible address select: INT low => 0x5D, INT high => 0x14 */ static void gt_hw_reset(bool addr_0x14) { pinMode(CYD_GT911_INT, OUTPUT); pinMode(CYD_GT911_RST, OUTPUT); digitalWrite(CYD_GT911_INT, LOW); digitalWrite(CYD_GT911_RST, LOW); delay(10); digitalWrite(CYD_GT911_INT, addr_0x14 ? HIGH : LOW); delay(1); digitalWrite(CYD_GT911_RST, HIGH); delay(5); digitalWrite(CYD_GT911_INT, LOW); delay(50); /* Backlight is GPIO27 — leave INT as input for polling / optional IRQ. */ pinMode(CYD_GT911_INT, INPUT); delay(50); } static bool gt_find_addr() { for (uint8_t a : {uint8_t(0x5D), uint8_t(0x14)}) { if (gt_probe(a)) { s_gt_addr = a; return true; } } return false; } void touch_init() { Serial.println("Touch: GT911 I2C capacitive (3.5C) minimal"); Wire.begin(CYD_GT911_SDA, CYD_GT911_SCL); Wire.setClock(100000); #if defined(WIRE_HAS_TIMEOUT) || defined(ESP32) Wire.setTimeOut(50); #endif if (!gt_find_addr()) { Serial.println("GT911 not found — hw reset 0x5D"); gt_hw_reset(false); if (!gt_find_addr()) { Serial.println("GT911 not found — hw reset 0x14"); gt_hw_reset(true); gt_find_addr(); } } Serial.printf("GT911 probe 0x5D=%s 0x14=%s using=0x%02X\n", gt_probe(0x5D) ? "OK" : "no", gt_probe(0x14) ? "OK" : "no", s_gt_addr); Serial.printf("GT911 SDA=%d SCL=%d INT=%d RST=%d\n", CYD_GT911_SDA, CYD_GT911_SCL, CYD_GT911_INT, CYD_GT911_RST); } void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { uint8_t info = 0; if (!gt_read(GT_POINT_INFO, &info, 1)) { data->state = LV_INDEV_STATE_RELEASED; return; } const uint8_t touches = info & 0x0F; const bool buffered = (info & 0x80) != 0; if (!buffered || touches == 0) { if (buffered) { gt_write8(GT_POINT_INFO, 0); } data->state = LV_INDEV_STATE_RELEASED; return; } uint8_t pt[7]; if (!gt_read(GT_POINT_1, pt, 7)) { gt_write8(GT_POINT_INFO, 0); data->state = LV_INDEV_STATE_RELEASED; return; } gt_write8(GT_POINT_INFO, 0); const int16_t raw_x = (int16_t)(pt[1] | (pt[2] << 8)); const int16_t raw_y = (int16_t)(pt[3] | (pt[4] << 8)); /* Native 320x480 → LVGL 270. UI ≈ (H-1-raw_y, raw_x). */ const int16_t nx = clampi(raw_x, 0, PANEL_W - 1); const int16_t ny = clampi(raw_y, 0, PANEL_H - 1); data->point.x = (int16_t)((PANEL_W - 1) - nx); data->point.y = (int16_t)((PANEL_H - 1) - ny); data->state = LV_INDEV_STATE_PRESSED; } #else #include #include #define XPT2046_IRQ 36 #define XPT2046_MOSI 32 #define XPT2046_MISO 39 #define XPT2046_CLK 25 #define XPT2046_CS 33 /* 2.8 UI landscape feed (unchanged from prior main.cpp). */ static constexpr int16_t UI_W = 320; static constexpr int16_t UI_H = 240; static SPIClass touchscreenSPI = SPIClass(VSPI); static XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ); void touch_init() { touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen.begin(touchscreenSPI); touchscreen.setRotation(2); Serial.println("Touch: XPT2046 resistive (2.8)"); } void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { if (touchscreen.tirqTouched() && touchscreen.touched()) { TS_Point p = touchscreen.getPoint(); data->point.x = map(p.y, 240, 3800, 1, UI_W); data->point.y = map(p.x, 200, 3700, UI_H, 1); data->state = LV_INDEV_STATE_PRESSED; } else { data->state = LV_INDEV_STATE_RELEASED; } } #endif