From 54cea6c41e3d43f94494c801f9e3c4ef8210fe18 Mon Sep 17 00:00:00 2001 From: kkosik20 <88562820+kkosik20@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:03:28 -0800 Subject: [PATCH] Adding support for chsc6x touch controller (#8258) --- CODEOWNERS | 1 + esphome/components/chsc6x/__init__.py | 2 + .../components/chsc6x/chsc6x_touchscreen.cpp | 47 +++++++++++++++++++ .../components/chsc6x/chsc6x_touchscreen.h | 34 ++++++++++++++ esphome/components/chsc6x/touchscreen.py | 33 +++++++++++++ tests/components/chsc6x/test.esp32-ard.yaml | 25 ++++++++++ .../components/chsc6x/test.esp32-c3-ard.yaml | 25 ++++++++++ .../components/chsc6x/test.esp32-c3-idf.yaml | 25 ++++++++++ tests/components/chsc6x/test.esp32-idf.yaml | 25 ++++++++++ tests/components/chsc6x/test.rp2040-ard.yaml | 25 ++++++++++ 10 files changed, 242 insertions(+) create mode 100644 esphome/components/chsc6x/__init__.py create mode 100644 esphome/components/chsc6x/chsc6x_touchscreen.cpp create mode 100644 esphome/components/chsc6x/chsc6x_touchscreen.h create mode 100644 esphome/components/chsc6x/touchscreen.py create mode 100644 tests/components/chsc6x/test.esp32-ard.yaml create mode 100644 tests/components/chsc6x/test.esp32-c3-ard.yaml create mode 100644 tests/components/chsc6x/test.esp32-c3-idf.yaml create mode 100644 tests/components/chsc6x/test.esp32-idf.yaml create mode 100644 tests/components/chsc6x/test.rp2040-ard.yaml diff --git a/CODEOWNERS b/CODEOWNERS index c725c2e736..2b0aefb569 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -93,6 +93,7 @@ esphome/components/captive_portal/* @OttoWinter esphome/components/ccs811/* @habbie esphome/components/cd74hc4067/* @asoehlke esphome/components/ch422g/* @clydebarrow @jesterret +esphome/components/chsc6x/* @kkosik20 esphome/components/climate/* @esphome/core esphome/components/climate_ir/* @glmnet esphome/components/color_temperature/* @jesserockz diff --git a/esphome/components/chsc6x/__init__.py b/esphome/components/chsc6x/__init__.py new file mode 100644 index 0000000000..80f3a0b33e --- /dev/null +++ b/esphome/components/chsc6x/__init__.py @@ -0,0 +1,2 @@ +CODEOWNERS = ["@kkosik20"] +DEPENDENCIES = ["i2c"] diff --git a/esphome/components/chsc6x/chsc6x_touchscreen.cpp b/esphome/components/chsc6x/chsc6x_touchscreen.cpp new file mode 100644 index 0000000000..5ad4329718 --- /dev/null +++ b/esphome/components/chsc6x/chsc6x_touchscreen.cpp @@ -0,0 +1,47 @@ +#include "chsc6x_touchscreen.h" + +namespace esphome { +namespace chsc6x { + +void CHSC6XTouchscreen::setup() { + ESP_LOGCONFIG(TAG, "Setting up CHSC6X Touchscreen..."); + if (this->interrupt_pin_ != nullptr) { + this->interrupt_pin_->setup(); + this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE); + } + if (this->x_raw_max_ == this->x_raw_min_) { + this->x_raw_max_ = this->display_->get_native_width(); + } + if (this->y_raw_max_ == this->y_raw_min_) { + this->y_raw_max_ = this->display_->get_native_height(); + } + + ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen setup complete"); +} + +void CHSC6XTouchscreen::update_touches() { + uint8_t data[CHSC6X_REG_STATUS_LEN]; + if (!this->read_bytes(CHSC6X_REG_STATUS, data, sizeof(data))) { + return; + } + + uint8_t num_of_touches = data[CHSC6X_REG_STATUS_TOUCH]; + + if (num_of_touches == 1) { + uint16_t x = data[CHSC6X_REG_STATUS_X_COR]; + uint16_t y = data[CHSC6X_REG_STATUS_Y_COR]; + this->add_raw_touch_position_(0, x, y); + } +} + +void CHSC6XTouchscreen::dump_config() { + ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen:"); + LOG_I2C_DEVICE(this); + LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); + ESP_LOGCONFIG(TAG, " Touch timeout: %d", this->touch_timeout_); + ESP_LOGCONFIG(TAG, " x_raw_max_: %d", this->x_raw_max_); + ESP_LOGCONFIG(TAG, " y_raw_max_: %d", this->y_raw_max_); +} + +} // namespace chsc6x +} // namespace esphome diff --git a/esphome/components/chsc6x/chsc6x_touchscreen.h b/esphome/components/chsc6x/chsc6x_touchscreen.h new file mode 100644 index 0000000000..25b79ad34a --- /dev/null +++ b/esphome/components/chsc6x/chsc6x_touchscreen.h @@ -0,0 +1,34 @@ +#pragma once + +#include "esphome/components/i2c/i2c.h" +#include "esphome/components/touchscreen/touchscreen.h" +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace chsc6x { + +static const char *const TAG = "chsc6x.touchscreen"; + +static const uint8_t CHSC6X_REG_STATUS = 0x00; +static const uint8_t CHSC6X_REG_STATUS_TOUCH = 0x00; +static const uint8_t CHSC6X_REG_STATUS_X_COR = 0x02; +static const uint8_t CHSC6X_REG_STATUS_Y_COR = 0x04; +static const uint8_t CHSC6X_REG_STATUS_LEN = 0x05; +static const uint8_t CHSC6X_CHIP_ID = 0x2e; + +class CHSC6XTouchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice { + public: + void setup() override; + void update_touches() override; + void dump_config() override; + + void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; } + + protected: + InternalGPIOPin *interrupt_pin_{}; +}; + +} // namespace chsc6x +} // namespace esphome diff --git a/esphome/components/chsc6x/touchscreen.py b/esphome/components/chsc6x/touchscreen.py new file mode 100644 index 0000000000..759e38609e --- /dev/null +++ b/esphome/components/chsc6x/touchscreen.py @@ -0,0 +1,33 @@ +from esphome import pins +import esphome.codegen as cg +from esphome.components import i2c, touchscreen +import esphome.config_validation as cv +from esphome.const import CONF_ID, CONF_INTERRUPT_PIN + +chsc6x_ns = cg.esphome_ns.namespace("chsc6x") + +CHSC6XTouchscreen = chsc6x_ns.class_( + "CHSC6XTouchscreen", + touchscreen.Touchscreen, + i2c.I2CDevice, +) + +CONFIG_SCHEMA = ( + touchscreen.touchscreen_schema("100ms") + .extend( + { + cv.GenerateID(): cv.declare_id(CHSC6XTouchscreen), + cv.Optional(CONF_INTERRUPT_PIN): pins.internal_gpio_input_pin_schema, + } + ) + .extend(i2c.i2c_device_schema(0x2E)) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await touchscreen.register_touchscreen(var, config) + await i2c.register_i2c_device(var, config) + + if interrupt_pin := config.get(CONF_INTERRUPT_PIN): + cg.add(var.set_interrupt_pin(await cg.gpio_pin_expression(interrupt_pin))) diff --git a/tests/components/chsc6x/test.esp32-ard.yaml b/tests/components/chsc6x/test.esp32-ard.yaml new file mode 100644 index 0000000000..9bc58b66f6 --- /dev/null +++ b/tests/components/chsc6x/test.esp32-ard.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_chsc6x + scl: 3 + sda: 21 + +spi: + clk_pin: 16 + mosi_pin: 17 + +display: + - platform: ili9xxx + id: ili9xxx_display + model: GC9A01A + invert_colors: True + cs_pin: 18 + dc_pin: 19 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: chsc6x + display: ili9xxx_display + interrupt_pin: 20 diff --git a/tests/components/chsc6x/test.esp32-c3-ard.yaml b/tests/components/chsc6x/test.esp32-c3-ard.yaml new file mode 100644 index 0000000000..b0f55eb2e6 --- /dev/null +++ b/tests/components/chsc6x/test.esp32-c3-ard.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_chsc6x + scl: 3 + sda: 9 + +spi: + clk_pin: 5 + mosi_pin: 4 + +display: + - platform: ili9xxx + id: ili9xxx_display + model: GC9A01A + invert_colors: True + cs_pin: 18 + dc_pin: 19 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: chsc6x + display: ili9xxx_display + interrupt_pin: 20 diff --git a/tests/components/chsc6x/test.esp32-c3-idf.yaml b/tests/components/chsc6x/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b0f55eb2e6 --- /dev/null +++ b/tests/components/chsc6x/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_chsc6x + scl: 3 + sda: 9 + +spi: + clk_pin: 5 + mosi_pin: 4 + +display: + - platform: ili9xxx + id: ili9xxx_display + model: GC9A01A + invert_colors: True + cs_pin: 18 + dc_pin: 19 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: chsc6x + display: ili9xxx_display + interrupt_pin: 20 diff --git a/tests/components/chsc6x/test.esp32-idf.yaml b/tests/components/chsc6x/test.esp32-idf.yaml new file mode 100644 index 0000000000..9bc58b66f6 --- /dev/null +++ b/tests/components/chsc6x/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_chsc6x + scl: 3 + sda: 21 + +spi: + clk_pin: 16 + mosi_pin: 17 + +display: + - platform: ili9xxx + id: ili9xxx_display + model: GC9A01A + invert_colors: True + cs_pin: 18 + dc_pin: 19 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: chsc6x + display: ili9xxx_display + interrupt_pin: 20 diff --git a/tests/components/chsc6x/test.rp2040-ard.yaml b/tests/components/chsc6x/test.rp2040-ard.yaml new file mode 100644 index 0000000000..dbd0d59fc4 --- /dev/null +++ b/tests/components/chsc6x/test.rp2040-ard.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_chsc6x + scl: 1 + sda: 0 + +spi: + clk_pin: 2 + mosi_pin: 3 + +display: + - platform: ili9xxx + id: ili9xxx_display + model: GC9A01A + invert_colors: True + cs_pin: 18 + dc_pin: 19 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: chsc6x + display: ili9xxx_display + interrupt_pin: 20