Calibrate touch from serial logs: invert physical X axis.
Bottom LVGL buttons were mapped to the top; add on-screen logic coordinate debug. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,13 +4,18 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
/**
|
||||
* SoftSPI XPT2046 → LVGL indev
|
||||
* SoftSPI XPT2046 → LVGL indev(物理 240x320,LVGL 再做 ROTATION_270)
|
||||
*
|
||||
* 关键:必须上报与 lv_tft_espi_create(240,320) 一致的【物理竖屏】坐标。
|
||||
* LVGL 在 ROTATION_270 时会自己做镜像+交换(见 lv_indev.c indev_pointer_proc)。
|
||||
* 若再 map 成 320x240,等于旋转两次,就会出现「只有上 1/3 有反应、底部按钮点不到」。
|
||||
* 串口实测:未反转时,点屏幕下方按钮对应到上方区域;
|
||||
* 故对物理 X 取反,使视觉上下与逻辑 ly 一致。
|
||||
*/
|
||||
|
||||
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);
|
||||
@@ -53,7 +58,7 @@ void touch_init() {
|
||||
pinMode(CYD_TOUCH_IRQ, INPUT);
|
||||
digitalWrite(CYD_TOUCH_CS, HIGH);
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
Serial.println("Touch: physical 240x320 for LVGL rotation");
|
||||
Serial.println("Touch: phys 240x320, invert X (from serial calib)");
|
||||
}
|
||||
|
||||
void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
@@ -66,23 +71,18 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
const bool in_range =
|
||||
(raw_x > 80 && raw_x < 4000 && raw_y > 80 && raw_y < 4000);
|
||||
|
||||
if (!in_range) {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
return;
|
||||
}
|
||||
// 无 IRQ 时仍允许(部分板 IRQ 不可靠),但过滤空闲噪声
|
||||
if (!irq && (raw_x < 150 || raw_y < 150)) {
|
||||
if (!in_range || (!irq && (raw_x < 150 || raw_y < 150))) {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
g_dbg_touch_down = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// XPT2046_Touchscreen setRotation(2) 等价变换
|
||||
// setRotation(2) 等价
|
||||
const int16_t p_x = (int16_t)raw_x;
|
||||
const int16_t p_y = (int16_t)(4095 - raw_y);
|
||||
|
||||
// 物理竖屏:宽 SCREEN_WIDTH=240,高 SCREEN_HEIGHT=320
|
||||
// (与 create(240,320) 的 disp->hor_res / ver_res 一致,供 LVGL 再旋转)
|
||||
int16_t x = map(p_x, 200, 3700, 0, SCREEN_WIDTH - 1);
|
||||
// 物理竖屏;X 反向(串口日志标定)
|
||||
int16_t x = map(p_x, 200, 3700, SCREEN_WIDTH - 1, 0);
|
||||
int16_t y = map(p_y, 240, 3800, 0, SCREEN_HEIGHT - 1);
|
||||
|
||||
if (x < 0) {
|
||||
@@ -98,11 +98,22 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
y = SCREEN_HEIGHT - 1;
|
||||
}
|
||||
|
||||
// LVGL ROTATION_270 之后的逻辑坐标(与 indev_pointer_proc 一致)
|
||||
// lx = y, ly = hor_res - x - 1 (hor_res=240)
|
||||
const int16_t logic_x = y;
|
||||
const int16_t logic_y = (int16_t)(SCREEN_WIDTH - 1 - x);
|
||||
|
||||
g_dbg_phys_x = x;
|
||||
g_dbg_phys_y = y;
|
||||
g_dbg_logic_x = logic_x;
|
||||
g_dbg_logic_y = logic_y;
|
||||
g_dbg_touch_down = true;
|
||||
|
||||
static uint32_t last_log = 0;
|
||||
if (millis() - last_log > 200) {
|
||||
if (millis() - last_log > 150) {
|
||||
last_log = millis();
|
||||
Serial.printf("Touch phys(%d,%d) raw(%u,%u) irq=%d\n", x, y, raw_x, raw_y,
|
||||
irq ? 1 : 0);
|
||||
Serial.printf("Touch raw(%u,%u) phys(%d,%d) logic(%d,%d)\n", raw_x, raw_y, x,
|
||||
y, logic_x, logic_y);
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
|
||||
Reference in New Issue
Block a user