ESPHome  2024.5.0
ft5x06_touchscreen.h
Go to the documentation of this file.
1 #pragma once
2 
6 #include "esphome/core/hal.h"
7 #include "esphome/core/log.h"
8 
9 namespace esphome {
10 namespace ft5x06 {
11 
12 static const char *const TAG = "ft5x06.touchscreen";
13 
14 enum VendorId {
16  FT5X06_ID_1 = 0x51,
17  FT5X06_ID_2 = 0x11,
18  FT5X06_ID_3 = 0xCD,
19 };
20 
21 enum FTCmd : uint8_t {
28  FT5X06_I_MODE = 0xA4,
30 };
31 
32 enum FTMode : uint8_t {
36 };
37 
38 static const size_t MAX_TOUCHES = 5; // max number of possible touches reported
39 
41  public:
42  void setup() override {
43  esph_log_config(TAG, "Setting up FT5x06 Touchscreen...");
44  // wait 200ms after reset.
45  this->set_timeout(200, [this] { this->continue_setup_(); });
46  }
47 
48  void continue_setup_(void) {
49  uint8_t data[4];
50  if (!this->set_mode_(FT5X06_OP_MODE))
51  return;
52 
53  if (!this->err_check_(this->read_register(FT5X06_VENDOR_ID_REG, data, 1), "Read Vendor ID"))
54  return;
55  switch (data[0]) {
56  case FT5X06_ID_1:
57  case FT5X06_ID_2:
58  case FT5X06_ID_3:
59  this->vendor_id_ = (VendorId) data[0];
60  esph_log_d(TAG, "Read vendor ID 0x%X", data[0]);
61  break;
62 
63  default:
64  esph_log_e(TAG, "Unknown vendor ID 0x%X", data[0]);
65  this->mark_failed();
66  return;
67  }
68  // reading the chip registers to get max x/y does not seem to work.
69  if (this->display_ != nullptr) {
70  if (this->x_raw_max_ == this->x_raw_min_) {
71  this->x_raw_max_ = this->display_->get_native_width();
72  }
73  if (this->y_raw_max_ == this->y_raw_min_) {
74  this->y_raw_max_ = this->display_->get_native_height();
75  }
76  }
77  esph_log_config(TAG, "FT5x06 Touchscreen setup complete");
78  }
79 
80  void update_touches() override {
81  uint8_t touch_cnt;
82  uint8_t data[MAX_TOUCHES][6];
83 
84  if (!this->read_byte(FT5X06_TD_STATUS, &touch_cnt) || touch_cnt > MAX_TOUCHES) {
85  esph_log_w(TAG, "Failed to read status");
86  return;
87  }
88  if (touch_cnt == 0)
89  return;
90 
91  if (!this->read_bytes(FT5X06_TOUCH_DATA, (uint8_t *) data, touch_cnt * 6)) {
92  esph_log_w(TAG, "Failed to read touch data");
93  return;
94  }
95  for (uint8_t i = 0; i != touch_cnt; i++) {
96  uint8_t status = data[i][0] >> 6;
97  uint8_t id = data[i][2] >> 3;
98  uint16_t x = encode_uint16(data[i][0] & 0x0F, data[i][1]);
99  uint16_t y = encode_uint16(data[i][2] & 0xF, data[i][3]);
100 
101  esph_log_d(TAG, "Read %X status, id: %d, pos %d/%d", status, id, x, y);
102  if (status == 0 || status == 2) {
103  this->add_raw_touch_position_(id, x, y);
104  }
105  }
106  }
107 
108  void dump_config() override {
109  esph_log_config(TAG, "FT5x06 Touchscreen:");
110  esph_log_config(TAG, " Address: 0x%02X", this->address_);
111  esph_log_config(TAG, " Vendor ID: 0x%X", (int) this->vendor_id_);
112  }
113 
114  protected:
115  bool err_check_(i2c::ErrorCode err, const char *msg) {
116  if (err != i2c::ERROR_OK) {
117  this->mark_failed();
118  esph_log_e(TAG, "%s failed - err 0x%X", msg, err);
119  return false;
120  }
121  return true;
122  }
124  return this->err_check_(this->write_register(FT5X06_MODE_REG, (uint8_t *) &mode, 1), "Set mode");
125  }
127 };
128 
129 } // namespace ft5x06
130 } // namespace esphome
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition: i2c.cpp:10
bool err_check_(i2c::ErrorCode err, const char *msg)
uint16_t x
Definition: tt21100.cpp:17
int get_native_height()
Get the native (original) height of the display in pixels.
Definition: display.h:222
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition: i2c.h:212
uint16_t y
Definition: tt21100.cpp:18
int get_native_width()
Get the native (original) width of the display in pixels.
Definition: display.h:220
No error found during execution of method.
Definition: i2c_bus.h:13
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition: helpers.h:182
uint8_t address_
store the address of the device on the bus
Definition: i2c.h:269
uint8_t status
Definition: bl0942.h:23
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
void add_raw_touch_position_(uint8_t id, int16_t x_raw, int16_t y_raw, int16_t z_raw=0)
Definition: touchscreen.cpp:74
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a specific register in the I²C device
Definition: i2c.cpp:25
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition: i2c_bus.h:11
This Class provides the methods to read/write bytes from/to an i2c device.
Definition: i2c.h:133