diff --git a/firmware/cyd_28r/VERSION.txt b/firmware/cyd_28r/VERSION.txt index 2765af6..10037e9 100644 --- a/firmware/cyd_28r/VERSION.txt +++ b/firmware/cyd_28r/VERSION.txt @@ -1,5 +1,5 @@ name: CYD inmp441recondtest (cyd_28r) -git: 76ca618 +git: 994d21c date: 2026-10-27 board: ESP32-2432S028R (ILI9341) inmp441: WS=GPIO22 SCK=GPIO27 SD=GPIO35 @@ -14,5 +14,5 @@ offsets: sha256: bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8 boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0 - firmware.bin 201E74138012880FDEA3AA46187BA3353B65788D2689DD076A7456C11EF5DD04 + firmware.bin 98431C01560E890DBE3F2BDE0A42AA6CFFBDF356FB8172B6FE755CB1FFC3AE99 partitions.bin 0A8B5720E7B77FF11F1462458C3A509DEE79224E5279898F26D6A2E3AE0517B7 diff --git a/firmware/cyd_28r/firmware.bin b/firmware/cyd_28r/firmware.bin index cf004b9..1e06059 100644 Binary files a/firmware/cyd_28r/firmware.bin and b/firmware/cyd_28r/firmware.bin differ diff --git a/lib/CYD28_Touchscreen/CYD28_TouchscreenR.cpp b/lib/CYD28_Touchscreen/CYD28_TouchscreenR.cpp new file mode 100644 index 0000000..240f6a4 --- /dev/null +++ b/lib/CYD28_Touchscreen/CYD28_TouchscreenR.cpp @@ -0,0 +1,234 @@ +/* Touchscreen library for XPT2046 Touch Controller Chip + * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice, development funding notice, and this permission + * notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * ----------------------- CYD28 (2.8" cheap yellow display) version -------------------------- + * using software bit banged SPI and fixed GPIOs + manual calibration + * 08.2023 - Piotr Zapart www.hexefx.com + * + * + */ + +#include "CYD28_TouchscreenR.h" + +#define ISR_PREFIX IRAM_ATTR +#define MSEC_THRESHOLD 3 + +static CYD28_TouchR *isrPinptr; +void isrPin(void); +// ------------------------------------------------------------ +bool CYD28_TouchR::begin() +{ + pinMode(CYD28_TouchR_MOSI, OUTPUT); + pinMode(CYD28_TouchR_MISO, INPUT); + pinMode(CYD28_TouchR_CLK, OUTPUT); + pinMode(CYD28_TouchR_CS, OUTPUT); + digitalWrite(CYD28_TouchR_CLK, LOW); + digitalWrite(CYD28_TouchR_CS, HIGH); + pinMode(CYD28_TouchR_IRQ, INPUT); + /* Polling mode: many CYD boards have flaky T_IRQ; keep isrWake true. */ + isrWake = true; + isrPinptr = this; + return true; +} +// ------------------------------------------------------------ +ISR_PREFIX +void isrPin(void) +{ + CYD28_TouchR *o = isrPinptr; + o->isrWake = true; +} +// ------------------------------------------------------------ +uint8_t CYD28_TouchR::transfer(uint8_t val) +{ + uint8_t out = 0; + uint8_t del = _delay >> 1; + uint8_t bval = 0; + int sck = LOW; + + int8_t bit = 8; + while (bit) + { + bit--; + digitalWrite(CYD28_TouchR_MOSI, ((val & (1 << bit)) ? HIGH : LOW)); // Write bit + wait(del); + sck ^= 1u; + digitalWrite(CYD28_TouchR_CLK, sck); + /* ... Read bit */ + bval = digitalRead(CYD28_TouchR_MISO); + out <<= 1; + out |= bval; + wait(del); + sck ^= 1u; + digitalWrite(CYD28_TouchR_CLK, sck); + } + return out; +} +// ------------------------------------------------------------ +uint16_t CYD28_TouchR::transfer16(uint16_t data) +{ + union + { + uint16_t val; + struct + { + uint8_t lsb; + uint8_t msb; + }; + } in, out; + + in.val = data; + out.msb = transfer(in.msb); + out.lsb = transfer(in.lsb); + return out.val; +} +// ------------------------------------------------------------ +void CYD28_TouchR::wait(uint_fast8_t del) +{ + for (uint_fast8_t i = 0; i < del; i++) + { + asm volatile("nop"); + } +} +// ------------------------------------------------------------ +CYD28_TS_Point CYD28_TouchR::getPointScaled() +{ + update(); + int16_t x = xraw, y = yraw; + convertRawXY(&x, &y); + return CYD28_TS_Point(x, y, zraw); +} +// ------------------------------------------------------------ +CYD28_TS_Point CYD28_TouchR::getPointRaw() +{ + update(); + return CYD28_TS_Point(xraw, yraw, zraw); +} +// ------------------------------------------------------------ +bool CYD28_TouchR::touched() +{ + update(); + return (zraw >= threshold); +} +// ------------------------------------------------------------ +void CYD28_TouchR::readData(uint16_t *x, uint16_t *y, uint8_t *z) +{ + update(); + *x = xraw; + *y = yraw; + *z = zraw; +} +// ------------------------------------------------------------ +static int16_t besttwoavg(int16_t x, int16_t y, int16_t z) +{ + int16_t da, db, dc; + int16_t reta = 0; + if (x > y) da = x - y; + else da = y - x; + if (x > z) db = x - z; + else db = z - x; + if (z > y) dc = z - y; + else dc = y - z; + + if (da <= db && da <= dc) reta = (x + y) >> 1; + else if (db <= da && db <= dc) reta = (x + z) >> 1; + else reta = (y + z) >> 1; + + return (reta); +} +// ------------------------------------------------------------ +void CYD28_TouchR::update() +{ + int16_t data[6]; + int z; + if (!isrWake) + return; + uint32_t now = millis(); + if (now - msraw < MSEC_THRESHOLD) + return; + + digitalWrite(CYD28_TouchR_CS, LOW); + transfer(0xB1 /* Z1 */); + int16_t z1 = transfer16(0xC1 /* Z2 */) >> 3; + z = z1 + 4095; + int16_t z2 = transfer16(0x91 /* X */) >> 3; + z -= z2; + if (z >= threshold) + { + transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy + data[0] = transfer16(0xD1 /* Y */) >> 3; + data[1] = transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements + data[2] = transfer16(0xD1 /* Y */) >> 3; + data[3] = transfer16(0x91 /* X */) >> 3; + } + else data[0] = data[1] = data[2] = data[3] = 0; + data[4] = transfer16(0xD0 /* Y */) >> 3; + data[5] = transfer16(0) >> 3; + digitalWrite(CYD28_TouchR_CS, HIGH); + + if (z < 0) z = 0; + zraw = z; /* always publish pressure for diagnostics */ + if (z < threshold) + { + /* Keep isrWake true for continuous SoftSPI polling (no IRQ dependency). */ + return; + } + + int16_t x = besttwoavg(data[0], data[2], data[4]); + int16_t y = besttwoavg(data[1], data[3], data[5]); + + if (z >= threshold) + { + msraw = now; // good read completed, set wait + xraw = x; + yraw = y; + //log_i("xraw= %d, yraw= %d", xraw, yraw); + } +} +// ------------------------------------------------------------ +void CYD28_TouchR::convertRawXY(int16_t *x, int16_t *y) +{ + int16_t x_tmp = *x, y_tmp = *y, xx, yy; + switch (rotation) + { + case 0: // PORT0 + xx = ((y_tmp - CYD28_TouchR_CAL_YMIN) * sizeY_px) / (CYD28_TouchR_CAL_YMAX - CYD28_TouchR_CAL_YMIN); + yy = ((x_tmp - CYD28_TouchR_CAL_XMIN) * sizeX_px) / (CYD28_TouchR_CAL_XMAX - CYD28_TouchR_CAL_XMIN); + xx = sizeY_px - xx; + break; + case 1: // LANDSC0 + xx = ((x_tmp - CYD28_TouchR_CAL_XMIN) * sizeX_px) / (CYD28_TouchR_CAL_XMAX - CYD28_TouchR_CAL_XMIN); + yy = ((y_tmp - CYD28_TouchR_CAL_YMIN) * sizeY_px) / (CYD28_TouchR_CAL_YMAX - CYD28_TouchR_CAL_YMIN); + break; + case 2: // PORT1 + xx = ((y_tmp - CYD28_TouchR_CAL_YMIN) * sizeY_px) / (CYD28_TouchR_CAL_YMAX - CYD28_TouchR_CAL_YMIN); + yy = ((x_tmp - CYD28_TouchR_CAL_XMIN) * sizeX_px) / (CYD28_TouchR_CAL_XMAX - CYD28_TouchR_CAL_XMIN); + yy = sizeX_px - yy; + break; + default: // 3 LANDSC1 + xx = ((x_tmp - CYD28_TouchR_CAL_XMIN) * sizeX_px) / (CYD28_TouchR_CAL_XMAX - CYD28_TouchR_CAL_XMIN); + yy = ((y_tmp - CYD28_TouchR_CAL_YMIN) * sizeY_px) / (CYD28_TouchR_CAL_YMAX - CYD28_TouchR_CAL_YMIN); + xx = sizeX_px - xx; + yy = sizeY_px - yy; + break; + } + *x = xx; + *y = yy; +} diff --git a/lib/CYD28_Touchscreen/CYD28_TouchscreenR.h b/lib/CYD28_Touchscreen/CYD28_TouchscreenR.h new file mode 100644 index 0000000..f474ea7 --- /dev/null +++ b/lib/CYD28_Touchscreen/CYD28_TouchscreenR.h @@ -0,0 +1,86 @@ +/* Touchscreen library for XPT2046 Touch Controller Chip + * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice, development funding notice, and this permission + * notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------- CYD28 (2.8" cheap yellow display) version -------------------------- + * using software bit banged SPI and fixed GPIOs + manual calibration + * 08.2023 - Piotr Zapart www.hexefx.com + * + */ + +#ifndef _CYD28_TOUCHSCREENR_H_ +#define _CYD28_TOUCHSCREENR_H_ + +#include + +#define CYD28_TouchR_Z_THRESH 300 +#define CYD28_TouchR_Z_THRES_INT 75 + +#define CYD28_TouchR_IRQ 36 +#define CYD28_TouchR_MOSI 32 +#define CYD28_TouchR_MISO 39 +#define CYD28_TouchR_CLK 25 +#define CYD28_TouchR_CS 33 + +// CALIBRAION VALUES +#define CYD28_TouchR_CAL_XMIN 185 +#define CYD28_TouchR_CAL_XMAX 3700 +#define CYD28_TouchR_CAL_YMIN 280 +#define CYD28_TouchR_CAL_YMAX 3850 + +class CYD28_TS_Point { +public: + CYD28_TS_Point(void) : x(0), y(0), z(0) {} + CYD28_TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {} + bool operator==(CYD28_TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); } + bool operator!=(CYD28_TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); } + int16_t x, y, z; +}; + +class CYD28_TouchR { +public: + constexpr CYD28_TouchR(int32_t w, int32_t h) + : _delay(20), sizeX_px(w), sizeY_px(h){ } + bool begin(); + CYD28_TS_Point getPointScaled(); + CYD28_TS_Point getPointRaw(); + bool touched(); + void readData(uint16_t *x, uint16_t *y, uint8_t *z); + void setRotation(uint8_t n) { rotation = n % 4; } + void setThreshold(uint16_t th) { threshold = th;} + + volatile bool isrWake=true; + +private: + void update(); + uint8_t transfer(uint8_t); + uint16_t transfer16(uint16_t data); + void wait(uint_fast8_t del); + void convertRawXY(int16_t *x, int16_t *y); + uint8_t rotation=1; + int16_t xraw=0, yraw=0, zraw=0; + uint16_t threshold = CYD28_TouchR_Z_THRESH; + uint32_t msraw=0x80000000; + uint8_t _delay; + const int32_t sizeX_px; + const int32_t sizeY_px; +}; + +#endif + diff --git a/lib/CYD28_Touchscreen/library.json b/lib/CYD28_Touchscreen/library.json new file mode 100644 index 0000000..fda3229 --- /dev/null +++ b/lib/CYD28_Touchscreen/library.json @@ -0,0 +1,7 @@ +{ + "name": "CYD28_Touchscreen", + "version": "1.0.0", + "description": "Bit-banged XPT2046 for CYD 2.8 (vendored from hexeguitar)", + "frameworks": "arduino", + "platforms": "espressif32" +} diff --git a/src/main.cpp b/src/main.cpp index ed9f449..ad4b6e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,6 +77,9 @@ static void set_backlight(uint8_t level) { ledcWrite(0, BRIGHT_PWM[bright_level]); } +static void do_rec_toggle(void); +static void do_play_toggle(void); + static void show_hint(const char *text, uint32_t ms) { lv_label_set_text(lbl_hint, text); lv_obj_remove_flag(lbl_hint, LV_OBJ_FLAG_HIDDEN); @@ -90,30 +93,58 @@ static const char *basename_of(const char *path) { return p ? p + 1 : path; } +/* Mirror LVGL 9 ROTATION_270 indev transform (create 240×320). */ +static void native_to_ui(int16_t nx, int16_t ny, int16_t *ux, int16_t *uy) { + int32_t x = nx; + int32_t y = ny; + x = SCREEN_WIDTH - x - 1; + y = SCREEN_HEIGHT - y - 1; + int32_t tmp = y; + y = x; + x = SCREEN_HEIGHT - tmp - 1; + *ux = (int16_t)x; + *uy = (int16_t)y; +} + static void touchscreen_read(lv_indev_t *indev, lv_indev_data_t *data) { static bool was_pressed = false; static uint32_t press_ms = 0; - static bool consumed = false; + static int16_t press_ux = 0; + static int16_t press_uy = 0; touch_read_cb(indev, data); if (data->state == LV_INDEV_STATE_PRESSED) { + int16_t ux = 0, uy = 0; + native_to_ui(data->point.x, data->point.y, &ux, &uy); if (!was_pressed) { was_pressed = true; press_ms = millis(); - consumed = false; + press_ux = ux; + press_uy = uy; + Serial.printf("UI press (%d,%d)\n", (int)ux, (int)uy); + } else { + press_ux = ux; + press_uy = uy; } } else if (was_pressed) { was_pressed = false; uint32_t held = millis() - press_ms; - if (!consumed && held < 350) { - /* Brightness only if press was not on a button — LVGL already handled - * buttons; use short idle-area taps via header region. */ - if (data->point.y < 28) { + if (held < 700) { + /* Direct hit-test in landscape UI — bypass flaky LVGL button hitboxes. */ + if (press_uy < 36) { set_backlight((bright_level + 1) & 0x03); char buf[24]; lv_snprintf(buf, sizeof(buf), "brightness %u/3", (unsigned)bright_level); show_hint(buf, 900); + } else if (press_uy > 130) { + if (press_ux < (UI_HOR_RES / 2)) { + Serial.println("Hit → REC"); + do_rec_toggle(); + } else { + Serial.println("Hit → PLAY"); + do_play_toggle(); + } } } } @@ -281,13 +312,14 @@ static void create_ui(void) { lv_obj_set_style_text_color(lbl_sd, COL_MUTED, 0); lv_obj_align(lbl_sd, LV_ALIGN_TOP_LEFT, 0, 40 + UI_BAR_H + 28); - const int btn_y = 40 + UI_BAR_H + 52; + const int btn_h = 56; const int btn_w = (content_w - 16 - UI_G) / 2; btn_rec = lv_button_create(p_main); - lv_obj_set_size(btn_rec, btn_w, UI_BTN_H); - lv_obj_align(btn_rec, LV_ALIGN_TOP_LEFT, 0, btn_y); + lv_obj_set_size(btn_rec, btn_w, btn_h); + lv_obj_align(btn_rec, LV_ALIGN_BOTTOM_LEFT, 0, -18); style_btn(btn_rec, COL_REC); + lv_obj_set_ext_click_area(btn_rec, 16); lv_obj_add_event_cb(btn_rec, on_rec_clicked, LV_EVENT_CLICKED, nullptr); lbl_rec = lv_label_create(btn_rec); lv_label_set_text(lbl_rec, "REC"); @@ -297,9 +329,10 @@ static void create_ui(void) { lv_obj_center(lbl_rec); btn_play = lv_button_create(p_main); - lv_obj_set_size(btn_play, btn_w, UI_BTN_H); - lv_obj_align(btn_play, LV_ALIGN_TOP_RIGHT, 0, btn_y); + lv_obj_set_size(btn_play, btn_w, btn_h); + lv_obj_align(btn_play, LV_ALIGN_BOTTOM_RIGHT, 0, -18); style_btn(btn_play, COL_ACCENT); + lv_obj_set_ext_click_area(btn_play, 16); lv_obj_add_event_cb(btn_play, on_play_clicked, LV_EVENT_CLICKED, nullptr); lbl_play = lv_label_create(btn_play); lv_label_set_text(lbl_play, "PLAY"); @@ -309,7 +342,7 @@ static void create_ui(void) { lv_obj_center(lbl_play); lv_obj_t *hint2 = lv_label_create(p_main); - lv_label_set_text(hint2, "tap header: brightness | max 120s"); + lv_label_set_text(hint2, "bottom: REC|PLAY header: BL BOOT/r: REC"); lv_obj_set_style_text_font(hint2, &lv_font_montserrat_12, 0); lv_obj_set_style_text_color(hint2, COL_MUTED, 0); lv_obj_align(hint2, LV_ALIGN_BOTTOM_MID, 0, 0); diff --git a/src/touch.cpp b/src/touch.cpp index db6c29a..944fdc9 100644 --- a/src/touch.cpp +++ b/src/touch.cpp @@ -3,6 +3,18 @@ #include +/** + * 2.8": CYD28 SoftSPI bit-bang (hexeguitar) — frees VSPI for microSD. + * Coord feed matches Random Nerd Tutorials LVGL9 + ROTATION_270: + * map raw → 240×320 native, let LVGL rotate to landscape UI. + * 3.5C: GT911 Wire1; release INT before I2S SCK=21. + * + * Refs: + * - https://randomnerdtutorials.com/esp32-cyd-display-touchscreen-microsd-card/ + * - https://github.com/hexeguitar/CYD28_Touchscreen + * - https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/discussions/88 + */ + static int16_t clampi(int32_t v, int32_t lo, int32_t hi) { if (v < lo) return (int16_t)lo; if (v > hi) return (int16_t)hi; @@ -115,86 +127,32 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { #else -/* Bit-bang SoftSPI — does not share VSPI with microSD (tftest path). */ +#include -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(10); - digitalWrite(CYD_TOUCH_CLK, LOW); - delayMicroseconds(10); - } -} - -static uint16_t soft_read16(void) { - uint16_t v = 0; - for (int i = 0; i < 16; ++i) { - digitalWrite(CYD_TOUCH_CLK, HIGH); - delayMicroseconds(10); - v = (uint16_t)((v << 1) | (digitalRead(CYD_TOUCH_MISO) ? 1u : 0u)); - digitalWrite(CYD_TOUCH_CLK, LOW); - delayMicroseconds(10); - } - return v; -} - -/* One CS transaction: Z, X, Y (closer to XPT2046 lib sequence). */ -static void xpt_sample(uint16_t *x, uint16_t *y, uint16_t *z) { - digitalWrite(SD_CS, HIGH); - digitalWrite(CYD_TOUCH_CS, LOW); - delayMicroseconds(10); - - soft_write(0xB1); /* Z1 */ - uint16_t z1 = soft_read16() >> 3; - soft_write(0xC1); /* Z2 */ - uint16_t z2 = soft_read16() >> 3; - *z = (uint16_t)((z1 + 4095) - z2); - - soft_write(0x91); /* dummy X */ - (void)soft_read16(); - soft_write(0xD1); /* Y */ - uint16_t y0 = soft_read16() >> 3; - soft_write(0x91); /* X */ - uint16_t x0 = soft_read16() >> 3; - soft_write(0xD0); /* Y power-down */ - uint16_t y1 = soft_read16() >> 3; - soft_write(0x00); - uint16_t x1 = soft_read16() >> 3; - - digitalWrite(CYD_TOUCH_CS, HIGH); - - *x = (uint16_t)((x0 + x1) / 2); - *y = (uint16_t)((y0 + y1) / 2); -} +/* Native panel size — LVGL create(240,320) + ROTATION_270. */ +static CYD28_TouchR ts(SCREEN_WIDTH, SCREEN_HEIGHT); void touch_init() { pinMode(SD_CS, OUTPUT); digitalWrite(SD_CS, HIGH); - 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 Z/X/Y (SD-safe, no VSPI)"); + ts.begin(); + ts.setThreshold(40); /* idle z~10; press usually >>100 */ + Serial.println("Touch: CYD28 SoftSPI bitbang (SD-safe, poll) RNT map"); } void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { - uint16_t adc_x = 0, adc_y = 0, adc_z = 0; - xpt_sample(&adc_x, &adc_y, &adc_z); + digitalWrite(SD_CS, HIGH); + ts.isrWake = true; - /* SoftSPI Z on this board is noisy (~4095 idle); use X/Y window only. - * Idle typically x≈50; a real press lands both axes in mid-range. */ - (void)adc_z; - const bool down = - (adc_x > 200 && adc_x < 3900 && adc_y > 200 && adc_y < 3900); + CYD28_TS_Point p = ts.getPointRaw(); + /* z threshold only — x/y stay 0 until press updates them in library */ + const bool down = (p.z >= 40); static uint32_t last_log = 0; - if (down && millis() - last_log > 200) { + if (millis() - last_log > (down ? 120u : 500u)) { last_log = millis(); - Serial.printf("Touch soft x=%u y=%u\n", (unsigned)adc_x, (unsigned)adc_y); + Serial.printf("Touch raw(%d,%d) z=%d down=%d\n", (int)p.x, (int)p.y, + (int)p.z, (int)down); } if (!down) { @@ -202,24 +160,15 @@ void touch_read_cb(lv_indev_t * /*indev*/, lv_indev_data_t *data) { return; } - /* tftest SoftSPI → native feed for LVGL ROTATION_270 */ - const int16_t p_x = (int16_t)adc_x; - const int16_t p_y = (int16_t)(4095 - adc_y); - - int16_t x = map(p_x, 200, 3700, 1, SCREEN_WIDTH); - int16_t y = map(p_y, 240, 3800, 1, SCREEN_HEIGHT); + /* Random Nerd Tutorials LVGL9 mapping → native 240×320 feed + * (lv_display_set_rotation 270 transforms to 320×240 UI). */ + int16_t x = (int16_t)map(p.x, 200, 3700, 1, SCREEN_WIDTH); + int16_t y = (int16_t)map(p.y, 240, 3800, 1, SCREEN_HEIGHT); x = clampi(x, 0, SCREEN_WIDTH - 1); y = clampi(y, 0, SCREEN_HEIGHT - 1); - const int32_t old_ux = y; - const int32_t old_uy = (SCREEN_WIDTH - 1) - x; - int16_t ui_x = clampi((old_uy * (UI_HOR_RES - 1)) / (UI_VER_RES - 1), 0, - UI_HOR_RES - 1); - int16_t ui_y = clampi((old_ux * (UI_VER_RES - 1)) / (UI_HOR_RES - 1), 0, - UI_VER_RES - 1); - - data->point.x = (int16_t)((SCREEN_WIDTH - 1) - ui_y); - data->point.y = ui_x; + data->point.x = x; + data->point.y = y; data->state = LV_INDEV_STATE_PRESSED; }