Files
tftest/src/touch.cpp
DESKTOP-PUHFO60\dsx2016 1381c221d9 Align touch and draw in one 320x240 space like CYD LVGL9.
Drop LVGL ROTATION_270 double-transform; SoftSPI rot3 maps directly to screen pixels.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 18:14:26 +08:00

120 lines
3.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "touch.h"
#include "pins.h"
#include <Arduino.h>
/**
* 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;
}