diff --git a/esphome/components/cst226/binary_sensor/__init__.py b/esphome/components/cst226/binary_sensor/__init__.py new file mode 100644 index 0000000000..d95f0d2b4d --- /dev/null +++ b/esphome/components/cst226/binary_sensor/__init__.py @@ -0,0 +1,28 @@ +import esphome.codegen as cg +from esphome.components import binary_sensor +import esphome.config_validation as cv + +from .. import cst226_ns +from ..touchscreen import CST226ButtonListener, CST226Touchscreen + +CONF_CST226_ID = "cst226_id" + +CST226Button = cst226_ns.class_( + "CST226Button", + binary_sensor.BinarySensor, + cg.Component, + CST226ButtonListener, + cg.Parented.template(CST226Touchscreen), +) + +CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(CST226Button).extend( + { + cv.GenerateID(CONF_CST226_ID): cv.use_id(CST226Touchscreen), + } +) + + +async def to_code(config): + var = await binary_sensor.new_binary_sensor(config) + await cg.register_component(var, config) + await cg.register_parented(var, config[CONF_CST226_ID]) diff --git a/esphome/components/cst226/binary_sensor/cs226_button.h b/esphome/components/cst226/binary_sensor/cs226_button.h new file mode 100644 index 0000000000..6d409df04f --- /dev/null +++ b/esphome/components/cst226/binary_sensor/cs226_button.h @@ -0,0 +1,22 @@ +#pragma once + +#include "esphome/components/binary_sensor/binary_sensor.h" +#include "../touchscreen/cst226_touchscreen.h" +#include "esphome/core/helpers.h" + +namespace esphome { +namespace cst226 { + +class CST226Button : public binary_sensor::BinarySensor, + public Component, + public CST226ButtonListener, + public Parented { + public: + void setup() override; + void dump_config() override; + + void update_button(bool state) override; +}; + +} // namespace cst226 +} // namespace esphome diff --git a/esphome/components/cst226/binary_sensor/cstt6_button.cpp b/esphome/components/cst226/binary_sensor/cstt6_button.cpp new file mode 100644 index 0000000000..c481ce5d57 --- /dev/null +++ b/esphome/components/cst226/binary_sensor/cstt6_button.cpp @@ -0,0 +1,19 @@ +#include "cs226_button.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace cst226 { + +static const char *const TAG = "CST226.binary_sensor"; + +void CST226Button::setup() { + this->parent_->register_button_listener(this); + this->publish_initial_state(false); +} + +void CST226Button::dump_config() { LOG_BINARY_SENSOR("", "CST226 Button", this); } + +void CST226Button::update_button(bool state) { this->publish_state(state); } + +} // namespace cst226 +} // namespace esphome diff --git a/esphome/components/cst226/touchscreen/cst226_touchscreen.cpp b/esphome/components/cst226/touchscreen/cst226_touchscreen.cpp index a25859fe17..fa8cd9b057 100644 --- a/esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +++ b/esphome/components/cst226/touchscreen/cst226_touchscreen.cpp @@ -3,8 +3,10 @@ namespace esphome { namespace cst226 { +static const char *const TAG = "cst226.touchscreen"; + void CST226Touchscreen::setup() { - esph_log_config(TAG, "Setting up CST226 Touchscreen..."); + ESP_LOGCONFIG(TAG, "Setting up CST226 Touchscreen..."); if (this->reset_pin_ != nullptr) { this->reset_pin_->setup(); this->reset_pin_->digital_write(true); @@ -26,6 +28,11 @@ void CST226Touchscreen::update_touches() { return; } this->status_clear_warning(); + if (data[0] == 0x83 && data[1] == 0x17 && data[5] == 0x80) { + this->update_button_state_(true); + return; + } + this->update_button_state_(false); if (data[6] != 0xAB || data[0] == 0xAB || data[5] == 0x80) { this->skip_update_ = true; return; @@ -43,13 +50,21 @@ void CST226Touchscreen::update_touches() { int16_t y = (data[index + 2] << 4) | (data[index + 3] & 0x0F); int16_t z = data[index + 4]; this->add_raw_touch_position_(id, x, y, z); - esph_log_v(TAG, "Read touch %d: %d/%d", id, x, y); + ESP_LOGV(TAG, "Read touch %d: %d/%d", id, x, y); index += 5; if (i == 0) index += 2; } } +bool CST226Touchscreen::read16_(uint16_t addr, uint8_t *data, size_t len) { + if (this->read_register16(addr, data, len) != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Read data from 0x%04X failed", addr); + this->mark_failed(); + return false; + } + return true; +} void CST226Touchscreen::continue_setup_() { uint8_t buffer[8]; if (this->interrupt_pin_ != nullptr) { @@ -58,7 +73,7 @@ void CST226Touchscreen::continue_setup_() { } buffer[0] = 0xD1; if (this->write_register16(0xD1, buffer, 1) != i2c::ERROR_OK) { - esph_log_e(TAG, "Write byte to 0xD1 failed"); + ESP_LOGE(TAG, "Write byte to 0xD1 failed"); this->mark_failed(); return; } @@ -66,7 +81,7 @@ void CST226Touchscreen::continue_setup_() { if (this->read16_(0xD204, buffer, 4)) { uint16_t chip_id = buffer[2] + (buffer[3] << 8); uint16_t project_id = buffer[0] + (buffer[1] << 8); - esph_log_config(TAG, "Chip ID %X, project ID %x", chip_id, project_id); + ESP_LOGCONFIG(TAG, "Chip ID %X, project ID %x", chip_id, project_id); } if (this->x_raw_max_ == 0 || this->y_raw_max_ == 0) { if (this->read16_(0xD1F8, buffer, 4)) { @@ -80,7 +95,14 @@ void CST226Touchscreen::continue_setup_() { } } this->setup_complete_ = true; - esph_log_config(TAG, "CST226 Touchscreen setup complete"); + ESP_LOGCONFIG(TAG, "CST226 Touchscreen setup complete"); +} +void CST226Touchscreen::update_button_state_(bool state) { + if (this->button_touched_ == state) + return; + this->button_touched_ = state; + for (auto *listener : this->button_listeners_) + listener->update_button(state); } void CST226Touchscreen::dump_config() { diff --git a/esphome/components/cst226/touchscreen/cst226_touchscreen.h b/esphome/components/cst226/touchscreen/cst226_touchscreen.h index 9f518e5068..c744e51fec 100644 --- a/esphome/components/cst226/touchscreen/cst226_touchscreen.h +++ b/esphome/components/cst226/touchscreen/cst226_touchscreen.h @@ -9,10 +9,13 @@ namespace esphome { namespace cst226 { -static const char *const TAG = "cst226.touchscreen"; - static const uint8_t CST226_REG_STATUS = 0x00; +class CST226ButtonListener { + public: + virtual void update_button(bool state) = 0; +}; + class CST226Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice { public: void setup() override; @@ -22,22 +25,19 @@ class CST226Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; } void set_reset_pin(GPIOPin *pin) { this->reset_pin_ = pin; } bool can_proceed() override { return this->setup_complete_ || this->is_failed(); } + void register_button_listener(CST226ButtonListener *listener) { this->button_listeners_.push_back(listener); } protected: - bool read16_(uint16_t addr, uint8_t *data, size_t len) { - if (this->read_register16(addr, data, len) != i2c::ERROR_OK) { - esph_log_e(TAG, "Read data from 0x%04X failed", addr); - this->mark_failed(); - return false; - } - return true; - } + bool read16_(uint16_t addr, uint8_t *data, size_t len); void continue_setup_(); + void update_button_state_(bool state); InternalGPIOPin *interrupt_pin_{}; GPIOPin *reset_pin_{}; uint8_t chip_id_{}; bool setup_complete_{}; + std::vector button_listeners_; + bool button_touched_{}; }; } // namespace cst226 diff --git a/tests/components/cst226/common.yaml b/tests/components/cst226/common.yaml index c12d8d872c..d0b8ea3a86 100644 --- a/tests/components/cst226/common.yaml +++ b/tests/components/cst226/common.yaml @@ -23,3 +23,9 @@ touchscreen: interrupt_pin: ${interrupt_pin} reset_pin: ${reset_pin} +binary_sensor: + - id: cst226_touch + platform: cst226 + on_press: + then: + - component.update: ts_cst226