Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch fixes #26455

Merged
merged 2 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ 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 true;
return isTouched();
}

uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/HAL/STM32/tft/xpt2046.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ 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 true;
return isTouched();
}

uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/HAL/STM32F1/tft/xpt2046.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ 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 true;
return isTouched();
}

uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
Expand Down
10 changes: 5 additions & 5 deletions Marlin/src/lcd/e3v2/jyersui/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,20 +389,20 @@ class TextScroller {

// Draw value text on
if (viewer_print_value) {
xy_uint_t offset { 0, cell_height_px / 2 - 6 };
const int8_t offset_y = 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;
if (GRID_MAX_POINTS_X < 10)
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;
const int8_t 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();
Expand Down
10 changes: 5 additions & 5 deletions Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,20 +247,20 @@ bool BedLevelTools::meshValidate() {
// Draw value text on
const uint8_t fs = DWINUI::fontWidth(meshfont);
if (viewer_print_value) {
xy_uint_t offset { 0, cell_height_px / 2 - fs };
const int8_t offset_y = 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;
if ((GRID_MAX_POINTS_X) < TERN(TJC_DISPLAY, 8, 10))
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;
const int8_t 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();
Expand Down
23 changes: 8 additions & 15 deletions Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,35 +305,28 @@ 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(xy_int_t &point) {
if (!touch.getRawPoint(&point.x, &point.y)) return false;
static bool get_point(int16_t * const x, int16_t * const y) {
if (!touch.getRawPoint(x, 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(point)) lv_update_touch_calibration_screen();
if (touch_calibration.handleTouch(*x, *y)) lv_update_touch_calibration_screen();
return false;
}
#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;
*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;

return true;
}

bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
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 {
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;
}
data->state = get_point(&last.x, &last.y) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
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;
return false; // Return `false` since no data is buffering or left to read
}

Expand Down
58 changes: 30 additions & 28 deletions Marlin/src/lcd/tft/touch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "tft.h"

bool Touch::enabled = true;
xy_int_t Touch::point;
int16_t Touch::x, Touch::y;
touch_control_t Touch::controls[];
touch_control_t *Touch::current_control;
uint16_t Touch::controls_count;
Expand Down Expand Up @@ -67,22 +67,25 @@ 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].pos.set(x, y);
controls[controls_count].size.set(width, height);
controls[controls_count].x = x;
controls[controls_count].y = y;
controls[controls_count].width = width;
controls[controls_count].height = height;
controls[controls_count].data = data;
controls_count++;
}

void Touch::idle() {
int16_t _x, _y;

if (!enabled) return;

// Return if Touch::idle is called within the same millisecond
const millis_t now = millis();
if (now <= next_touch_ms) return;
next_touch_ms = now;

xy_int_t got_point;
if (get_point(got_point)) {
if (get_point(&_x, &_y)) {
#if HAS_RESUME_CONTINUE
// UI is waiting for a click anywhere?
if (wait_for_user) {
Expand All @@ -106,24 +109,19 @@ void Touch::idle() {
if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME;
if (PENDING(now, time_to_hold)) return;

if (bool(point)) {
if (x != 0 && y != 0) {
if (current_control) {
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);
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);
touch(current_control);
}
else
current_control = nullptr;
}
else {
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))
) {
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))) {
touch_control_type = controls[i].type;
touch(&controls[i]);
break;
Expand All @@ -134,10 +132,11 @@ void Touch::idle() {
if (!current_control)
touch_time = now;
}
point = got_point;
x = _x;
y = _y;
}
else {
point.reset();
x = y = 0;
current_control = nullptr;
touch_time = 0;
touch_control_type = NONE;
Expand All @@ -150,7 +149,7 @@ void Touch::touch(touch_control_t *control) {
switch (control->type) {
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
case CALIBRATE:
if (touch_calibration.handleTouch(point)) ui.refresh();
if (touch_calibration.handleTouch(x, y)) ui.refresh();
break;
#endif

Expand All @@ -177,7 +176,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 = (point.x - control->pos.x) * control->data / control->size.x; break;
case SLIDER: hold(control); ui.encoderPosition = (x - control->x) * control->data / control->width; 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:
Expand Down Expand Up @@ -263,16 +262,19 @@ void Touch::hold(touch_control_t *control, millis_t delay) {
ui.refresh();
}

bool Touch::get_point(xy_int_t &point) {
bool is_touched = false;
bool Touch::get_point(int16_t * const x, int16_t * const y) {
#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;
const bool is_touched = TOUCH_PORTRAIT == _TOUCH_ORIENTATION ? io.getRawPoint(y, x) : io.getRawPoint(x, y);
#endif
#if ENABLED(TFT_TOUCH_DEVICE_XPT2046)
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
if (is_touched && TOUCH_ORIENTATION_NONE != _TOUCH_ORIENTATION) {
*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;
}
#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
#endif

Expand Down
10 changes: 6 additions & 4 deletions Marlin/src/lcd/tft/touch.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ enum TouchControlType : uint16_t {

typedef struct __attribute__((__packed__)) {
TouchControlType type;
xy_uint_t pos;
xy_uint_t size;
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
intptr_t data;
} touch_control_t;

Expand All @@ -75,7 +77,7 @@ typedef struct __attribute__((__packed__)) {
class Touch {
private:
static TOUCH_DRIVER_CLASS io;
static xy_int_t point;
static int16_t x, y;
static bool enabled;

static touch_control_t controls[MAX_CONTROLS];
Expand All @@ -85,7 +87,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(xy_int_t &point);
static bool get_point(int16_t * const x, int16_t * const y);
static void touch(touch_control_t *control);
static void hold(touch_control_t *control, millis_t delay=0);

Expand Down
30 changes: 15 additions & 15 deletions Marlin/src/lcd/tft_io/touch_calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,18 @@ void TouchCalibration::validate_calibration() {
#define CP(N) calibration_points[CALIBRATION_##N]
if (landscape) {
calibration_state = CALIBRATION_SUCCESS;
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.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 = ((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.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 {
Expand All @@ -83,23 +83,23 @@ void TouchCalibration::validate_calibration() {
SERIAL_ECHOLNPGM("Touch screen calibration completed");
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_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 xy_int_t &point) {
bool TouchCalibration::handleTouch(const uint16_t x, const uint16_t y) {
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 = 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);
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);
}

switch (calibration_state) {
Expand Down
Loading
Loading