mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 05:24:53 +01:00
[ft5x06] Interrupt pin and code quality improvements (#6851)
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
This commit is contained in:
parent
eb75778f84
commit
69d38f6137
3 changed files with 119 additions and 85 deletions
|
@ -1,8 +1,9 @@
|
|||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from esphome.components import i2c, touchscreen
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.const import CONF_ID, CONF_INTERRUPT_PIN
|
||||
from .. import ft5x06_ns
|
||||
|
||||
FT5x06ButtonListener = ft5x06_ns.class_("FT5x06ButtonListener")
|
||||
|
@ -16,6 +17,7 @@ FT5x06Touchscreen = ft5x06_ns.class_(
|
|||
CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(FT5x06Touchscreen),
|
||||
cv.Optional(CONF_INTERRUPT_PIN): pins.internal_gpio_input_pin_schema,
|
||||
}
|
||||
).extend(i2c.i2c_device_schema(0x48))
|
||||
|
||||
|
@ -24,3 +26,7 @@ async def to_code(config):
|
|||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await i2c.register_i2c_device(var, config)
|
||||
await touchscreen.register_touchscreen(var, config)
|
||||
|
||||
if interrupt_pin := config.get(CONF_INTERRUPT_PIN):
|
||||
pin = await cg.gpio_pin_expression(interrupt_pin)
|
||||
cg.add(var.set_interrupt_pin(pin))
|
||||
|
|
102
esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp
Normal file
102
esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include "ft5x06_touchscreen.h"
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ft5x06 {
|
||||
|
||||
static const char *const TAG = "ft5x06.touchscreen";
|
||||
|
||||
void FT5x06Touchscreen::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up FT5x06 Touchscreen...");
|
||||
if (this->interrupt_pin_ != nullptr) {
|
||||
this->interrupt_pin_->setup();
|
||||
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
||||
this->interrupt_pin_->setup();
|
||||
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
|
||||
}
|
||||
|
||||
// wait 200ms after reset.
|
||||
this->set_timeout(200, [this] { this->continue_setup_(); });
|
||||
}
|
||||
|
||||
void FT5x06Touchscreen::continue_setup_() {
|
||||
uint8_t data[4];
|
||||
if (!this->set_mode_(FT5X06_OP_MODE))
|
||||
return;
|
||||
|
||||
if (!this->err_check_(this->read_register(FT5X06_VENDOR_ID_REG, data, 1), "Read Vendor ID"))
|
||||
return;
|
||||
switch (data[0]) {
|
||||
case FT5X06_ID_1:
|
||||
case FT5X06_ID_2:
|
||||
case FT5X06_ID_3:
|
||||
this->vendor_id_ = (VendorId) data[0];
|
||||
ESP_LOGD(TAG, "Read vendor ID 0x%X", data[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unknown vendor ID 0x%X", data[0]);
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
// reading the chip registers to get max x/y does not seem to work.
|
||||
if (this->display_ != nullptr) {
|
||||
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, "FT5x06 Touchscreen setup complete");
|
||||
}
|
||||
|
||||
void FT5x06Touchscreen::update_touches() {
|
||||
uint8_t touch_cnt;
|
||||
uint8_t data[MAX_TOUCHES][6];
|
||||
|
||||
if (!this->read_byte(FT5X06_TD_STATUS, &touch_cnt) || touch_cnt > MAX_TOUCHES) {
|
||||
ESP_LOGW(TAG, "Failed to read status");
|
||||
return;
|
||||
}
|
||||
if (touch_cnt == 0)
|
||||
return;
|
||||
|
||||
if (!this->read_bytes(FT5X06_TOUCH_DATA, (uint8_t *) data, touch_cnt * 6)) {
|
||||
ESP_LOGW(TAG, "Failed to read touch data");
|
||||
return;
|
||||
}
|
||||
for (uint8_t i = 0; i != touch_cnt; i++) {
|
||||
uint8_t status = data[i][0] >> 6;
|
||||
uint8_t id = data[i][2] >> 3;
|
||||
uint16_t x = encode_uint16(data[i][0] & 0x0F, data[i][1]);
|
||||
uint16_t y = encode_uint16(data[i][2] & 0xF, data[i][3]);
|
||||
|
||||
ESP_LOGD(TAG, "Read %X status, id: %d, pos %d/%d", status, id, x, y);
|
||||
if (status == 0 || status == 2) {
|
||||
this->add_raw_touch_position_(id, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FT5x06Touchscreen::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "FT5x06 Touchscreen:");
|
||||
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
|
||||
ESP_LOGCONFIG(TAG, " Vendor ID: 0x%X", (int) this->vendor_id_);
|
||||
}
|
||||
|
||||
bool FT5x06Touchscreen::err_check_(i2c::ErrorCode err, const char *msg) {
|
||||
if (err != i2c::ERROR_OK) {
|
||||
this->mark_failed();
|
||||
ESP_LOGE(TAG, "%s failed - err 0x%X", msg, err);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool FT5x06Touchscreen::set_mode_(FTMode mode) {
|
||||
return this->err_check_(this->write_register(FT5X06_MODE_REG, (uint8_t *) &mode, 1), "Set mode");
|
||||
}
|
||||
|
||||
} // namespace ft5x06
|
||||
} // namespace esphome
|
|
@ -3,14 +3,12 @@
|
|||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/touchscreen/touchscreen.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/gpio.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ft5x06 {
|
||||
|
||||
static const char *const TAG = "ft5x06.touchscreen";
|
||||
|
||||
enum VendorId {
|
||||
FT5X06_ID_UNKNOWN = 0,
|
||||
FT5X06_ID_1 = 0x51,
|
||||
|
@ -39,91 +37,19 @@ static const size_t MAX_TOUCHES = 5; // max number of possible touches reported
|
|||
|
||||
class FT5x06Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override {
|
||||
esph_log_config(TAG, "Setting up FT5x06 Touchscreen...");
|
||||
// wait 200ms after reset.
|
||||
this->set_timeout(200, [this] { this->continue_setup_(); });
|
||||
}
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
void update_touches() override;
|
||||
|
||||
void continue_setup_(void) {
|
||||
uint8_t data[4];
|
||||
if (!this->set_mode_(FT5X06_OP_MODE))
|
||||
return;
|
||||
|
||||
if (!this->err_check_(this->read_register(FT5X06_VENDOR_ID_REG, data, 1), "Read Vendor ID"))
|
||||
return;
|
||||
switch (data[0]) {
|
||||
case FT5X06_ID_1:
|
||||
case FT5X06_ID_2:
|
||||
case FT5X06_ID_3:
|
||||
this->vendor_id_ = (VendorId) data[0];
|
||||
esph_log_d(TAG, "Read vendor ID 0x%X", data[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
esph_log_e(TAG, "Unknown vendor ID 0x%X", data[0]);
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
// reading the chip registers to get max x/y does not seem to work.
|
||||
if (this->display_ != nullptr) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
esph_log_config(TAG, "FT5x06 Touchscreen setup complete");
|
||||
}
|
||||
|
||||
void update_touches() override {
|
||||
uint8_t touch_cnt;
|
||||
uint8_t data[MAX_TOUCHES][6];
|
||||
|
||||
if (!this->read_byte(FT5X06_TD_STATUS, &touch_cnt) || touch_cnt > MAX_TOUCHES) {
|
||||
esph_log_w(TAG, "Failed to read status");
|
||||
return;
|
||||
}
|
||||
if (touch_cnt == 0)
|
||||
return;
|
||||
|
||||
if (!this->read_bytes(FT5X06_TOUCH_DATA, (uint8_t *) data, touch_cnt * 6)) {
|
||||
esph_log_w(TAG, "Failed to read touch data");
|
||||
return;
|
||||
}
|
||||
for (uint8_t i = 0; i != touch_cnt; i++) {
|
||||
uint8_t status = data[i][0] >> 6;
|
||||
uint8_t id = data[i][2] >> 3;
|
||||
uint16_t x = encode_uint16(data[i][0] & 0x0F, data[i][1]);
|
||||
uint16_t y = encode_uint16(data[i][2] & 0xF, data[i][3]);
|
||||
|
||||
esph_log_d(TAG, "Read %X status, id: %d, pos %d/%d", status, id, x, y);
|
||||
if (status == 0 || status == 2) {
|
||||
this->add_raw_touch_position_(id, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_config() override {
|
||||
esph_log_config(TAG, "FT5x06 Touchscreen:");
|
||||
esph_log_config(TAG, " Address: 0x%02X", this->address_);
|
||||
esph_log_config(TAG, " Vendor ID: 0x%X", (int) this->vendor_id_);
|
||||
}
|
||||
void set_interrupt_pin(InternalGPIOPin *interrupt_pin) { this->interrupt_pin_ = interrupt_pin; }
|
||||
|
||||
protected:
|
||||
bool err_check_(i2c::ErrorCode err, const char *msg) {
|
||||
if (err != i2c::ERROR_OK) {
|
||||
this->mark_failed();
|
||||
esph_log_e(TAG, "%s failed - err 0x%X", msg, err);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool set_mode_(FTMode mode) {
|
||||
return this->err_check_(this->write_register(FT5X06_MODE_REG, (uint8_t *) &mode, 1), "Set mode");
|
||||
}
|
||||
void continue_setup_();
|
||||
bool err_check_(i2c::ErrorCode err, const char *msg);
|
||||
bool set_mode_(FTMode mode);
|
||||
VendorId vendor_id_{FT5X06_ID_UNKNOWN};
|
||||
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace ft5x06
|
||||
|
|
Loading…
Reference in a new issue