ESPHome  2022.12.8
ektf2232.cpp
Go to the documentation of this file.
1 #include "ektf2232.h"
2 #include "esphome/core/helpers.h"
3 #include "esphome/core/log.h"
4 
5 #include <vector>
6 
7 namespace esphome {
8 namespace ektf2232 {
9 
10 static const char *const TAG = "ektf2232";
11 
12 static const uint8_t SOFT_RESET_CMD[4] = {0x77, 0x77, 0x77, 0x77};
13 static const uint8_t HELLO[4] = {0x55, 0x55, 0x55, 0x55};
14 static const uint8_t GET_X_RES[4] = {0x53, 0x60, 0x00, 0x00};
15 static const uint8_t GET_Y_RES[4] = {0x53, 0x63, 0x00, 0x00};
16 static const uint8_t GET_POWER_STATE_CMD[4] = {0x53, 0x50, 0x00, 0x01};
17 
19 
21  ESP_LOGCONFIG(TAG, "Setting up EKT2232 Touchscreen...");
22  this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
23  this->interrupt_pin_->setup();
24 
25  this->store_.pin = this->interrupt_pin_->to_isr();
26  this->interrupt_pin_->attach_interrupt(EKTF2232TouchscreenStore::gpio_intr, &this->store_,
28 
29  this->rts_pin_->setup();
30 
31  this->hard_reset_();
32  if (!this->soft_reset_()) {
33  ESP_LOGE(TAG, "Failed to soft reset EKT2232!");
34  this->interrupt_pin_->detach_interrupt();
35  this->mark_failed();
36  return;
37  }
38 
39  // Get touch resolution
40  uint8_t received[4];
41  this->write(GET_X_RES, 4);
42  if (this->read(received, 4)) {
43  ESP_LOGE(TAG, "Failed to read X resolution!");
44  this->interrupt_pin_->detach_interrupt();
45  this->mark_failed();
46  return;
47  }
48  this->x_resolution_ = ((received[2])) | ((received[3] & 0xf0) << 4);
49 
50  this->write(GET_Y_RES, 4);
51  if (this->read(received, 4)) {
52  ESP_LOGE(TAG, "Failed to read Y resolution!");
53  this->interrupt_pin_->detach_interrupt();
54  this->mark_failed();
55  return;
56  }
57  this->y_resolution_ = ((received[2])) | ((received[3] & 0xf0) << 4);
58  this->store_.touch = false;
59 
60  this->set_power_state(true);
61 }
62 
64  if (!this->store_.touch)
65  return;
66  this->store_.touch = false;
67 
68  uint8_t touch_count = 0;
69  std::vector<TouchPoint> touches;
70 
71  uint8_t raw[8];
72  this->read(raw, 8);
73  for (int i = 0; i < 8; i++) {
74  if (raw[7] & (1 << i))
75  touch_count++;
76  }
77 
78  if (touch_count == 0) {
79  for (auto *listener : this->touch_listeners_)
80  listener->release();
81  return;
82  }
83 
84  touch_count = std::min<uint8_t>(touch_count, 2);
85 
86  ESP_LOGV(TAG, "Touch count: %d", touch_count);
87 
88  for (int i = 0; i < touch_count; i++) {
89  uint8_t *d = raw + 1 + (i * 3);
90  uint32_t raw_x = (d[0] & 0xF0) << 4 | d[1];
91  uint32_t raw_y = (d[0] & 0x0F) << 8 | d[2];
92 
93  raw_x = raw_x * this->display_height_ - 1;
94  raw_y = raw_y * this->display_width_ - 1;
95 
96  TouchPoint tp;
97  switch (this->rotation_) {
98  case ROTATE_0_DEGREES:
99  tp.y = raw_x / this->x_resolution_;
100  tp.x = this->display_width_ - 1 - (raw_y / this->y_resolution_);
101  break;
102  case ROTATE_90_DEGREES:
103  tp.x = raw_x / this->x_resolution_;
104  tp.y = raw_y / this->y_resolution_;
105  break;
106  case ROTATE_180_DEGREES:
107  tp.y = this->display_height_ - 1 - (raw_x / this->x_resolution_);
108  tp.x = raw_y / this->y_resolution_;
109  break;
110  case ROTATE_270_DEGREES:
111  tp.x = this->display_height_ - 1 - (raw_x / this->x_resolution_);
112  tp.y = this->display_width_ - 1 - (raw_y / this->y_resolution_);
113  break;
114  }
115 
116  this->defer([this, tp]() { this->send_touch_(tp); });
117  }
118 }
119 
121  uint8_t data[] = {0x54, 0x50, 0x00, 0x01};
122  data[1] |= (enable << 3);
123  this->write(data, 4);
124 }
125 
127  uint8_t received[4];
128  this->write(GET_POWER_STATE_CMD, 4);
129  this->store_.touch = false;
130  this->read(received, 4);
131  return (received[1] >> 3) & 1;
132 }
133 
135  this->rts_pin_->digital_write(false);
136  delay(15);
137  this->rts_pin_->digital_write(true);
138  delay(15);
139 }
140 
142  auto err = this->write(SOFT_RESET_CMD, 4);
143  if (err != i2c::ERROR_OK)
144  return false;
145 
146  uint8_t received[4];
147  uint16_t timeout = 1000;
148  while (!this->store_.touch && timeout > 0) {
149  delay(1);
150  timeout--;
151  }
152  if (timeout > 0)
153  this->store_.touch = true;
154  this->read(received, 4);
155  this->store_.touch = false;
156 
157  return !memcmp(received, HELLO, 4);
158 }
159 
161  ESP_LOGCONFIG(TAG, "EKT2232 Touchscreen:");
162  LOG_I2C_DEVICE(this);
163  LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
164  LOG_PIN(" RTS Pin: ", this->rts_pin_);
165 }
166 
167 } // namespace ektf2232
168 } // namespace esphome
uint8_t raw[35]
Definition: bl0939.h:19
static void gpio_intr(EKTF2232TouchscreenStore *store)
Definition: ektf2232.cpp:18
Definition: a4988.cpp:4
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:27