Files
tftest/src/touch.cpp
DESKTOP-PUHFO60\dsx2016 aa08b23fca Restore SoftSPI touch and exclusive VSPI for SD.
HW SPI remux froze touch at (0,4095) and broke SD; keep temperature UI map plus LVGL inverse feed.

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

121 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 的 VSPI 分脚,互不抢总线)
* 标定对齐 temperature(rot2 + map 到 UI 320x240),再反变换喂给 LVGL
* ROTATION_270(见 lv_indev.c):out=(y_in, 239-x_in)
*/
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 + temp map + LVGL inverse");
}
void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) {
uint16_t raw_x = xpt_read(0x90);
uint16_t raw_y = xpt_read(0xD0);
raw_x = (uint16_t)((raw_x + xpt_read(0x90)) / 2);
raw_y = (uint16_t)((raw_y + xpt_read(0xD0)) / 2);
const bool irq = (digitalRead(CYD_TOUCH_IRQ) == LOW);
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))) {
data->state = LV_INDEV_STATE_RELEASED;
g_dbg_touch_down = false;
return;
}
// 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 坐标
int16_t lx = map(p_y, 240, 3800, 1, UI_HOR_RES);
int16_t ly = map(p_x, 200, 3700, UI_VER_RES, 1);
if (lx < 0) {
lx = 0;
}
if (ly < 0) {
ly = 0;
}
if (lx >= UI_HOR_RES) {
lx = UI_HOR_RES - 1;
}
if (ly >= UI_VER_RES) {
ly = UI_VER_RES - 1;
}
// 反变换:让 LVGL ROTATION_270 之后落到 (lx, ly)
const int16_t x_in = (int16_t)((SCREEN_WIDTH - 1) - ly);
const int16_t y_in = lx;
g_dbg_phys_x = p_x;
g_dbg_phys_y = p_y;
g_dbg_logic_x = lx;
g_dbg_logic_y = ly;
g_dbg_touch_down = true;
static uint32_t last_log = 0;
if (millis() - last_log > 120) {
last_log = millis();
Serial.printf("Touch raw(%u,%u) UI(%d,%d) feed(%d,%d)\n", raw_x, raw_y, lx,
ly, x_in, y_in);
}
data->point.x = x_in;
data->point.y = y_in;
data->state = LV_INDEV_STATE_PRESSED;
}