knxdisplay/main/Touch.cpp
2026-01-24 18:31:31 +01:00

86 lines
2.8 KiB
C++

#include "Touch.hpp"
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "esp_lcd_touch_gt911.h"
#include "WidgetManager.hpp"
// Common display resolutions, used for touch dimensions
#define LCD_H_RES 800
#define LCD_V_RES 1280
// Touch config (GT911)
#define TOUCH_I2C_SDA 7
#define TOUCH_I2C_SCL 8
#define TOUCH_INT_GPIO 3
#define TOUCH_RST_GPIO 2
#define TOUCH_I2C_FREQ_HZ 400000
Touch::Touch() : touch_handle(nullptr) {}
void Touch::init() {
// --- I2C Bus Config ---
i2c_master_bus_config_t i2c_bus_cfg = {};
i2c_bus_cfg.i2c_port = I2C_NUM_0;
i2c_bus_cfg.sda_io_num = static_cast<gpio_num_t>(TOUCH_I2C_SDA);
i2c_bus_cfg.scl_io_num = static_cast<gpio_num_t>(TOUCH_I2C_SCL);
i2c_bus_cfg.clk_source = I2C_CLK_SRC_DEFAULT;
i2c_bus_cfg.glitch_ignore_cnt = 7;
i2c_bus_cfg.flags.enable_internal_pullup = true;
i2c_master_bus_handle_t i2c_bus = NULL;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus));
// --- Touch Panel IO Config ---
esp_lcd_panel_io_handle_t touch_io = NULL;
esp_lcd_panel_io_i2c_config_t touch_io_cfg = {};
touch_io_cfg.dev_addr = 0x5D; // Default GT911 address
touch_io_cfg.control_phase_bytes = 1;
touch_io_cfg.dc_bit_offset = 0;
touch_io_cfg.lcd_cmd_bits = 16;
touch_io_cfg.flags.disable_control_phase = true;
touch_io_cfg.scl_speed_hz = TOUCH_I2C_FREQ_HZ;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &touch_io_cfg, &touch_io));
// --- Touch Device Config ---
esp_lcd_touch_config_t touch_cfg = {};
touch_cfg.x_max = LCD_H_RES;
touch_cfg.y_max = LCD_V_RES;
touch_cfg.rst_gpio_num = static_cast<gpio_num_t>(TOUCH_RST_GPIO);
touch_cfg.int_gpio_num = static_cast<gpio_num_t>(TOUCH_INT_GPIO);
touch_cfg.levels.reset = 0;
touch_cfg.levels.interrupt = 0;
touch_cfg.flags.swap_xy = 1;
touch_cfg.flags.mirror_x = 1;
touch_cfg.flags.mirror_y = 0;
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(touch_io, &touch_cfg, &this->touch_handle));
}
esp_lcd_touch_handle_t Touch::getTouchHandle() const {
return this->touch_handle;
}
void Touch::lv_indev_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
{
Touch* self = static_cast<Touch*>(lv_indev_get_user_data(indev));
if (!self) {
data->state = LV_INDEV_STATE_RELEASED;
return;
}
uint16_t x[1], y[1];
uint8_t touch_cnt = 0;
esp_lcd_touch_read_data(self->getTouchHandle());
if (esp_lcd_touch_get_coordinates(self->getTouchHandle(), x, y, NULL, &touch_cnt, 1) && touch_cnt > 0) {
data->point.x = x[0];
data->point.y = y[0];
data->state = LV_INDEV_STATE_PRESSED;
// TEMP: Disabled to test if this causes the freeze
// WidgetManager::instance().onUserActivity();
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}