From b7ca802bcda74f029a86c2b115b7d446248aade8 Mon Sep 17 00:00:00 2001 From: Christopher Liebman Date: Thu, 24 Dec 2020 11:26:58 -0800 Subject: [PATCH 1/5] working z test before if-else refactor --- lvgl_touch/xpt2046.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index b6fe51b..dd84009 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -18,8 +18,11 @@ *********************/ #define TAG "XPT2046" -#define CMD_X_READ 0b10010000 -#define CMD_Y_READ 0b11010000 +#define CMD_X_READ 0b10010000 // NOTE: XPT2046 data sheet says this is actually Y +#define CMD_Y_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X +#define CMD_Z1_READ 0b10110000 +#define CMD_Z2_READ 0b11000000 +#define Z_MIN 400 /********************** * TYPEDEFS @@ -65,6 +68,14 @@ void xpt2046_init(void) assert(ret == ESP_OK); } +static int16_t readVal(uint8_t cmd) +{ + uint8_t data[2]; + tp_spi_read_reg(cmd, data, 2); + int16_t val = (data[0] << 8) | data[1]; + return val; +} + /** * Get the current position and state of the touchpad * @param data store the read data here @@ -78,19 +89,26 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) int16_t x = 0; int16_t y = 0; + int16_t z = 0; uint8_t irq = gpio_get_level(XPT2046_IRQ); - if (irq == 0) { - uint8_t data[2]; - - tp_spi_read_reg(CMD_X_READ, data, 2); - x = (data[0] << 8) | data[1]; - - tp_spi_read_reg(CMD_Y_READ, data, 2); - y = (data[0] << 8) | data[1]; - ESP_LOGI(TAG, "P(%d,%d)", x, y); - + // only compute Z if we think its pressed (irq) + if (irq == 0) + { + int16_t z1 = readVal(CMD_Z1_READ) >> 3; + int16_t z2 = readVal(CMD_Z2_READ) >> 3; + + z = z1 + 4096; + z -= z2; + } + + if (irq == 0 && z >= Z_MIN) { + + x = readVal(CMD_X_READ); + y = readVal(CMD_Y_READ); + ESP_LOGI(TAG, "P(%d,%d,%d)", x, y, z); + /*Normalize Data back to 12-bits*/ x = x >> 4; y = y >> 4; From 0fc057b22c735368ea3548748865b471ce31a347 Mon Sep 17 00:00:00 2001 From: Christopher Liebman Date: Thu, 24 Dec 2020 13:46:04 -0800 Subject: [PATCH 2/5] add Kconfig option for touch check --- lvgl_touch/Kconfig | 4 ++ lvgl_touch/xpt2046.c | 87 ++++++++++++++++++++++++-------------------- lvgl_touch/xpt2046.h | 2 +- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/lvgl_touch/Kconfig b/lvgl_touch/Kconfig index bbcdad7..34d2a0b 100644 --- a/lvgl_touch/Kconfig +++ b/lvgl_touch/Kconfig @@ -180,6 +180,10 @@ menu "LVGL Touch controller" prompt "Invert Y coordinate value." default y + config LV_TOUCH_CHECK + bool + prompt "Check touch pressure to validate LV_TOUCH_PIN_IRQ" + default n endmenu menu "Touchpanel (FT6X06) Pin Assignments" diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index dd84009..b8a2617 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -33,6 +33,7 @@ **********************/ static void xpt2046_corr(int16_t * x, int16_t * y); static void xpt2046_avg(int16_t * x, int16_t * y); +static int16_t xpt2046_cmd(uint8_t cmd); /********************** * STATIC VARIABLES @@ -68,14 +69,6 @@ void xpt2046_init(void) assert(ret == ESP_OK); } -static int16_t readVal(uint8_t cmd) -{ - uint8_t data[2]; - tp_spi_read_reg(cmd, data, 2); - int16_t val = (data[0] << 8) | data[1]; - return val; -} - /** * Get the current position and state of the touchpad * @param data store the read data here @@ -85,46 +78,52 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) { static int16_t last_x = 0; static int16_t last_y = 0; - bool valid = true; + bool valid = false; - int16_t x = 0; - int16_t y = 0; - int16_t z = 0; + int16_t x = last_x; + int16_t y = last_y; uint8_t irq = gpio_get_level(XPT2046_IRQ); - // only compute Z if we think its pressed (irq) - if (irq == 0) - { - int16_t z1 = readVal(CMD_Z1_READ) >> 3; - int16_t z2 = readVal(CMD_Z2_READ) >> 3; + if (irq == 0) { +#if XPT2046_TOUCH_CHECK != 0 + int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3; + int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3; - z = z1 + 4096; - z -= z2; + // this is not what the confusing datasheet says but it seems to + // be enough to detect real touches on the panel + int16_t z = z1 + 4096 - z2; + + // seems the irq can be noisy so we only accept this as a touch if + // there is some pressure (z) detected + if (z >= Z_MIN) + { +#endif + valid = true; + + x = xpt2046_cmd(CMD_X_READ); + y = xpt2046_cmd(CMD_Y_READ); + ESP_LOGI(TAG, "P(%d,%d)", x, y); + + /*Normalize Data back to 12-bits*/ + x = x >> 4; + y = y >> 4; + ESP_LOGI(TAG, "P_norm(%d,%d)", x, y); + + xpt2046_corr(&x, &y); + xpt2046_avg(&x, &y); + last_x = x; + last_y = y; + + ESP_LOGI(TAG, "x = %d, y = %d", x, y); +#if XPT2046_TOUCH_CHECK != 0 + } +#endif } - if (irq == 0 && z >= Z_MIN) { - - x = readVal(CMD_X_READ); - y = readVal(CMD_Y_READ); - ESP_LOGI(TAG, "P(%d,%d,%d)", x, y, z); - - /*Normalize Data back to 12-bits*/ - x = x >> 4; - y = y >> 4; - ESP_LOGI(TAG, "P_norm(%d,%d)", x, y); - - xpt2046_corr(&x, &y); - xpt2046_avg(&x, &y); - last_x = x; - last_y = y; - - ESP_LOGI(TAG, "x = %d, y = %d", x, y); - } else { - x = last_x; - y = last_y; + if (!valid) + { avg_last = 0; - valid = false; } data->point.x = x; @@ -137,6 +136,14 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) /********************** * STATIC FUNCTIONS **********************/ +static int16_t xpt2046_cmd(uint8_t cmd) +{ + uint8_t data[2]; + tp_spi_read_reg(cmd, data, 2); + int16_t val = (data[0] << 8) | data[1]; + return val; +} + static void xpt2046_corr(int16_t * x, int16_t * y) { #if XPT2046_XY_SWAP != 0 diff --git a/lvgl_touch/xpt2046.h b/lvgl_touch/xpt2046.h index 8d61ce8..592ae8d 100644 --- a/lvgl_touch/xpt2046.h +++ b/lvgl_touch/xpt2046.h @@ -35,7 +35,7 @@ extern "C" { #define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X #define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y #define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP - +#define XPT2046_TOUCH_CHECK CONFIG_LV_TOUCH_CHECK /********************** * TYPEDEFS **********************/ From c445eca696ecd2ae376e8cf42fb5ffa7b2ba2690 Mon Sep 17 00:00:00 2001 From: Christopher Liebman Date: Fri, 25 Dec 2020 12:42:01 -0800 Subject: [PATCH 3/5] xpt2048 add option for using only touch pressure and ignoring IRQ --- lvgl_touch/Kconfig | 11 ++++++++--- lvgl_touch/xpt2046.c | 12 ++++++++---- lvgl_touch/xpt2046.h | 6 ++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lvgl_touch/Kconfig b/lvgl_touch/Kconfig index 34d2a0b..b1b5e89 100644 --- a/lvgl_touch/Kconfig +++ b/lvgl_touch/Kconfig @@ -99,7 +99,6 @@ menu "LVGL Touch controller" range 0 39 default 35 if LV_PREDEFINED_PINS_38V1 default 19 - help Configure the touchpanel MISO pin here. @@ -109,7 +108,6 @@ menu "LVGL Touch controller" range 0 39 default 32 if LV_PREDEFINED_PINS_38V1 default 23 - help Configure the touchpanel MOSI pin here. @@ -135,7 +133,7 @@ menu "LVGL Touch controller" default 27 if LV_PREDEFINED_PINS_38V4 default 25 help - Configure the touchpanel CS pin here. + Configure the touchpanel IRQ pin here. endmenu menu "Touchpanel Configuration (XPT2046)" @@ -180,10 +178,17 @@ menu "LVGL Touch controller" prompt "Invert Y coordinate value." default y + config LV_TOUCH_CHECK bool prompt "Check touch pressure to validate LV_TOUCH_PIN_IRQ" default n + + config LV_TOUCH_ONLY + bool + prompt "Only use touch pressure and not IRQ to detect a touch" + depends on LV_TOUCH_CHECK + default n endmenu menu "Touchpanel (FT6X06) Pin Assignments" diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index b8a2617..5815a15 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -55,6 +55,9 @@ uint8_t avg_last; */ void xpt2046_init(void) { + ESP_LOGI(TAG, "XPT2046 Initialization"); + +#if XPT2046_TOUCH_ONLY == 0 gpio_config_t irq_config = { .pin_bit_mask = BIT64(XPT2046_IRQ), .mode = GPIO_MODE_INPUT, @@ -63,10 +66,9 @@ void xpt2046_init(void) .intr_type = GPIO_INTR_DISABLE, }; - ESP_LOGI(TAG, "XPT2046 Initialization"); - esp_err_t ret = gpio_config(&irq_config); assert(ret == ESP_OK); +#endif } /** @@ -82,10 +84,11 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) int16_t x = last_x; int16_t y = last_y; - +#if XPT2046_TOUCH_ONLY == 0 uint8_t irq = gpio_get_level(XPT2046_IRQ); if (irq == 0) { +#endif #if XPT2046_TOUCH_CHECK != 0 int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3; int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3; @@ -119,8 +122,9 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) #if XPT2046_TOUCH_CHECK != 0 } #endif +#if XPT2046_TOUCH_ONLY == 0 } - +#endif if (!valid) { avg_last = 0; diff --git a/lvgl_touch/xpt2046.h b/lvgl_touch/xpt2046.h index 592ae8d..9a4ccf3 100644 --- a/lvgl_touch/xpt2046.h +++ b/lvgl_touch/xpt2046.h @@ -36,6 +36,12 @@ extern "C" { #define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y #define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP #define XPT2046_TOUCH_CHECK CONFIG_LV_TOUCH_CHECK +#if defined(CONFIG_LV_TOUCH_ONLY) +#define XPT2046_TOUCH_ONLY CONFIG_LV_TOUCH_ONLY +#else +#define XPT2046_TOUCH_ONLY 0 +#endif + /********************** * TYPEDEFS **********************/ From eaf43e40fa1616260a91c40124fad03ed1961e15 Mon Sep 17 00:00:00 2001 From: Christopher Liebman Date: Tue, 29 Dec 2020 13:35:20 -0800 Subject: [PATCH 4/5] refactoring for clarity on press/touch dection --- lvgl_touch/xpt2046.c | 88 ++++++++++++++++++++++++-------------------- lvgl_touch/xpt2046.h | 19 +++++----- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index 5815a15..074cbfc 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -22,11 +22,14 @@ #define CMD_Y_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X #define CMD_Z1_READ 0b10110000 #define CMD_Z2_READ 0b11000000 -#define Z_MIN 400 /********************** * TYPEDEFS **********************/ +typedef enum { + TOUCH_NOT_DETECTED = 0, + TOUCH_DETECTED = 1, +} xpt2046_touch_detect_t; /********************** * STATIC PROTOTYPES @@ -34,6 +37,7 @@ static void xpt2046_corr(int16_t * x, int16_t * y); static void xpt2046_avg(int16_t * x, int16_t * y); static int16_t xpt2046_cmd(uint8_t cmd); +static xpt2046_touch_detect_t xpt2048_is_touch_detected(); /********************** * STATIC VARIABLES @@ -84,48 +88,27 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) int16_t x = last_x; int16_t y = last_y; -#if XPT2046_TOUCH_ONLY == 0 - uint8_t irq = gpio_get_level(XPT2046_IRQ); + if (xpt2048_is_touch_detected() == TOUCH_DETECTED) + { + valid = true; - if (irq == 0) { -#endif -#if XPT2046_TOUCH_CHECK != 0 - int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3; - int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3; + x = xpt2046_cmd(CMD_X_READ); + y = xpt2046_cmd(CMD_Y_READ); + ESP_LOGI(TAG, "P(%d,%d)", x, y); - // this is not what the confusing datasheet says but it seems to - // be enough to detect real touches on the panel - int16_t z = z1 + 4096 - z2; + /*Normalize Data back to 12-bits*/ + x = x >> 4; + y = y >> 4; + ESP_LOGI(TAG, "P_norm(%d,%d)", x, y); + + xpt2046_corr(&x, &y); + xpt2046_avg(&x, &y); + last_x = x; + last_y = y; - // seems the irq can be noisy so we only accept this as a touch if - // there is some pressure (z) detected - if (z >= Z_MIN) - { -#endif - valid = true; - - x = xpt2046_cmd(CMD_X_READ); - y = xpt2046_cmd(CMD_Y_READ); - ESP_LOGI(TAG, "P(%d,%d)", x, y); - - /*Normalize Data back to 12-bits*/ - x = x >> 4; - y = y >> 4; - ESP_LOGI(TAG, "P_norm(%d,%d)", x, y); - - xpt2046_corr(&x, &y); - xpt2046_avg(&x, &y); - last_x = x; - last_y = y; - - ESP_LOGI(TAG, "x = %d, y = %d", x, y); -#if XPT2046_TOUCH_CHECK != 0 - } -#endif -#if XPT2046_TOUCH_ONLY == 0 + ESP_LOGI(TAG, "x = %d, y = %d", x, y); } -#endif - if (!valid) + else { avg_last = 0; } @@ -140,6 +123,33 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) /********************** * STATIC FUNCTIONS **********************/ +static xpt2046_touch_detect_t xpt2048_is_touch_detected() +{ + // check IRQ if we are not touch only OR are not checking touch +#if XPT2046_TOUCH_ONLY == 0 || XPT2046_TOUCH_CHECK == 0 + uint8_t irq = gpio_get_level(XPT2046_IRQ); + + if (irq != 0) { + return TOUCH_NOT_DETECTED; + } +#endif +#if XPT2046_TOUCH_CHECK != 0 + int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3; + int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3; + + // this is not what the confusing datasheet says but it seems to + // be enough to detect real touches on the panel + int16_t z = z1 + 4096 - z2; + + if (z < XPT2046_TOUCH_THRESHOLD) + { + return TOUCH_NOT_DETECTED; + } +#endif + + return TOUCH_DETECTED; +} + static int16_t xpt2046_cmd(uint8_t cmd) { uint8_t data[2]; diff --git a/lvgl_touch/xpt2046.h b/lvgl_touch/xpt2046.h index 9a4ccf3..bcdf84f 100644 --- a/lvgl_touch/xpt2046.h +++ b/lvgl_touch/xpt2046.h @@ -27,15 +27,16 @@ extern "C" { *********************/ #define XPT2046_IRQ CONFIG_LV_TOUCH_PIN_IRQ -#define XPT2046_AVG 4 -#define XPT2046_X_MIN CONFIG_LV_TOUCH_X_MIN -#define XPT2046_Y_MIN CONFIG_LV_TOUCH_Y_MIN -#define XPT2046_X_MAX CONFIG_LV_TOUCH_X_MAX -#define XPT2046_Y_MAX CONFIG_LV_TOUCH_Y_MAX -#define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X -#define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y -#define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP -#define XPT2046_TOUCH_CHECK CONFIG_LV_TOUCH_CHECK +#define XPT2046_AVG 4 +#define XPT2046_X_MIN CONFIG_LV_TOUCH_X_MIN +#define XPT2046_Y_MIN CONFIG_LV_TOUCH_Y_MIN +#define XPT2046_X_MAX CONFIG_LV_TOUCH_X_MAX +#define XPT2046_Y_MAX CONFIG_LV_TOUCH_Y_MAX +#define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X +#define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y +#define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP +#define XPT2046_TOUCH_CHECK CONFIG_LV_TOUCH_CHECK +#define XPT2046_TOUCH_THRESHOLD 400 // Threshold for touch detection #if defined(CONFIG_LV_TOUCH_ONLY) #define XPT2046_TOUCH_ONLY CONFIG_LV_TOUCH_ONLY #else From 895434a41080068b4016bf4c7ca44f7f6182c525 Mon Sep 17 00:00:00 2001 From: Christopher Liebman Date: Tue, 29 Dec 2020 14:40:03 -0800 Subject: [PATCH 5/5] use Kconfig choice for IRQ/PRESS/IRQ&PRESS --- lvgl_touch/Kconfig | 22 ++++++++++++---------- lvgl_touch/xpt2046.c | 9 +++++---- lvgl_touch/xpt2046.h | 9 +++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lvgl_touch/Kconfig b/lvgl_touch/Kconfig index b1b5e89..659cf02 100644 --- a/lvgl_touch/Kconfig +++ b/lvgl_touch/Kconfig @@ -178,17 +178,19 @@ menu "LVGL Touch controller" prompt "Invert Y coordinate value." default y + choice + prompt "Select touch detection method." + default LV_TOUCH_DETECT_IRQ + help + Select the controller for your touch panel. - config LV_TOUCH_CHECK - bool - prompt "Check touch pressure to validate LV_TOUCH_PIN_IRQ" - default n - - config LV_TOUCH_ONLY - bool - prompt "Only use touch pressure and not IRQ to detect a touch" - depends on LV_TOUCH_CHECK - default n + config LV_TOUCH_DETECT_IRQ + bool "IRQ pin only" + config LV_TOUCH_DETECT_IRQ_PRESSURE + bool "IRQ pin and pressure" + config LV_TOUCH_DETECT_PRESSURE + bool "Pressure only" + endchoice endmenu menu "Touchpanel (FT6X06) Pin Assignments" diff --git a/lvgl_touch/xpt2046.c b/lvgl_touch/xpt2046.c index 074cbfc..93b4329 100644 --- a/lvgl_touch/xpt2046.c +++ b/lvgl_touch/xpt2046.c @@ -61,7 +61,7 @@ void xpt2046_init(void) { ESP_LOGI(TAG, "XPT2046 Initialization"); -#if XPT2046_TOUCH_ONLY == 0 +#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS gpio_config_t irq_config = { .pin_bit_mask = BIT64(XPT2046_IRQ), .mode = GPIO_MODE_INPUT, @@ -125,15 +125,16 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data) **********************/ static xpt2046_touch_detect_t xpt2048_is_touch_detected() { - // check IRQ if we are not touch only OR are not checking touch -#if XPT2046_TOUCH_ONLY == 0 || XPT2046_TOUCH_CHECK == 0 + // check IRQ pin if we IRQ or IRQ and preessure +#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS uint8_t irq = gpio_get_level(XPT2046_IRQ); if (irq != 0) { return TOUCH_NOT_DETECTED; } #endif -#if XPT2046_TOUCH_CHECK != 0 + // check pressure if we are pressure or IRQ and pressure +#if XPT2046_TOUCH_PRESS || XPT2046_TOUCH_IRQ_PRESS int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3; int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3; diff --git a/lvgl_touch/xpt2046.h b/lvgl_touch/xpt2046.h index bcdf84f..016a351 100644 --- a/lvgl_touch/xpt2046.h +++ b/lvgl_touch/xpt2046.h @@ -35,13 +35,10 @@ extern "C" { #define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X #define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y #define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP -#define XPT2046_TOUCH_CHECK CONFIG_LV_TOUCH_CHECK #define XPT2046_TOUCH_THRESHOLD 400 // Threshold for touch detection -#if defined(CONFIG_LV_TOUCH_ONLY) -#define XPT2046_TOUCH_ONLY CONFIG_LV_TOUCH_ONLY -#else -#define XPT2046_TOUCH_ONLY 0 -#endif +#define XPT2046_TOUCH_IRQ CONFIG_LV_TOUCH_DETECT_IRQ +#define XPT2046_TOUCH_IRQ_PRESS CONFIG_LV_TOUCH_DETECT_IRQ_PRESSURE +#define XPT2046_TOUCH_PRESS CONFIG_LV_TOUCH_DETECT_PRESSURE /********************** * TYPEDEFS