Add GT911 using esp_lcd_touch_gt911

This commit is contained in:
martinberlin 2023-09-03 00:20:11 +02:00
parent 9445dab325
commit 5ffb67f193
8 changed files with 92 additions and 149 deletions

View file

@ -69,6 +69,8 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
list(APPEND SOURCES "lvgl_touch/ft6x36.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_L58)
list(APPEND SOURCES "lvgl_touch/l58.cpp")
elseif(CONFIG_LV_TOUCH_CONTROLLER_GT911)
list(APPEND SOURCES "lvgl_touch/gt911.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
list(APPEND SOURCES "lvgl_touch/stmpe610.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
@ -89,7 +91,7 @@ endif()
idf_component_register(SRCS ${SOURCES}
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
REQUIRES epdiy
lvgl CalEPD sharp-lcd
lvgl CalEPD sharp-lcd espressif__esp_lcd_touch_gt911
)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_LVGL_H_INCLUDE_SIMPLE")

View file

@ -148,9 +148,7 @@ void lvgl_driver_init(void)
touch_driver_init();
#elif defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
ESP_LOGI(TAG, "Initializing I2C master for touch");
lvgl_i2c_driver_init(TOUCH_I2C_PORT,
TOUCH_I2C_SDA, TOUCH_I2C_SCL,
TOUCH_I2C_SPEED_HZ);
//lvgl_i2c_driver_init(TOUCH_I2C_PORT, TOUCH_I2C_SDA, TOUCH_I2C_SCL, TOUCH_I2C_SPEED_HZ);
touch_driver_init();
#elif defined (CONFIG_LV_TOUCH_DRIVER_ADC)
@ -197,7 +195,7 @@ bool lvgl_i2c_driver_init(int port, int sda_pin, int scl_pin, int speed_hz)
I2C_MODE_MASTER,
0, 0 /*I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE */,
0 /* intr_alloc_flags */);
assert(ESP_OK == err);
//assert(ESP_OK == err);
return ESP_OK != err;
}

View file

@ -84,10 +84,10 @@ void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_ma
printf("%x ", buf[index]);
} */
// This is the slower version that works good without leaving any white line
//buf_copy_to_framebuffer(update_area, buf);
buf_copy_to_framebuffer(update_area, buf);
//Faster mode suggested in LVGL forum (Leaves ghosting&prints bad sections / experimental) NOTE: Do NOT use in production
buf_area_to_framebuffer(area, buf);
//buf_area_to_framebuffer(area, buf);
epd_hl_update_area(&hl, updateMode, temperature, update_area); //update_area

View file

@ -2,14 +2,15 @@ menu "LVGL Touch controller"
config LV_TOUCH_CONTROLLER
int
default 0 if LV_TOUCH_CONTROLLER_NONE
default 1 if LV_TOUCH_CONTROLLER_XPT2046
default 2 if LV_TOUCH_CONTROLLER_FT6X06
default 3 if LV_TOUCH_CONTROLLER_STMPE610
default 0 if LV_TOUCH_CONTROLLER_NONE
default 1 if LV_TOUCH_CONTROLLER_XPT2046
default 2 if LV_TOUCH_CONTROLLER_FT6X06
default 3 if LV_TOUCH_CONTROLLER_STMPE610
default 4 if LV_TOUCH_CONTROLLER_ADCRAW
default 5 if LV_TOUCH_CONTROLLER_FT81X
default 6 if LV_TOUCH_CONTROLLER_RA8875
default 7 if LV_TOUCH_CONTROLLER_L58
default 8 if LV_TOUCH_CONTROLLER_GT911
choice
prompt "Select a touch panel controller model."
default LV_TOUCH_CONTROLLER_NONE
@ -29,7 +30,9 @@ menu "LVGL Touch controller"
# Start only touch without protocol:
select CONFIG_LV_TOUCH_DRIVER_DISPLAY
bool "L58"
config LV_TOUCH_CONTROLLER_GT911
select LV_TOUCH_DRIVER_PROTOCOL_I2C
bool "GT911"
config LV_TOUCH_CONTROLLER_STMPE610
select LV_TOUCH_DRIVER_PROTOCOL_SPI
bool "STMPE610"
@ -522,7 +525,27 @@ menu "LVGL Touch controller"
bool
prompt "De-bounce Circuit Enable for Touch Panel Interrupt"
default y
endmenu
menu "Touchpanel GT911 Pin Assignments"
depends on LV_TOUCH_CONTROLLER_GT911
config LV_TOUCH_I2C_SDA
int
prompt "GPIO for SDA (I2C)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S3
default 39
help
Configure the I2C touchpanel SDA pin here.
config LV_TOUCH_I2C_SCL
int "GPIO for clock signal SCL (I2C)"
range 0 39 if IDF_TARGET_ESP32
range 0 43 if IDF_TARGET_ESP32S3
default 40
help
Configure the I2C touchpanel SCL pin here.
endmenu
endmenu

View file

@ -1,5 +1,5 @@
/*
* Copyright © 2021 Sturnus Inc.
* Copyright © 2023 Fasani Corp.
* 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
@ -17,8 +17,12 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_lcd_touch_gt911.h"
#include <esp_log.h>
#include "driver/i2c.h"
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include <lvgl.h>
#else
@ -26,62 +30,46 @@
#endif
#include "gt911.h"
#include "lvgl_i2c/i2c_manager.h"
#define TAG "GT911"
gt911_status_t gt911_status;
//TODO: handle multibyte read and refactor to just one read transaction
esp_err_t gt911_i2c_read(uint8_t slave_addr, uint16_t register_addr, uint8_t *data_buf, uint8_t len) {
return lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, data_buf, len);
}
esp_err_t gt911_i2c_write8(uint8_t slave_addr, uint16_t register_addr, uint8_t data) {
uint8_t buffer = data;
return lvgl_i2c_write(CONFIG_LV_I2C_TOUCH_PORT, slave_addr, register_addr | I2C_REG_16, &buffer, 1);
}
#ifdef CONFIG_LV_TOUCH_I2C_PORT_0
#define I2C_PORT I2C_NUM_0
#endif
#ifdef CONFIG_LV_TOUCH_I2C_PORT_1
#define I2C_PORT I2C_NUM_1
#endif
// When the touch panel has different pixels definition
float x_adjust = 1.55;
float y_adjust = 0.8;
esp_lcd_touch_handle_t tp;
/**
* @brief Initialize for GT911 communication via I2C
* @param dev_addr: Device address on communication Bus (I2C slave address of GT911).
* @retval None
*/
void gt911_init(uint8_t dev_addr) {
if (!gt911_status.inited) {
gt911_status.i2c_dev_addr = dev_addr;
uint8_t data_buf;
esp_err_t ret;
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
ESP_LOGI(TAG, "Checking for GT911 Touch Controller");
if ((ret = gt911_i2c_read(dev_addr, GT911_PRODUCT_ID1, &data_buf, 1) != ESP_OK)) {
ESP_LOGE(TAG, "Error reading from device: %s",
esp_err_to_name(ret)); // Only show error the first time
return;
}
esp_lcd_touch_config_t tp_cfg = {
.x_max = 1025,
.y_max = 770,
.rst_gpio_num = -1,
.int_gpio_num = -1,
.levels = {
.reset = 0,
.interrupt = 0,
},
.flags = {
.swap_xy = 1,
.mirror_x = 1,
.mirror_y = 0,
},
};
// Read 4 bytes for Product ID in ASCII
for (int i = 0; i < GT911_PRODUCT_ID_LEN; i++) {
gt911_i2c_read(dev_addr, (GT911_PRODUCT_ID1 + i), (uint8_t *)&(gt911_status.product_id[i]), 1);
}
ESP_LOGI(TAG, "\tProduct ID: %s", gt911_status.product_id);
esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_PORT, &tp_io_config, &tp_io_handle);
gt911_i2c_read(dev_addr, GT911_VENDOR_ID, &data_buf, 1);
ESP_LOGI(TAG, "\tVendor ID: 0x%02x", data_buf);
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_L, &data_buf, 1);
gt911_status.max_x_coord = data_buf;
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_H, &data_buf, 1);
gt911_status.max_x_coord |= ((uint16_t)data_buf << 8);
ESP_LOGI(TAG, "\tX Resolution: %d", gt911_status.max_x_coord);
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_L, &data_buf, 1);
gt911_status.max_y_coord = data_buf;
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_H, &data_buf, 1);
gt911_status.max_y_coord |= ((uint16_t)data_buf << 8);
ESP_LOGI(TAG, "\tY Resolution: %d", gt911_status.max_y_coord);
gt911_status.inited = true;
}
esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp);
}
/**
@ -91,54 +79,22 @@ void gt911_init(uint8_t dev_addr) {
* @retval Always false
*/
bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
uint8_t touch_pnt_cnt; // Number of detected touch points
static int16_t last_x = 0; // 12bit pixel value
static int16_t last_y = 0; // 12bit pixel value
uint8_t data_buf;
uint8_t status_reg;
esp_lcd_touch_read_data(tp);
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_STATUS_REG, &status_reg, 1);
// ESP_LOGI(TAG, "\tstatus: 0x%02x", status_reg);
touch_pnt_cnt = status_reg & 0x0F;
if ((status_reg & 0x80) || (touch_pnt_cnt < 6)) {
//Reset Status Reg Value
gt911_i2c_write8(gt911_status.i2c_dev_addr, GT911_STATUS_REG, 0x00);
}
if (touch_pnt_cnt != 1) { // ignore no touch & multi touch
data->point.x = last_x;
data->point.y = last_y;
uint16_t touch_x[2];
uint16_t touch_y[2];
uint16_t touch_strength[2];
uint8_t touch_cnt = 0;
bool touchpad_pressed = esp_lcd_touch_get_coordinates(tp, touch_x, touch_y, touch_strength, &touch_cnt, 2);
if (touchpad_pressed) {
data->state = LV_INDEV_STATE_PR;
data->point.x = (int)(touch_x[0]*x_adjust);
data->point.y = (int)(touch_y[0]*y_adjust);
ESP_LOGI(TAG, "X=%d Y=%d", (int)data->point.x, (int)data->point.y);
} else {
data->state = LV_INDEV_STATE_REL;
return false;
data->point.x = -1;
data->point.y = -1;
}
// gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_TRACK_ID1, &data_buf, 1);
// ESP_LOGI(TAG, "\ttrack_id: %d", data_buf);
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_L, &data_buf, 1);
last_x = data_buf;
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_H, &data_buf, 1);
last_x |= ((uint16_t)data_buf << 8);
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_Y_COORD_L, &data_buf, 1);
last_y = data_buf;
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_Y_COORD_H, &data_buf, 1);
last_y |= ((uint16_t)data_buf << 8);
#if CONFIG_LV_GT911_INVERT_X
last_x = gt911_status.max_x_coord - last_x;
#endif
#if CONFIG_LV_GT911_INVERT_Y
last_y = gt911_status.max_y_coord - last_y;
#endif
#if CONFIG_LV_GT911_SWAPXY
int16_t swap_buf = last_x;
last_x = last_y;
last_y = swap_buf;
#endif
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_PR;
ESP_LOGI(TAG, "X=%u Y=%u", data->point.x, data->point.y);
ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
return false;
}

View file

@ -22,7 +22,6 @@
#define __GT911_H
#include <stdint.h>
#include <stdbool.h>
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
@ -33,46 +32,6 @@
extern "C" {
#endif
#define GT911_I2C_SLAVE_ADDR 0x5D
#define GT911_PRODUCT_ID_LEN 4
/* Register Map of GT911 */
#define GT911_PRODUCT_ID1 0x8140
#define GT911_PRODUCT_ID2 0x8141
#define GT911_PRODUCT_ID3 0x8142
#define GT911_PRODUCT_ID4 0x8143
#define GT911_FIRMWARE_VER_L 0x8144
#define GT911_FIRMWARE_VER_H 0x8145
#define GT911_X_COORD_RES_L 0x8146
#define GT911_X_COORD_RES_H 0x8147
#define GT911_Y_COORD_RES_L 0x8148
#define GT911_Y_COORD_RES_H 0x8149
#define GT911_VENDOR_ID 0x814A
#define GT911_STATUS_REG 0x814E
#define GT911_STATUS_REG_BUF 0x80
#define GT911_STATUS_REG_LARGE 0x40
#define GT911_STATUS_REG_PROX_VALID 0x20
#define GT911_STATUS_REG_HAVEKEY 0x10
#define GT911_STATUS_REG_PT_MASK 0x0F
#define GT911_TRACK_ID1 0x814F
#define GT911_PT1_X_COORD_L 0x8150
#define GT911_PT1_X_COORD_H 0x8151
#define GT911_PT1_Y_COORD_L 0x8152
#define GT911_PT1_Y_COORD_H 0x8153
#define GT911_PT1_X_SIZE_L 0x8154
#define GT911_PT1_X_SIZE_H 0x8155
typedef struct {
bool inited;
char product_id[GT911_PRODUCT_ID_LEN];
uint16_t max_x_coord;
uint16_t max_y_coord;
uint8_t i2c_dev_addr;
} gt911_status_t;
/**
* @brief Initialize for GT911 communication via I2C
* @param dev_addr: Device address on communication Bus (I2C slave address of GT911).

View file

@ -16,6 +16,8 @@ void touch_driver_init(void)
ft6x06_init(FT6236_I2C_SLAVE_ADDR);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
l58_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
gt911_init(0x5d);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
stmpe610_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
@ -37,7 +39,8 @@ bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
res = ft6x36_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_L58)
res = l58_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
res = gt911_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
res = stmpe610_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)

View file

@ -32,6 +32,8 @@ extern "C" {
#include "FT81x.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
#include "ra8875_touch.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_GT911)
#include "gt911.h"
#endif
/*********************