From cd58fcae4fb0e4eb8eafc8f9b473decb79e865ea Mon Sep 17 00:00:00 2001 From: suchmememanyskill <38142618+suchmememanyskill@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:26:09 +0100 Subject: [PATCH] Move touch calibration to lv_conf, implement invert colors in smartdisplay driver --- .../boards/esp32-2432S028R-smartdisplay.json | 3 +- CYD-Klipper/extract_commit.py | 8 +- CYD-Klipper/src/conf/lv_conf.h | 6 +- .../src/core/device/ESP32-2432S028R.cpp | 69 +------- .../src/core/device/ESP32-smartdisplay.cpp | 30 +++- CYD-Klipper/src/core/lv_setup.cpp | 156 +++++++++++++++--- CYD-Klipper/src/core/screen_driver.h | 1 - 7 files changed, 172 insertions(+), 101 deletions(-) diff --git a/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json b/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json index 4a8324a..2d8de26 100644 --- a/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json +++ b/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json @@ -92,8 +92,7 @@ "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10", "-DCYD_SCREEN_SIDEBAR_SIZE_PX=40", "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", - "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1", - "-DCYD_SCREEN_DISABLE_INVERT_COLORS=1" + "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1" ], "f_cpu": "240000000L", "f_flash": "40000000L", diff --git a/CYD-Klipper/extract_commit.py b/CYD-Klipper/extract_commit.py index e8f1e52..9362f66 100644 --- a/CYD-Klipper/extract_commit.py +++ b/CYD-Klipper/extract_commit.py @@ -15,11 +15,17 @@ def extract_commit() -> str: version = "Unknown" flag = "-D REPO_VERSION=\\\"" + version + "\\\"" +dev_flag = "-DREPO_DEVELOPMENT=1" print(f"Version: {version}") print(f"Flag: {flag}") +flags = [flag] + +if ('(' in version): + flags.append(dev_flag) + Import("env") env.Append( - BUILD_FLAGS=[flag] + BUILD_FLAGS=flags ) \ No newline at end of file diff --git a/CYD-Klipper/src/conf/lv_conf.h b/CYD-Klipper/src/conf/lv_conf.h index ef6a52c..896f684 100644 --- a/CYD-Klipper/src/conf/lv_conf.h +++ b/CYD-Klipper/src/conf/lv_conf.h @@ -242,8 +242,12 @@ * Others *-----------*/ +#ifndef REPO_DEVELOPMENT + #define REPO_DEVELOPMENT 0 +#endif + /*1: Show CPU usage and FPS count*/ -#define LV_USE_PERF_MONITOR 0 +#define LV_USE_PERF_MONITOR REPO_DEVELOPMENT #if LV_USE_PERF_MONITOR #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT #endif diff --git a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp index 3112dfa..1543e2c 100644 --- a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp +++ b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp @@ -25,71 +25,6 @@ static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10]; TFT_eSPI tft = TFT_eSPI(); -TS_Point touchscreen_point() -{ - TS_Point p = touchscreen.getPoint(); - p.x = round((p.x * global_config.screenCalXMult) + global_config.screenCalXOffset); - p.y = round((p.y * global_config.screenCalYMult) + global_config.screenCalYOffset); - return p; -} - -void touchscreen_calibrate(bool force) -{ - if (global_config.screenCalibrated && !force) - { - return; - } - - tft.fillScreen(TFT_BLACK); - tft.setCursor(20, 140); - tft.setTextColor(TFT_WHITE, TFT_BLACK); - tft.setTextSize(2); - tft.println("Calibrate Screen"); - - TS_Point p; - int16_t x1, y1, x2, y2; - - while (touchscreen.touched()) - ; - tft.drawFastHLine(0, 10, 20, ILI9341_WHITE); - tft.drawFastVLine(10, 0, 20, ILI9341_WHITE); - while (!touchscreen.touched()) - ; - delay(50); - p = touchscreen.getPoint(); - x1 = p.x; - y1 = p.y; - tft.drawFastHLine(0, 10, 20, ILI9341_BLACK); - tft.drawFastVLine(10, 0, 20, ILI9341_BLACK); - delay(500); - - while (touchscreen.touched()) - ; - tft.drawFastHLine(300, 230, 20, ILI9341_WHITE); - tft.drawFastVLine(310, 220, 20, ILI9341_WHITE); - - while (!touchscreen.touched()) - ; - delay(50); - p = touchscreen.getPoint(); - x2 = p.x; - y2 = p.y; - tft.drawFastHLine(300, 230, 20, ILI9341_BLACK); - tft.drawFastVLine(310, 220, 20, ILI9341_BLACK); - - int16_t xDist = 320 - 20; - int16_t yDist = 240 - 20; - - global_config.screenCalXMult = (float)xDist / (float)(x2 - x1); - global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult); - - global_config.screenCalYMult = (float)yDist / (float)(y2 - y1); - global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult); - - global_config.screenCalibrated = true; - WriteGlobalConfig(); -} - void screen_setBrightness(byte brightness) { // calculate duty, 4095 from 2 ^ 12 - 1 @@ -116,7 +51,7 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { if (touchscreen.tirqTouched() && touchscreen.touched()) { - TS_Point p = touchscreen_point(); + TS_Point p = touchscreen.getPoint(); data->state = LV_INDEV_STATE_PR; data->point.x = p.x; data->point.y = p.y; @@ -152,8 +87,6 @@ void screen_setup() touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen.begin(touchscreen_spi); - touchscreen_calibrate(false); - lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10); /*Initialize the display*/ diff --git a/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp b/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp index 3855bd6..e338982 100644 --- a/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp +++ b/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp @@ -7,11 +7,8 @@ #include "lvgl.h" #include "../lv_setup.h" -void touchscreen_calibrate(bool force) -{ - // TODO: Stubbed - return; -} +typedef void (*lv_disp_drv_t_flush_cb)(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); +static lv_disp_drv_t_flush_cb original_screen_driver; void screen_setBrightness(byte brightness) { @@ -19,13 +16,34 @@ void screen_setBrightness(byte brightness) } void set_invert_display(){ - // Stubbed + lv_obj_invalidate(lv_scr_act()); +} + +void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +{ + if (global_config.invertColors) { + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + for (int i = 0 ; i < w * h; i++){ + color_p[i].full ^= 0xFFFF; + } + } + + original_screen_driver(disp_drv, area, color_p); } void screen_setup() { smartdisplay_init(); +#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS + if (original_screen_driver == NULL){ + original_screen_driver = lv_disp_get_default()->driver->flush_cb; + lv_disp_get_default()->driver->flush_cb = lv_screen_intercept; + } +#endif // CYD_SCREEN_DISABLE_INVERT_COLORS + lv_disp_set_rotation(lv_disp_get_default(), (global_config.rotateScreen) ? LV_DISP_ROT_270 : LV_DISP_ROT_90); } diff --git a/CYD-Klipper/src/core/lv_setup.cpp b/CYD-Klipper/src/core/lv_setup.cpp index ac84c49..2280d7b 100644 --- a/CYD-Klipper/src/core/lv_setup.cpp +++ b/CYD-Klipper/src/core/lv_setup.cpp @@ -2,6 +2,7 @@ #include "screen_driver.h" #include "../conf/global_config.h" #include "lvgl.h" +#include "../ui/ui_utils.h" #include #ifndef CPU_FREQ_HIGH @@ -13,8 +14,89 @@ typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data); -bool isScreenInSleep = false; -lv_timer_t *screenSleepTimer; +bool is_screen_in_sleep = false; +bool is_in_calibration_mode = false; +lv_timer_t *screen_sleep_timer; +lv_coord_t point[2] = {0}; + +void lv_do_calibration(){ + if (global_config.screenCalibrated){ + return; + } + + is_in_calibration_mode = true; + lv_obj_clean(lv_scr_act()); + + lv_obj_t * label = lv_label_create(lv_scr_act()); + lv_label_set_text(label, "Calibrate Screen"); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t * line = lv_line_create(lv_scr_act()); + static lv_point_t line_points_x[] = { {0, 10}, {20, 10} }; + static lv_point_t line_points_y[] = { {10, 0}, {10, 20} }; + + lv_line_set_points(line, line_points_x, 2); + lv_obj_align(line, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_line_width(line, 1, 0); + + lv_obj_t * line2 = lv_line_create(lv_scr_act()); + lv_line_set_points(line2, line_points_y, 2); + lv_obj_align(line2, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_line_width(line2, 1, 0); + + while (true){ + lv_timer_handler(); + lv_task_handler(); + + if (point[0] != 0 && point[1] != 0){ + break; + } + } + + lv_coord_t x1 = point[0]; + lv_coord_t y1 = point[1]; + point[0] = 0; + point[1] = 0; + + lv_obj_del(line); + lv_obj_del(line2); + + line = lv_line_create(lv_scr_act()); + lv_line_set_points(line, line_points_x, 2); + lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, 0, -10); + lv_obj_set_style_line_width(line, 1, 0); + + line = lv_line_create(lv_scr_act()); + lv_line_set_points(line, line_points_y, 2); + lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, -10, 0); + + while (true){ + lv_timer_handler(); + lv_task_handler(); + + if (point[0] != 0 && point[1] != 0){ + break; + } + } + + lv_coord_t x2 = point[0]; + lv_coord_t y2 = point[1]; + + int16_t xDist = CYD_SCREEN_WIDTH_PX - 20; + int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20; + + global_config.screenCalXMult = (float)xDist / (float)(x2 - x1); + global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult); + + global_config.screenCalYMult = (float)yDist / (float)(y2 - y1); + global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult); + + global_config.screenCalibrated = true; + WriteGlobalConfig(); + + is_in_calibration_mode = false; + lv_obj_clean(lv_scr_act()); +} void set_screen_brightness() { @@ -27,13 +109,13 @@ void set_screen_brightness() void screen_timer_wake() { #ifndef CYD_SCREEN_DISABLE_TIMEOUT - lv_timer_reset(screenSleepTimer); + lv_timer_reset(screen_sleep_timer); - if (!isScreenInSleep){ + if (!is_screen_in_sleep){ return; } - isScreenInSleep = false; + is_screen_in_sleep = false; set_screen_brightness(); // Reset cpu freq @@ -46,7 +128,7 @@ void screen_timer_sleep(lv_timer_t *timer) { #ifndef CYD_SCREEN_DISABLE_TIMEOUT screen_setBrightness(0); - isScreenInSleep = true; + is_screen_in_sleep = true; // Screen is off, no need to make the cpu run fast, the user won't notice ;) setCpuFrequencyMhz(CPU_FREQ_LOW); @@ -56,23 +138,23 @@ void screen_timer_sleep(lv_timer_t *timer) void screen_timer_setup() { - screenSleepTimer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL); - lv_timer_pause(screenSleepTimer); + screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL); + lv_timer_pause(screen_sleep_timer); } void screen_timer_start() { - lv_timer_resume(screenSleepTimer); + lv_timer_resume(screen_sleep_timer); } void screen_timer_stop() { - lv_timer_pause(screenSleepTimer); + lv_timer_pause(screen_sleep_timer); } void screen_timer_period(unsigned int period) { - lv_timer_set_period(screenSleepTimer, period); + lv_timer_set_period(screen_sleep_timer, period); } void set_screen_timer_period() @@ -100,16 +182,33 @@ void set_color_scheme() lv_disp_set_theme(dispp, theme); } -static lv_indev_drv_read_cb_t original_driver = NULL; +static lv_indev_drv_read_cb_t original_touch_driver = NULL; void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { - original_driver(indev_driver, data); + original_touch_driver(indev_driver, data); + +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + if (is_in_calibration_mode){ + if (data->state == LV_INDEV_STATE_PR){ + point[0] = data->point.x; + point[1] = data->point.y; + while (data->state == LV_INDEV_STATE_PR){ + original_touch_driver(indev_driver, data); + delay(20); + } + } + + data->state = LV_INDEV_STATE_REL; + return; + } +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + if (data->state == LV_INDEV_STATE_PR) { if (is_screen_asleep()) { while (data->state == LV_INDEV_STATE_PR) { - original_driver(indev_driver, data); + original_touch_driver(indev_driver, data); delay(20); } @@ -118,23 +217,36 @@ void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) screen_timer_wake(); } + +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + if (data->state == LV_INDEV_STATE_PR) { + //Serial.printf("Before: %d %d\n", data->point.x, data->point.y); + data->point.x = round((data->point.x * global_config.screenCalXMult) + global_config.screenCalXOffset); + data->point.y = round((data->point.y * global_config.screenCalYMult) + global_config.screenCalYOffset); + //Serial.printf("After: %d %d\n", data->point.x, data->point.y); + } +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION } void lv_setup() { - screen_timer_setup(); - screen_timer_start(); + if (original_touch_driver == NULL) { + lv_indev_t * display_driver = lv_indev_get_next(NULL); + original_touch_driver = display_driver->driver->read_cb; + display_driver->driver->read_cb = lv_touch_intercept; + } + set_color_scheme(); - if (original_driver != NULL) - return; +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + lv_do_calibration(); +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION - lv_indev_t * display_driver = lv_indev_get_next(NULL); - original_driver = display_driver->driver->read_cb; - display_driver->driver->read_cb = lv_touch_intercept; + screen_timer_setup(); + screen_timer_start(); } bool is_screen_asleep() { - return isScreenInSleep; + return is_screen_in_sleep; } \ No newline at end of file diff --git a/CYD-Klipper/src/core/screen_driver.h b/CYD-Klipper/src/core/screen_driver.h index e8f8e1a..00ca655 100644 --- a/CYD-Klipper/src/core/screen_driver.h +++ b/CYD-Klipper/src/core/screen_driver.h @@ -1,7 +1,6 @@ #pragma once // Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h -void touchscreen_calibrate(bool force = false); void screen_setBrightness(unsigned char brightness); void screen_setup(); void set_invert_display(); \ No newline at end of file