Fix double touch rotation so bottom LVGL buttons receive hits.
Report physical 240x320 coordinates and let LVGL apply ROTATION_270. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,8 +4,11 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
/**
|
||||
* SoftSPI XPT2046 → LVGL pointer indev
|
||||
* 读数用简单稳定协议(此前能点到);坐标变换对齐 temperature(rot2 + map 320x240)。
|
||||
* SoftSPI XPT2046 → LVGL indev
|
||||
*
|
||||
* 关键:必须上报与 lv_tft_espi_create(240,320) 一致的【物理竖屏】坐标。
|
||||
* LVGL 在 ROTATION_270 时会自己做镜像+交换(见 lv_indev.c indev_pointer_proc)。
|
||||
* 若再 map 成 320x240,等于旋转两次,就会出现「只有上 1/3 有反应、底部按钮点不到」。
|
||||
*/
|
||||
|
||||
static void soft_write(uint8_t data) {
|
||||
@@ -50,11 +53,10 @@ void touch_init() {
|
||||
pinMode(CYD_TOUCH_IRQ, INPUT);
|
||||
digitalWrite(CYD_TOUCH_CS, HIGH);
|
||||
digitalWrite(CYD_TOUCH_CLK, LOW);
|
||||
Serial.println("Touch: LVGL indev SoftSPI");
|
||||
Serial.println("Touch: physical 240x320 for LVGL rotation");
|
||||
}
|
||||
|
||||
void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
// 不依赖 IRQ(部分板子 IRQ 不可靠):用采样有效性判断
|
||||
uint16_t raw_x = xpt_read(0x90);
|
||||
uint16_t raw_y = xpt_read(0xD0);
|
||||
raw_x = (uint16_t)((raw_x + xpt_read(0x90)) / 2);
|
||||
@@ -64,18 +66,24 @@ 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 || (!irq && (raw_x < 200 || raw_y < 200))) {
|
||||
if (!in_range) {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
return;
|
||||
}
|
||||
// 无 IRQ 时仍允许(部分板 IRQ 不可靠),但过滤空闲噪声
|
||||
if (!irq && (raw_x < 150 || raw_y < 150)) {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
return;
|
||||
}
|
||||
|
||||
// XPT2046_Touchscreen setRotation(2)
|
||||
// XPT2046_Touchscreen setRotation(2) 等价变换
|
||||
const int16_t p_x = (int16_t)raw_x;
|
||||
const int16_t p_y = (int16_t)(4095 - raw_y);
|
||||
|
||||
// temperature 横屏逻辑坐标(UI 320x240)
|
||||
int16_t x = map(p_y, 240, 3800, 1, UI_HOR_RES);
|
||||
int16_t y = map(p_x, 200, 3700, UI_VER_RES, 1);
|
||||
// 物理竖屏:宽 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);
|
||||
int16_t y = map(p_y, 240, 3800, 0, SCREEN_HEIGHT - 1);
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
@@ -83,18 +91,18 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
if (x >= UI_HOR_RES) {
|
||||
x = UI_HOR_RES - 1;
|
||||
if (x >= SCREEN_WIDTH) {
|
||||
x = SCREEN_WIDTH - 1;
|
||||
}
|
||||
if (y >= UI_VER_RES) {
|
||||
y = UI_VER_RES - 1;
|
||||
if (y >= SCREEN_HEIGHT) {
|
||||
y = SCREEN_HEIGHT - 1;
|
||||
}
|
||||
|
||||
static uint32_t last_log = 0;
|
||||
if (millis() - last_log > 250) {
|
||||
if (millis() - last_log > 200) {
|
||||
last_log = millis();
|
||||
Serial.printf("LVGL touch irq=%d raw(%u,%u) -> (%d,%d)\n", irq ? 1 : 0, raw_x,
|
||||
raw_y, x, y);
|
||||
Serial.printf("Touch phys(%d,%d) raw(%u,%u) irq=%d\n", x, y, raw_x, raw_y,
|
||||
irq ? 1 : 0);
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
|
||||
Reference in New Issue
Block a user