#include "touch.h" #include "pins.h" #include /** * SoftSPI XPT2046 — 与 SD 分脚 * * 对齐官方 CYD LVGL9 例程(witnessmenow): * - 显示直接建为 320x240,LVGL rotation=0(触控不再被二次变换) * - touch setRotation(3) + map 到 SCREEN_WIDTH/HEIGHT * 参考:https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/Examples/LVGL9/ */ int16_t g_dbg_phys_x = -1; int16_t g_dbg_phys_y = -1; int16_t g_dbg_logic_x = -1; int16_t g_dbg_logic_y = -1; bool g_dbg_touch_down = false; static void soft_write(uint8_t data) { for (int i = 7; i >= 0; --i) { digitalWrite(CYD_TOUCH_MOSI, (data >> i) & 1); digitalWrite(CYD_TOUCH_CLK, HIGH); delayMicroseconds(2); digitalWrite(CYD_TOUCH_CLK, LOW); delayMicroseconds(2); } } static uint16_t soft_read12() { uint16_t v = 0; digitalWrite(CYD_TOUCH_CLK, HIGH); delayMicroseconds(2); digitalWrite(CYD_TOUCH_CLK, LOW); delayMicroseconds(2); for (int i = 0; i < 12; ++i) { digitalWrite(CYD_TOUCH_CLK, HIGH); delayMicroseconds(2); v = (uint16_t)((v << 1) | (digitalRead(CYD_TOUCH_MISO) ? 1u : 0u)); digitalWrite(CYD_TOUCH_CLK, LOW); delayMicroseconds(2); } return v; } static uint16_t xpt_read(uint8_t cmd) { digitalWrite(CYD_TOUCH_CS, LOW); soft_write(cmd); uint16_t v = soft_read12(); digitalWrite(CYD_TOUCH_CS, HIGH); return v; } void touch_init() { pinMode(CYD_TOUCH_CS, OUTPUT); pinMode(CYD_TOUCH_CLK, OUTPUT); pinMode(CYD_TOUCH_MOSI, OUTPUT); pinMode(CYD_TOUCH_MISO, INPUT); pinMode(CYD_TOUCH_IRQ, INPUT); digitalWrite(CYD_TOUCH_CS, HIGH); digitalWrite(CYD_TOUCH_CLK, LOW); Serial.println("Touch: SoftSPI rot3 map 320x240 (no LVGL rot)"); } void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { uint16_t adc_x = xpt_read(0x90); uint16_t adc_y = xpt_read(0xD0); adc_x = (uint16_t)((adc_x + xpt_read(0x90)) / 2); adc_y = (uint16_t)((adc_y + xpt_read(0xD0)) / 2); const bool irq = (digitalRead(CYD_TOUCH_IRQ) == LOW); const bool in_range = (adc_x > 80 && adc_x < 4000 && adc_y > 80 && adc_y < 4000); if (!in_range || (!irq && (adc_x < 200 || adc_y < 200))) { data->state = LV_INDEV_STATE_RELEASED; g_dbg_touch_down = false; return; } // XPT2046_Touchscreen setRotation(3): // xraw = 4095 - Y_sample, yraw = 4095 - X_sample const int16_t p_x = (int16_t)(4095 - adc_y); const int16_t p_y = (int16_t)(4095 - adc_x); int16_t x = map(p_x, 200, 3700, 1, SCREEN_WIDTH); int16_t y = map(p_y, 240, 3800, 1, SCREEN_HEIGHT); if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (x >= SCREEN_WIDTH) { x = SCREEN_WIDTH - 1; } if (y >= SCREEN_HEIGHT) { y = SCREEN_HEIGHT - 1; } g_dbg_phys_x = p_x; g_dbg_phys_y = p_y; g_dbg_logic_x = x; g_dbg_logic_y = y; g_dbg_touch_down = true; static uint32_t last_log = 0; if (millis() - last_log > 120) { last_log = millis(); Serial.printf("Touch adc(%u,%u) p(%d,%d) -> (%d,%d)\n", adc_x, adc_y, p_x, p_y, x, y); } data->point.x = x; data->point.y = y; data->state = LV_INDEV_STATE_PRESSED; }