From cea09c8b9ab9eb65c7dc6fc979f84cf878772a7b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 19 Nov 2023 17:25:42 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Tweak=20touch=20calibration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/HAL/LPC1768/tft/xpt2046.cpp | 7 +- Marlin/src/HAL/LPC1768/tft/xpt2046.h | 2 +- Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h | 2 +- Marlin/src/HAL/STM32/tft/gt911.cpp | 4 +- Marlin/src/HAL/STM32/tft/gt911.h | 2 +- Marlin/src/HAL/STM32/tft/xpt2046.cpp | 7 +- Marlin/src/HAL/STM32/tft/xpt2046.h | 2 +- Marlin/src/HAL/STM32F1/tft/xpt2046.cpp | 7 +- Marlin/src/HAL/STM32F1/tft/xpt2046.h | 2 +- Marlin/src/core/debug_out.h | 3 + Marlin/src/lcd/e3v2/jyersui/dwin.cpp | 10 +-- Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp | 10 +-- .../extui/mks_ui/tft_lvgl_configuration.cpp | 38 ++++------- Marlin/src/lcd/marlinui.cpp | 2 +- Marlin/src/lcd/marlinui.h | 2 +- Marlin/src/lcd/tft/touch.cpp | 66 +++++++++---------- Marlin/src/lcd/tft/touch.h | 38 ++++------- Marlin/src/lcd/tft_io/touch_calibration.cpp | 40 +++++------ Marlin/src/lcd/tft_io/touch_calibration.h | 63 ++++++++++++------ Marlin/src/lcd/touch/touch_buttons.cpp | 34 ++++++---- 20 files changed, 172 insertions(+), 169 deletions(-) diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp index 74596935e967..6c00a4cae0b2 100644 --- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp @@ -74,12 +74,11 @@ bool XPT2046::isTouched() { ); } -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; +bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { + if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return isTouched(); + return true; } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.h b/Marlin/src/HAL/LPC1768/tft/xpt2046.h index 8fdcacf92641..9a19e3c98de5 100644 --- a/Marlin/src/HAL/LPC1768/tft/xpt2046.h +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h @@ -79,5 +79,5 @@ class XPT2046 { #endif static void init(); - static bool getRawPoint(int16_t *x, int16_t *y); + static bool getRawPoint(int16_t * const x, int16_t * const y); }; diff --git a/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h index c546646d16fe..43a0791e0a23 100644 --- a/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h +++ b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h @@ -76,5 +76,5 @@ class XPT2046 { #endif static void init(); - static bool getRawPoint(int16_t *x, int16_t *y); + static bool getRawPoint(int16_t * const x, int16_t * const y); }; diff --git a/Marlin/src/HAL/STM32/tft/gt911.cpp b/Marlin/src/HAL/STM32/tft/gt911.cpp index 52119c19b794..e57bccfef31b 100644 --- a/Marlin/src/HAL/STM32/tft/gt911.cpp +++ b/Marlin/src/HAL/STM32/tft/gt911.cpp @@ -189,8 +189,8 @@ bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) { return false; } -bool GT911::getPoint(int16_t *x, int16_t *y) { - static bool touched = 0; +bool GT911::getRawPoint(int16_t * const x, int16_t * const y) { + static bool touched = false; static int16_t read_x = 0, read_y = 0; static millis_t next_time = 0; diff --git a/Marlin/src/HAL/STM32/tft/gt911.h b/Marlin/src/HAL/STM32/tft/gt911.h index 75e025245d62..989517c183b7 100644 --- a/Marlin/src/HAL/STM32/tft/gt911.h +++ b/Marlin/src/HAL/STM32/tft/gt911.h @@ -92,5 +92,5 @@ class GT911 { public: static void init(); static bool getFirstTouchPoint(int16_t *x, int16_t *y); - static bool getPoint(int16_t *x, int16_t *y); + static bool getRawPoint(int16_t * const x, int16_t * const y); }; diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp index f0c54f3690e9..57c50653c9ce 100644 --- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp @@ -119,12 +119,11 @@ bool XPT2046::isTouched() { ); } -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; +bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { + if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return isTouched(); + return true; } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.h b/Marlin/src/HAL/STM32/tft/xpt2046.h index 5ed0881ec68b..685c9441aedb 100644 --- a/Marlin/src/HAL/STM32/tft/xpt2046.h +++ b/Marlin/src/HAL/STM32/tft/xpt2046.h @@ -81,5 +81,5 @@ class XPT2046 { public: static void init(); - static bool getRawPoint(int16_t *x, int16_t *y); + static bool getRawPoint(int16_t * const x, int16_t * const y); }; diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp index 845a57a8147b..3428110c127e 100644 --- a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp @@ -86,12 +86,11 @@ bool XPT2046::isTouched() { ); } -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; +bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { + if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return isTouched(); + return true; } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.h b/Marlin/src/HAL/STM32F1/tft/xpt2046.h index 8fdcacf92641..9a19e3c98de5 100644 --- a/Marlin/src/HAL/STM32F1/tft/xpt2046.h +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.h @@ -79,5 +79,5 @@ class XPT2046 { #endif static void init(); - static bool getRawPoint(int16_t *x, int16_t *y); + static bool getRawPoint(int16_t * const x, int16_t * const y); }; diff --git a/Marlin/src/core/debug_out.h b/Marlin/src/core/debug_out.h index 6dd358997612..8f14f05c79f4 100644 --- a/Marlin/src/core/debug_out.h +++ b/Marlin/src/core/debug_out.h @@ -40,6 +40,7 @@ #undef DEBUG_ECHO_MSG #undef DEBUG_ERROR_MSG #undef DEBUG_WARN_MSG +#undef DEBUG_ECHO_TERNARY #undef DEBUG_EOL #undef DEBUG_FLUSH #undef DEBUG_POS @@ -67,6 +68,7 @@ #define DEBUG_ECHO_MSG SERIAL_ECHO_MSG #define DEBUG_ERROR_MSG SERIAL_ERROR_MSG #define DEBUG_WARN_MSG SERIAL_WARN_MSG + #define DEBUG_ECHO_TERNARY SERIAL_ECHO_TERNARY #define DEBUG_EOL SERIAL_EOL #define DEBUG_FLUSH SERIAL_FLUSH #define DEBUG_POS SERIAL_POS @@ -90,6 +92,7 @@ #define DEBUG_ECHO_MSG(...) NOOP #define DEBUG_ERROR_MSG(...) NOOP #define DEBUG_WARN_MSG(...) NOOP + #define DEBUG_ECHO_TERNARY(...) NOOP #define DEBUG_EOL() NOOP #define DEBUG_FLUSH() NOOP #define DEBUG_POS(...) NOOP diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index d945db8e588c..0222f1e1d045 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -389,9 +389,9 @@ class TextScroller { // Draw value text on if (viewer_print_value) { - int8_t offset_x, offset_y = cell_height_px / 2 - 6; + xy_int8_t offset { 0, cell_height_px / 2 - 6 }; if (isnan(bedlevel.z_values[x][y])) { // undefined - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset.y, F("X")); } else { // has value MString<12> msg; @@ -399,10 +399,10 @@ class TextScroller { msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2)); else msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100)); - offset_x = cell_width_px / 2 - 3 * msg.length() - 2; + offset.x = cell_width_px / 2 - 3 * msg.length() - 2; if (GRID_MAX_POINTS_X >= 10) - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F(".")); - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, msg); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset.x, start_y_px + offset.y /*+ square / 2 - 6*/, F(".")); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset.x, start_y_px + offset.y /*+ square / 2 - 6*/, msg); } safe_delay(10); LCD_SERIAL.flushTX(); diff --git a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp index db6c76269ca8..87930a18799e 100644 --- a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp +++ b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp @@ -247,9 +247,9 @@ bool BedLevelTools::meshValidate() { // Draw value text on const uint8_t fs = DWINUI::fontWidth(meshfont); if (viewer_print_value) { - int8_t offset_x, offset_y = cell_height_px / 2 - fs; + xy_int8_t offset { 0, cell_height_px / 2 - fs }; if (isnan(bedlevel.z_values[x][y])) { // undefined - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset.y, F("X")); } else { // has value MString<12> msg; @@ -257,10 +257,10 @@ bool BedLevelTools::meshValidate() { msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2)); else msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100)); - offset_x = cell_width_px / 2 - (fs / 2) * msg.length() - 2; + offset.x = cell_width_px / 2 - (fs / 2) * msg.length() - 2; if ((GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10)) - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y, F(".")); - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y, msg); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset.x, start_y_px + offset.y, F(".")); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset.x, start_y_px + offset.y, msg); } safe_delay(10); LCD_SERIAL.flushTX(); diff --git a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp index a53e0d606b7c..7adce94c2fa6 100644 --- a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp +++ b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp @@ -55,8 +55,8 @@ XPT2046 touch; #include "../../../module/probe.h" #endif +#include "../../tft_io/touch_calibration.h" #if ENABLED(TOUCH_SCREEN_CALIBRATION) - #include "../../tft_io/touch_calibration.h" #include "draw_touch_calibration.h" #endif @@ -305,45 +305,33 @@ uint16_t getTickDiff(const uint16_t curTick, const uint16_t lastTick) { return (TICK_CYCLE) * (lastTick <= curTick ? (curTick - lastTick) : (0xFFFFFFFF - lastTick + curTick)); } -static bool get_point(int16_t *x, int16_t *y) { - if (!touch.getRawPoint(x, y)) return false; +static bool get_point(xy_int_t &point) { + if (!touch.getRawPoint(&point.x, &point.y)) return false; #if ENABLED(TOUCH_SCREEN_CALIBRATION) const calibrationState state = touch_calibration.get_calibration_state(); if (WITHIN(state, CALIBRATION_TOP_LEFT, CALIBRATION_BOTTOM_LEFT)) { - if (touch_calibration.handleTouch(*x, *y)) lv_update_touch_calibration_screen(); + if (touch_calibration.handleTouch(point)) lv_update_touch_calibration_screen(); return false; } - *x = int16_t((int32_t(*x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x; - *y = int16_t((int32_t(*y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y; - #else - *x = int16_t((int32_t(*x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X; - *y = int16_t((int32_t(*y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y; #endif + point.x = int16_t((int32_t(point.x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + point.y = int16_t((int32_t(point.y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + return true; } bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { - static int16_t last_x = 0, last_y = 0; - if (get_point(&last_x, &last_y)) { - #if TFT_ROTATION == TFT_ROTATE_180 - data->point.x = TFT_WIDTH - last_x; - data->point.y = TFT_HEIGHT - last_y; - #else - data->point.x = last_x; - data->point.y = last_y; - #endif + static xy_int_t last { 0, 0 }; + if (get_point(last)) { + data->point.x = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_WIDTH - last.x : last.x; + data->point.y = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_HEIGHT - last.y : last.y; data->state = LV_INDEV_STATE_PR; } else { - #if TFT_ROTATION == TFT_ROTATE_180 - data->point.x = TFT_WIDTH - last_x; - data->point.y = TFT_HEIGHT - last_y; - #else - data->point.x = last_x; - data->point.y = last_y; - #endif + data->point.x = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_WIDTH - last.x : last.x; + data->point.y = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_HEIGHT - last.y : last.y; data->state = LV_INDEV_STATE_REL; } return false; // Return `false` since no data is buffering or left to read diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index fa511b4882cb..49b9fecad8ae 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -408,7 +408,7 @@ void MarlinUI::init() { #if HAS_TOUCH_BUTTONS uint8_t MarlinUI::touch_buttons; - uint8_t MarlinUI::repeat_delay; + uint16_t MarlinUI::repeat_delay; #endif #if ANY(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 69235dda36b9..7dd5b6b2d83d 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -660,7 +660,7 @@ class MarlinUI { #if HAS_TOUCH_BUTTONS static uint8_t touch_buttons; - static uint8_t repeat_delay; + static uint16_t repeat_delay; #else static constexpr uint8_t touch_buttons = 0; #endif diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp index 3de0f4f42aa4..4d5056183bb9 100644 --- a/Marlin/src/lcd/tft/touch.cpp +++ b/Marlin/src/lcd/tft/touch.cpp @@ -39,7 +39,7 @@ #include "tft.h" bool Touch::enabled = true; -int16_t Touch::x, Touch::y; +xy_int_t Touch::point; touch_control_t Touch::controls[]; touch_control_t *Touch::current_control; uint16_t Touch::controls_count; @@ -67,18 +67,13 @@ void Touch::add_control(TouchControlType type, uint16_t x, uint16_t y, uint16_t if (controls_count == MAX_CONTROLS) return; controls[controls_count].type = type; - controls[controls_count].x = x; - controls[controls_count].y = y; - controls[controls_count].width = width; - controls[controls_count].height = height; + controls[controls_count].pos.set(x, y); + controls[controls_count].size.set(width, height); controls[controls_count].data = data; controls_count++; } void Touch::idle() { - uint16_t i; - int16_t _x, _y; - if (!enabled) return; // Return if Touch::idle is called within the same millisecond @@ -86,7 +81,8 @@ void Touch::idle() { if (now <= next_touch_ms) return; next_touch_ms = now; - if (get_point(&_x, &_y)) { + xy_int_t got_point; + if (get_point(got_point)) { #if HAS_RESUME_CONTINUE // UI is waiting for a click anywhere? if (wait_for_user) { @@ -110,19 +106,24 @@ void Touch::idle() { if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME; if (PENDING(now, time_to_hold)) return; - if (x != 0 && y != 0) { + if (bool(point)) { if (current_control) { - if (WITHIN(x, current_control->x - FREE_MOVE_RANGE, current_control->x + current_control->width + FREE_MOVE_RANGE) && WITHIN(y, current_control->y - FREE_MOVE_RANGE, current_control->y + current_control->height + FREE_MOVE_RANGE)) { - LIMIT(x, current_control->x, current_control->x + current_control->width); - LIMIT(y, current_control->y, current_control->y + current_control->height); + if ( WITHIN(point.x, current_control->pos.x - FREE_MOVE_RANGE, current_control->pos.x + current_control->size.x + FREE_MOVE_RANGE) + && WITHIN(point.y, current_control->pos.y - FREE_MOVE_RANGE, current_control->pos.y + current_control->size.y + FREE_MOVE_RANGE) + ) { + LIMIT(point.x, current_control->pos.x, current_control->pos.x + current_control->size.x); + LIMIT(point.y, current_control->pos.y, current_control->pos.y + current_control->size.y); touch(current_control); } else current_control = nullptr; } else { - for (i = 0; i < controls_count; i++) { - if ((WITHIN(x, controls[i].x, controls[i].x + controls[i].width) && WITHIN(y, controls[i].y, controls[i].y + controls[i].height)) || (TERN(TOUCH_SCREEN_CALIBRATION, controls[i].type == CALIBRATE, false))) { + for (uint16_t i = 0; i < controls_count; i++) { + if (TERN0(TOUCH_SCREEN_CALIBRATION, controls[i].type == CALIBRATE) + || ( WITHIN(point.x, controls[i].pos.x, controls[i].pos.x + controls[i].size.x) + && WITHIN(point.y, controls[i].pos.y, controls[i].pos.y + controls[i].size.y)) + ) { touch_control_type = controls[i].type; touch(&controls[i]); break; @@ -133,11 +134,10 @@ void Touch::idle() { if (!current_control) touch_time = now; } - x = _x; - y = _y; + point = got_point; } else { - x = y = 0; + point.reset(); current_control = nullptr; touch_time = 0; touch_control_type = NONE; @@ -150,7 +150,7 @@ void Touch::touch(touch_control_t *control) { switch (control->type) { #if ENABLED(TOUCH_SCREEN_CALIBRATION) case CALIBRATE: - if (touch_calibration.handleTouch(x, y)) ui.refresh(); + if (touch_calibration.handleTouch(point)) ui.refresh(); break; #endif @@ -177,7 +177,7 @@ void Touch::touch(touch_control_t *control) { ui.encoderPosition = ui.encoderPosition + LCD_HEIGHT < (uint32_t)screen_items ? ui.encoderPosition + LCD_HEIGHT : screen_items; ui.refresh(); break; - case SLIDER: hold(control); ui.encoderPosition = (x - control->x) * control->data / control->width; break; + case SLIDER: hold(control); ui.encoderPosition = (point.x - control->pos.x) * control->data / control->size.x; break; case INCREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff++ : ui.encoderPosition++, ui.encoderPosition++); break; case DECREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff-- : ui.encoderPosition--, ui.encoderPosition--); break; case HEATER: @@ -263,28 +263,26 @@ void Touch::hold(touch_control_t *control, millis_t delay) { ui.refresh(); } -bool Touch::get_point(int16_t *x, int16_t *y) { - #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) - #if ENABLED(TOUCH_SCREEN_CALIBRATION) - const bool is_touched = (touch_calibration.calibration.orientation == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); - if (is_touched && touch_calibration.calibration.orientation != TOUCH_ORIENTATION_NONE) { - *x = int16_t((int32_t(*x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x; - *y = int16_t((int32_t(*y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y; - } - #else - const bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); - *x = uint16_t((uint32_t(*x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X; - *y = uint16_t((uint32_t(*y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y; +bool Touch::get_point(xy_int_t &point) { + bool is_touched = false; + #if ANY(TFT_TOUCH_DEVICE_XPT2046, TFT_TOUCH_DEVICE_GT911) + is_touched = (TOUCH_ORIENTATION_NONE != _TOUCH_ORIENTATION) + && (TOUCH_PORTRAIT == _TOUCH_ORIENTATION + ? io.getRawPoint(&point.y, &point.x) + : io.getRawPoint(&point.x, &point.y)); + #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) + point.x = uint16_t((uint32_t(point.x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + point.y = uint16_t((uint32_t(point.y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; #endif - #elif ENABLED(TFT_TOUCH_DEVICE_GT911) - const bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getPoint(y, x) : io.getPoint(x, y)); #endif + #if HAS_TOUCH_SLEEP if (is_touched) wakeUp(); else if (!isSleeping() && ELAPSED(millis(), next_sleep_ms) && ui.on_status_screen()) sleepTimeout(); #endif + return is_touched; } diff --git a/Marlin/src/lcd/tft/touch.h b/Marlin/src/lcd/tft/touch.h index 16f51bfaaa31..6c0ff88f4674 100644 --- a/Marlin/src/lcd/tft/touch.h +++ b/Marlin/src/lcd/tft/touch.h @@ -22,10 +22,7 @@ #pragma once #include "../../inc/MarlinConfigPre.h" - -#if ENABLED(TOUCH_SCREEN_CALIBRATION) - #include "../tft_io/touch_calibration.h" -#endif +#include "../tft_io/touch_calibration.h" #if ENABLED(TFT_TOUCH_DEVICE_GT911) #include HAL_PATH(../.., tft/gt911.h) @@ -43,34 +40,25 @@ extern int8_t encoderTopLine, encoderLine, screen_items; enum TouchControlType : uint16_t { NONE = 0x0000, CALIBRATE, - MENU_SCREEN, - MENU_ITEM, + MENU_SCREEN, MENU_ITEM, BACK, - PAGE_UP, - PAGE_DOWN, - CLICK, - MENU_CLICK, + PAGE_UP, PAGE_DOWN, + CLICK, MENU_CLICK, RESUME_CONTINUE, SLIDER, - INCREASE, - DECREASE, - CANCEL, - CONFIRM, - HEATER, - FAN, - FEEDRATE, - FLOWRATE, + INCREASE, DECREASE, + CANCEL, CONFIRM, + HEATER, FAN, + FEEDRATE, FLOWRATE, UBL, STOP, - BUTTON, + BUTTON }; typedef struct __attribute__((__packed__)) { TouchControlType type; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; + xy_uint_t pos; + xy_uint_t size; intptr_t data; } touch_control_t; @@ -87,7 +75,7 @@ typedef struct __attribute__((__packed__)) { class Touch { private: static TOUCH_DRIVER_CLASS io; - static int16_t x, y; + static xy_int_t point; static bool enabled; static touch_control_t controls[MAX_CONTROLS]; @@ -97,7 +85,7 @@ class Touch { static millis_t next_touch_ms, time_to_hold, repeat_delay, touch_time; static TouchControlType touch_control_type; - static bool get_point(int16_t *x, int16_t *y); + static bool get_point(xy_int_t &point); static void touch(touch_control_t *control); static void hold(touch_control_t *control, millis_t delay=0); diff --git a/Marlin/src/lcd/tft_io/touch_calibration.cpp b/Marlin/src/lcd/tft_io/touch_calibration.cpp index 3cd73fe6204c..b1cdfe6cda94 100644 --- a/Marlin/src/lcd/tft_io/touch_calibration.cpp +++ b/Marlin/src/lcd/tft_io/touch_calibration.cpp @@ -55,21 +55,21 @@ void TouchCalibration::validate_calibration() { && VALIDATE_PRECISION(x, BOTTOM_LEFT, BOTTOM_RIGHT); #undef VALIDATE_PRECISION - #define CAL_PTS(N) calibration_points[CALIBRATION_##N] + #define CP(N) calibration_points[CALIBRATION_##N] if (landscape) { calibration_state = CALIBRATION_SUCCESS; - calibration.x = ((CAL_PTS(TOP_RIGHT).x - CAL_PTS(TOP_LEFT).x) << 17) / (CAL_PTS(BOTTOM_RIGHT).raw_x + CAL_PTS(TOP_RIGHT).raw_x - CAL_PTS(BOTTOM_LEFT).raw_x - CAL_PTS(TOP_LEFT).raw_x); - calibration.y = ((CAL_PTS(BOTTOM_LEFT).y - CAL_PTS(TOP_LEFT).y) << 17) / (CAL_PTS(BOTTOM_RIGHT).raw_y - CAL_PTS(TOP_RIGHT).raw_y + CAL_PTS(BOTTOM_LEFT).raw_y - CAL_PTS(TOP_LEFT).raw_y); - calibration.offset_x = CAL_PTS(TOP_LEFT).x - int16_t(((CAL_PTS(TOP_LEFT).raw_x + CAL_PTS(BOTTOM_LEFT).raw_x) * calibration.x) >> 17); - calibration.offset_y = CAL_PTS(TOP_LEFT).y - int16_t(((CAL_PTS(TOP_LEFT).raw_y + CAL_PTS(TOP_RIGHT).raw_y) * calibration.y) >> 17); + calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw.x + CP(TOP_RIGHT).raw.x - CP(BOTTOM_LEFT).raw.x - CP(TOP_LEFT).raw.x); + calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw.y - CP(TOP_RIGHT).raw.y + CP(BOTTOM_LEFT).raw.y - CP(TOP_LEFT).raw.y); + calibration.offset.x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw.x + CP(BOTTOM_LEFT).raw.x) * calibration.x) >> 17); + calibration.offset.y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw.y + CP(TOP_RIGHT).raw.y) * calibration.y) >> 17); calibration.orientation = TOUCH_LANDSCAPE; } else if (portrait) { calibration_state = CALIBRATION_SUCCESS; - calibration.x = ((CAL_PTS(TOP_RIGHT).x - CAL_PTS(TOP_LEFT).x) << 17) / (CAL_PTS(BOTTOM_RIGHT).raw_y + CAL_PTS(TOP_RIGHT).raw_y - CAL_PTS(BOTTOM_LEFT).raw_y - CAL_PTS(TOP_LEFT).raw_y); - calibration.y = ((CAL_PTS(BOTTOM_LEFT).y - CAL_PTS(TOP_LEFT).y) << 17) / (CAL_PTS(BOTTOM_RIGHT).raw_x - CAL_PTS(TOP_RIGHT).raw_x + CAL_PTS(BOTTOM_LEFT).raw_x - CAL_PTS(TOP_LEFT).raw_x); - calibration.offset_x = CAL_PTS(TOP_LEFT).x - int16_t(((CAL_PTS(TOP_LEFT).raw_y + CAL_PTS(BOTTOM_LEFT).raw_y) * calibration.x) >> 17); - calibration.offset_y = CAL_PTS(TOP_LEFT).y - int16_t(((CAL_PTS(TOP_LEFT).raw_x + CAL_PTS(TOP_RIGHT).raw_x) * calibration.y) >> 17); + calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw.y + CP(TOP_RIGHT).raw.y - CP(BOTTOM_LEFT).raw.y - CP(TOP_LEFT).raw.y); + calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw.x - CP(TOP_RIGHT).raw.x + CP(BOTTOM_LEFT).raw.x - CP(TOP_LEFT).raw.x); + calibration.offset.x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw.y + CP(BOTTOM_LEFT).raw.y) * calibration.x) >> 17); + calibration.offset.y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw.x + CP(TOP_RIGHT).raw.x) * calibration.y) >> 17); calibration.orientation = TOUCH_PORTRAIT; } else { @@ -77,29 +77,29 @@ void TouchCalibration::validate_calibration() { calibration_reset(); if (need_calibration() && failed_count++ < TOUCH_CALIBRATION_MAX_RETRIES) calibration_state = CALIBRATION_NONE; } - #undef CAL_PTS + #undef CP if (calibration_state == CALIBRATION_SUCCESS) { SERIAL_ECHOLNPGM("Touch screen calibration completed"); - SERIAL_ECHOLNPGM("TOUCH_CALIBRATION_X ", calibration.x); - SERIAL_ECHOLNPGM("TOUCH_CALIBRATION_Y ", calibration.y); - SERIAL_ECHOLNPGM("TOUCH_OFFSET_X ", calibration.offset_x); - SERIAL_ECHOLNPGM("TOUCH_OFFSET_Y ", calibration.offset_y); - SERIAL_ECHO_TERNARY(calibration.orientation == TOUCH_LANDSCAPE, "TOUCH_ORIENTATION ", "TOUCH_LANDSCAPE", "TOUCH_PORTRAIT", "\n"); + SERIAL_ECHOLN(F("#define TOUCH_"), F("CALIBRATION_X "), calibration.x); + SERIAL_ECHOLN(F("#define TOUCH_"), F("CALIBRATION_Y "), calibration.y); + SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_X "), calibration.offset.x); + SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_Y "), calibration.offset.y); + SERIAL_ECHO(F("#define TOUCH_")); SERIAL_ECHO_TERNARY(calibration.orientation == TOUCH_LANDSCAPE, "ORIENTATION ", "TOUCH_LANDSCAPE", "TOUCH_PORTRAIT", "\n"); TERN_(TOUCH_CALIBRATION_AUTO_SAVE, settings.save()); } } -bool TouchCalibration::handleTouch(const uint16_t x, const uint16_t y) { +bool TouchCalibration::handleTouch(const xy_int_t &point) { const millis_t now = millis(); - if (next_touch_update_ms && PENDING(now, next_touch_update_ms)) return false; next_touch_update_ms = now + BUTTON_DELAY_MENU; if (calibration_state < CALIBRATION_SUCCESS) { - calibration_points[calibration_state].raw_x = x; - calibration_points[calibration_state].raw_y = y; - DEBUG_ECHOLNPGM("TouchCalibration - State: ", calibration_state, ", x: ", calibration_points[calibration_state].x, ", raw_x: ", x, ", y: ", calibration_points[calibration_state].y, ", raw_y: ", y); + calibration_points[calibration_state].raw = point; + DEBUG_ECHOLNPGM("TouchCalibration - State: ", calibration_state, + ", x: ", calibration_points[calibration_state].x, ", raw.x: ", point.x, + ", y: ", calibration_points[calibration_state].y, ", raw.y: ", point.y); } switch (calibration_state) { diff --git a/Marlin/src/lcd/tft_io/touch_calibration.h b/Marlin/src/lcd/tft_io/touch_calibration.h index 2dd8a81ab7cc..be226db224cc 100644 --- a/Marlin/src/lcd/tft_io/touch_calibration.h +++ b/Marlin/src/lcd/tft_io/touch_calibration.h @@ -23,6 +23,14 @@ #include "../../inc/MarlinConfig.h" +#if ENABLED(TOUCH_SCREEN_CALIBRATION) + +#define _TOUCH_CALIBRATION_X touch_calibration.calibration.x +#define _TOUCH_CALIBRATION_Y touch_calibration.calibration.y +#define _TOUCH_OFFSET_X touch_calibration.calibration.offset.x +#define _TOUCH_OFFSET_Y touch_calibration.calibration.offset.y +#define _TOUCH_ORIENTATION touch_calibration.calibration.orientation + #ifndef TOUCH_SCREEN_CALIBRATION_PRECISION #define TOUCH_SCREEN_CALIBRATION_PRECISION 80 #endif @@ -30,15 +38,22 @@ #define TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS 2500 #endif -typedef struct __attribute__((__packed__)) { - int32_t x, y; - int16_t offset_x, offset_y; +typedef struct __attribute__((__packed__)) TouchCal : xy_long_t { + xy_int_t offset; uint8_t orientation; + TouchCal() { set(xy_long_t({ 0, 0 }), xy_int_t({ 0, 0 }), TOUCH_ORIENTATION_NONE); } + void set(const xy_long_t &xy, const xy_int_t &hv, const uint8_t o) { + xy_long_t::set(xy); offset = hv; orientation = o; + } + void reset() { + set(xy_long_t({ TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y }), + xy_int_t({ TOUCH_OFFSET_X, TOUCH_OFFSET_Y }), + TOUCH_ORIENTATION); + } } touch_calibration_t; -typedef struct __attribute__((__packed__)) { - uint16_t x, y; - int16_t raw_x, raw_y; +typedef struct __attribute__((__packed__)) : xy_uint_t { + xy_int_t raw; } touch_calibration_point_t; enum calibrationState : uint8_t { @@ -57,28 +72,24 @@ class TouchCalibration { static touch_calibration_point_t calibration_points[4]; static millis_t next_touch_update_ms; - static bool validate_precision(int32_t a, int32_t b) { return (a > b ? (100 * b) / a : (100 * a) / b) > TOUCH_SCREEN_CALIBRATION_PRECISION; } - static bool validate_precision_x(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_x, calibration_points[b].raw_x); } - static bool validate_precision_y(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_y, calibration_points[b].raw_y); } + static bool validate_precision(int32_t a, int32_t b) { return (a > b ? (100 * b) / a : (100 * a) / b) > (TOUCH_SCREEN_CALIBRATION_PRECISION); } + static bool validate_precision_x(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw.x, calibration_points[b].raw.x); } + static bool validate_precision_y(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw.y, calibration_points[b].raw.y); } static void validate_calibration(); static touch_calibration_t calibration; static uint8_t failed_count; - static void calibration_reset() { calibration = { TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y, TOUCH_OFFSET_X, TOUCH_OFFSET_Y, TOUCH_ORIENTATION }; } - static bool need_calibration() { return !calibration.offset_x && !calibration.offset_y && !calibration.x && !calibration.y; } + static void calibration_reset() { calibration.set(xy_long_t({ TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y }), xy_int_t({ TOUCH_OFFSET_X, TOUCH_OFFSET_Y }), TOUCH_ORIENTATION); } + static bool need_calibration() { return !(calibration.offset.x || calibration.offset.y || calibration.x || calibration.y); } static calibrationState calibration_start() { next_touch_update_ms = millis() + 750UL; - calibration = { 0, 0, 0, 0, TOUCH_ORIENTATION_NONE }; + calibration.reset(); calibration_state = CALIBRATION_TOP_LEFT; - calibration_points[CALIBRATION_TOP_LEFT].x = 30; - calibration_points[CALIBRATION_TOP_LEFT].y = 30; - calibration_points[CALIBRATION_TOP_RIGHT].x = TFT_WIDTH - 31; - calibration_points[CALIBRATION_TOP_RIGHT].y = 30; - calibration_points[CALIBRATION_BOTTOM_RIGHT].x = TFT_WIDTH - 31; - calibration_points[CALIBRATION_BOTTOM_RIGHT].y = TFT_HEIGHT - 31; - calibration_points[CALIBRATION_BOTTOM_LEFT].x = 30; - calibration_points[CALIBRATION_BOTTOM_LEFT].y = TFT_HEIGHT - 31; + calibration_points[CALIBRATION_TOP_LEFT].set(30, 30); + calibration_points[CALIBRATION_TOP_RIGHT].set(TFT_WIDTH - 31, 30); + calibration_points[CALIBRATION_BOTTOM_RIGHT].set(TFT_WIDTH - 31, TFT_HEIGHT - 31); + calibration_points[CALIBRATION_BOTTOM_LEFT].set(30, TFT_HEIGHT - 31); failed_count = 0; return calibration_state; } @@ -89,7 +100,17 @@ class TouchCalibration { return !need_calibration(); } - static bool handleTouch(const uint16_t x, const uint16_t y); + static bool handleTouch(const xy_int_t &point); }; extern TouchCalibration touch_calibration; + +#else // TOUCH_SCREEN_CALIBRATION + +#define _TOUCH_CALIBRATION_X (TOUCH_CALIBRATION_X) +#define _TOUCH_CALIBRATION_Y (TOUCH_CALIBRATION_Y) +#define _TOUCH_OFFSET_X (TOUCH_OFFSET_X) +#define _TOUCH_OFFSET_Y (TOUCH_OFFSET_Y) +#define _TOUCH_ORIENTATION (TOUCH_ORIENTATION) + +#endif diff --git a/Marlin/src/lcd/touch/touch_buttons.cpp b/Marlin/src/lcd/touch/touch_buttons.cpp index 1ae5397b2ef6..636a31dafa41 100644 --- a/Marlin/src/lcd/touch/touch_buttons.cpp +++ b/Marlin/src/lcd/touch/touch_buttons.cpp @@ -37,10 +37,6 @@ #error "Unknown Touch Screen Type." #endif -#if ENABLED(TOUCH_SCREEN_CALIBRATION) - #include "../tft_io/touch_calibration.h" -#endif - #if HAS_TOUCH_SLEEP millis_t TouchButtons::next_sleep_ms; #endif @@ -48,6 +44,7 @@ #include "../buttons.h" // For EN_C bit mask #include "../marlinui.h" // For ui.refresh #include "../tft_io/tft_io.h" +#include "../tft_io/touch_calibration.h" #define DOGM_AREA_LEFT TFT_PIXEL_OFFSET_X #define DOGM_AREA_TOP TFT_PIXEL_OFFSET_Y @@ -69,30 +66,41 @@ uint8_t TouchButtons::read_buttons() { int16_t x, y; #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) - const bool is_touched = (TERN(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration.orientation, TOUCH_ORIENTATION) == TOUCH_PORTRAIT ? touchIO.getRawPoint(&y, &x) : touchIO.getRawPoint(&x, &y)); + const bool is_touched = TOUCH_PORTRAIT == _TOUCH_ORIENTATION + ? touchIO.getRawPoint(&y, &x) + : touchIO.getRawPoint(&x, &y); #if HAS_TOUCH_SLEEP if (is_touched) wakeUp(); else if (!isSleeping() && ELAPSED(millis(), next_sleep_ms) && ui.on_status_screen()) sleepTimeout(); #endif - if (!is_touched) return 0; + + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + static bool no_touch = false; + #endif + + if (!is_touched) { + TERN_(TOUCH_SCREEN_CALIBRATION, no_touch = false); + return 0; + } #if ENABLED(TOUCH_SCREEN_CALIBRATION) const calibrationState state = touch_calibration.get_calibration_state(); if (WITHIN(state, CALIBRATION_TOP_LEFT, CALIBRATION_BOTTOM_LEFT)) { - if (touch_calibration.handleTouch(x, y)) ui.refresh(); + if (!no_touch && touch_calibration.handleTouch(xy_int_t({x, y}))) ui.refresh(); + no_touch = true; return 0; } - x = int16_t((int32_t(x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x; - y = int16_t((int32_t(y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y; - #else - x = uint16_t((uint32_t(x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X; - y = uint16_t((uint32_t(y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y; #endif + x = uint16_t((uint32_t(x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + y = uint16_t((uint32_t(y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + #elif ENABLED(TFT_TOUCH_DEVICE_GT911) - const bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? touchIO.getPoint(&y, &x) : touchIO.getPoint(&x, &y)); + + const bool is_touched = TOUCH_PORTRAIT == _TOUCH_ORIENTATION ? touchIO.getRawPoint(&y, &x) : touchIO.getRawPoint(&x, &y); if (!is_touched) return 0; + #endif // Touch within the button area simulates an encoder button