diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b2cdc2..f8ae06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,14 @@ # Changelog +## 2026-10-17 — Sunton official touch + log offset + +- Use esp32-2432S028R.json touch flags: X=0xD1 Y=0x91, linear/4096, MIRROR_X. +- Keep landscape 240x320+ROTATION_270. +- Serial/user: red cursor lower-left of finger → UI corr (+45,-45), inverse-feed LVGL. + ## 2026-10-17 — Restore landscape + RNT touch map -- Revert create(320x240) — caused 花屏; keep 240x320 + ROTATION_270 landscape. -- Touch = Random Nerd Tutorials recipe: SoftSPI rot2, map to 240x320, feed LVGL - directly (no extra inverse). Red cursor shows estimated UI point. +- Revert create(320x240) 花屏; RNT map superseded by Sunton official above. ## 2026-10-17 — Touch = draw coords (CYD LVGL9 official) [reverted] diff --git a/firmware/cyd/VERSION.txt b/firmware/cyd/VERSION.txt index 9b74c2f..c881c19 100644 --- a/firmware/cyd/VERSION.txt +++ b/firmware/cyd/VERSION.txt @@ -1,5 +1,5 @@ name: CYD TF card + touch speaker (cyd) -git: 1381c22 +git: 01c5266 date: 2026-10-17 board: ESP32-2432S028R (ILI9341) features: TF/SD info, SoftSPI touch, GPIO26 speaker @@ -12,5 +12,5 @@ offsets: sha256: bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8 boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0 - firmware.bin 7C632F8D033997F18F39056F321011B2DB7D0B0FA64F14FED269EB70EE86C814 + firmware.bin 94A0C3011B584646E8D4F4D29531252E97B488BBE47827DEDD2CDB21FD1FA76F partitions.bin 148B959CBFF1C38AA8E1D5C0BA9D612C54997B945E56A63F41223EEF650653A1 diff --git a/firmware/cyd/firmware.bin b/firmware/cyd/firmware.bin index 303cabc..46805af 100644 Binary files a/firmware/cyd/firmware.bin and b/firmware/cyd/firmware.bin differ diff --git a/src/main.cpp b/src/main.cpp index 3e01e17..e9e61d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,8 +45,8 @@ void setup() { lv_init(); - // RNT / temperature:240x320 + ROTATION_270 → 横屏(勿改成 create 320x240,会花屏) - // https://randomnerdtutorials.com/lvgl-cheap-yellow-display-esp32-2432s028r/ + // Sunton 官方:240x320 + ROTATION_270 → 横屏(勿 create 320x240,会花屏) + // 触摸见 touch.cpp(官方 mirror_x + 日志补偿) lv_display_t *disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf)); lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270); diff --git a/src/touch.cpp b/src/touch.cpp index 4779847..7e8b8e8 100644 --- a/src/touch.cpp +++ b/src/touch.cpp @@ -4,17 +4,21 @@ #include /** - * SoftSPI XPT2046(SD 占 VSPI,触摸必须 SoftSPI) + * SoftSPI XPT2046 — 对齐 Sunton 官方板级(esp32-2432S028R.json / smartdisplay): + * TOUCH_SWAP_XY=false, TOUCH_MIRROR_X=true, TOUCH_MIRROR_Y=false + * x_max=240, y_max=320 + * X 通道 CMD=0xD1, Y 通道 CMD=0x91(与 PaulStoffregen 命名相反) + * 线性:coord = adc * max / 4096,再 mirror_x + * 显示仍用 create(240,320)+LV_DISPLAY_ROTATION_270(横屏,勿改 320x240) * - * 现成方案 — Random Nerd Tutorials CYD + LVGL: - * create(240,320) + LV_DISPLAY_ROTATION_270 - * touchscreen.setRotation(2) - * x = map(p.x, 200, 3700, 1, 240) - * y = map(p.y, 240, 3800, 1, 320) - * 直接喂给 LVGL(由 LVGL 做旋转,不要再反变换 / 不要建 320x240) - * https://randomnerdtutorials.com/lvgl-cheap-yellow-display-esp32-2432s028r/ + * 用户日志:红点在手指左下方 → UI 需向右上修正(见 TOUCH_UI_DX/DY) + * https://github.com/rzeldent/platformio-espressif32-sunton/blob/main/esp32-2432S028R.json */ +// 红点相对手指的补偿(像素,横屏 UI):左偏→+X,下偏→-Y +static constexpr int16_t TOUCH_UI_DX = 45; +static constexpr int16_t TOUCH_UI_DY = -45; + int16_t g_dbg_phys_x = -1; int16_t g_dbg_phys_y = -1; int16_t g_dbg_logic_x = -1; @@ -63,14 +67,17 @@ void touch_init() { pinMode(CYD_TOUCH_IRQ, INPUT); digitalWrite(CYD_TOUCH_CS, HIGH); digitalWrite(CYD_TOUCH_CLK, LOW); - Serial.println("Touch: RNT SoftSPI rot2 map 240x320"); + Serial.printf("Touch: Sunton official mirror_x + UI corr(%d,%d)\n", + (int)TOUCH_UI_DX, (int)TOUCH_UI_DY); } 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); + // 官方驱动:X=0xD1, Y=0x91(先丢弃一次噪声读) + (void)xpt_read(0xD1); + uint16_t adc_x = xpt_read(0xD1); + uint16_t adc_y = xpt_read(0x91); + adc_x = (uint16_t)((adc_x + xpt_read(0xD1)) / 2); + adc_y = (uint16_t)((adc_y + xpt_read(0x91)) / 2); const bool irq = (digitalRead(CYD_TOUCH_IRQ) == LOW); const bool in_range = @@ -82,45 +89,61 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { return; } - // XPT2046_Touchscreen setRotation(2) - const int16_t p_x = (int16_t)adc_x; - const int16_t p_y = (int16_t)(4095 - adc_y); + // esp_touch_xpt2046: (adc>>3 等价 12bit) * max / 4096 + int16_t px = (int16_t)(((uint32_t)adc_x * SCREEN_WIDTH) / 4096); + int16_t py = (int16_t)(((uint32_t)adc_y * SCREEN_HEIGHT) / 4096); - // RNT:映射到物理 240x320,交给 LVGL ROTATION_270 - int16_t x = map(p_x, 200, 3700, 1, SCREEN_WIDTH); - int16_t y = map(p_y, 240, 3800, 1, SCREEN_HEIGHT); + // TOUCH_MIRROR_X=true + px = (int16_t)((SCREEN_WIDTH - 1) - px); - if (x < 0) { - x = 0; + if (px < 0) { + px = 0; } - if (y < 0) { - y = 0; + if (py < 0) { + py = 0; } - if (x >= SCREEN_WIDTH) { - x = SCREEN_WIDTH - 1; + if (px >= SCREEN_WIDTH) { + px = SCREEN_WIDTH - 1; } - if (y >= SCREEN_HEIGHT) { - y = SCREEN_HEIGHT - 1; + if (py >= SCREEN_HEIGHT) { + py = SCREEN_HEIGHT - 1; } - // 预估 LVGL 270 后的 UI 坐标(光标用):(y, 239-x) - const int16_t ui_x = y; - const int16_t ui_y = (int16_t)((SCREEN_WIDTH - 1) - x); + // LVGL ROTATION_270 后 UI:(py, 239-px);再按日志把红点挪向手指 + int16_t ui_x = (int16_t)(py + TOUCH_UI_DX); + int16_t ui_y = (int16_t)(((SCREEN_WIDTH - 1) - px) + TOUCH_UI_DY); - g_dbg_phys_x = x; - g_dbg_phys_y = y; + if (ui_x < 0) { + ui_x = 0; + } + if (ui_y < 0) { + ui_y = 0; + } + if (ui_x >= UI_HOR_RES) { + ui_x = UI_HOR_RES - 1; + } + if (ui_y >= UI_VER_RES) { + ui_y = UI_VER_RES - 1; + } + + // 反变换喂给 LVGL,使其变换后落到 (ui_x, ui_y) + const int16_t feed_x = (int16_t)((SCREEN_WIDTH - 1) - ui_y); + const int16_t feed_y = ui_x; + + g_dbg_phys_x = px; + g_dbg_phys_y = py; g_dbg_logic_x = ui_x; g_dbg_logic_y = ui_y; g_dbg_touch_down = true; static uint32_t last_log = 0; - if (millis() - last_log > 120) { + if (millis() - last_log > 100) { last_log = millis(); - Serial.printf("Touch p(%d,%d) feed(%d,%d) UI~(%d,%d)\n", p_x, p_y, x, y, - ui_x, ui_y); + Serial.printf("Touch adc(%u,%u) phys(%d,%d) UI(%d,%d) feed(%d,%d)\n", adc_x, + adc_y, px, py, ui_x, ui_y, feed_x, feed_y); } - data->point.x = x; - data->point.y = y; + data->point.x = feed_x; + data->point.y = feed_y; data->state = LV_INDEV_STATE_PRESSED; }