ESPHome  2022.8.0
lilygo_t5_47_touchscreen.cpp
Go to the documentation of this file.
2 
3 #include "esphome/core/helpers.h"
4 #include "esphome/core/log.h"
5 
6 namespace esphome {
7 namespace lilygo_t5_47 {
8 
9 static const char *const TAG = "lilygo_t5_47.touchscreen";
10 
11 static const uint8_t POWER_REGISTER = 0xD6;
12 static const uint8_t TOUCH_REGISTER = 0xD0;
13 
14 static const uint8_t WAKEUP_CMD[1] = {0x06};
15 static const uint8_t READ_FLAGS[1] = {0x00};
16 static const uint8_t CLEAR_FLAGS[2] = {0x00, 0xAB};
17 static const uint8_t READ_TOUCH[1] = {0x07};
18 
19 #define ERROR_CHECK(err) \
20  if ((err) != i2c::ERROR_OK) { \
21  ESP_LOGE(TAG, "Failed to communicate!"); \
22  this->status_set_warning(); \
23  return; \
24  }
25 
26 void Store::gpio_intr(Store *store) { store->touch = true; }
27 
29  ESP_LOGCONFIG(TAG, "Setting up Lilygo T5 4.7 Touchscreen...");
30  this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
31  this->interrupt_pin_->setup();
32 
33  this->store_.pin = this->interrupt_pin_->to_isr();
34  this->interrupt_pin_->attach_interrupt(Store::gpio_intr, &this->store_, gpio::INTERRUPT_FALLING_EDGE);
35 
36  if (this->write(nullptr, 0) != i2c::ERROR_OK) {
37  ESP_LOGE(TAG, "Failed to communicate!");
38  this->interrupt_pin_->detach_interrupt();
39  this->mark_failed();
40  return;
41  }
42 
43  this->write_register(POWER_REGISTER, WAKEUP_CMD, 1);
44 }
45 
47  if (!this->store_.touch) {
48  for (auto *listener : this->touch_listeners_)
49  listener->release();
50  return;
51  }
52  this->store_.touch = false;
53 
54  uint8_t point = 0;
55  uint8_t buffer[40] = {0};
56  uint32_t sum_l = 0, sum_h = 0;
57 
58  i2c::ErrorCode err;
59  err = this->write_register(TOUCH_REGISTER, READ_FLAGS, 1);
60  ERROR_CHECK(err);
61 
62  err = this->read(buffer, 7);
63  ERROR_CHECK(err);
64 
65  if (buffer[0] == 0xAB) {
66  this->write_register(TOUCH_REGISTER, CLEAR_FLAGS, 2);
67  return;
68  }
69 
70  point = buffer[5] & 0xF;
71 
72  if (point == 0) {
73  for (auto *listener : this->touch_listeners_)
74  listener->release();
75  return;
76  } else if (point == 1) {
77  err = this->write_register(TOUCH_REGISTER, READ_TOUCH, 1);
78  ERROR_CHECK(err);
79  err = this->read(&buffer[5], 2);
80  ERROR_CHECK(err);
81 
82  sum_l = buffer[5] << 8 | buffer[6];
83  } else if (point > 1) {
84  err = this->write_register(TOUCH_REGISTER, READ_TOUCH, 1);
85  ERROR_CHECK(err);
86  err = this->read(&buffer[5], 5 * (point - 1) + 3);
87  ERROR_CHECK(err);
88 
89  sum_l = buffer[5 * point + 1] << 8 | buffer[5 * point + 2];
90  }
91 
92  this->write_register(TOUCH_REGISTER, CLEAR_FLAGS, 2);
93 
94  for (int i = 0; i < 5 * point; i++)
95  sum_h += buffer[i];
96 
97  if (sum_l != sum_h)
98  point = 0;
99 
100  if (point) {
101  uint8_t offset;
102  for (int i = 0; i < point; i++) {
103  if (i == 0) {
104  offset = 0;
105  } else {
106  offset = 4;
107  }
108 
109  TouchPoint tp;
110 
111  tp.id = (buffer[i * 5 + offset] >> 4) & 0x0F;
112  tp.state = buffer[i * 5 + offset] & 0x0F;
113  if (tp.state == 0x06)
114  tp.state = 0x07;
115 
116  uint16_t y = (uint16_t)((buffer[i * 5 + 1 + offset] << 4) | ((buffer[i * 5 + 3 + offset] >> 4) & 0x0F));
117  uint16_t x = (uint16_t)((buffer[i * 5 + 2 + offset] << 4) | (buffer[i * 5 + 3 + offset] & 0x0F));
118 
119  switch (this->rotation_) {
120  case ROTATE_0_DEGREES:
121  tp.y = this->display_height_ - y;
122  tp.x = x;
123  break;
124  case ROTATE_90_DEGREES:
125  tp.x = this->display_height_ - y;
126  tp.y = this->display_width_ - x;
127  break;
128  case ROTATE_180_DEGREES:
129  tp.y = y;
130  tp.x = this->display_width_ - x;
131  break;
132  case ROTATE_270_DEGREES:
133  tp.x = y;
134  tp.y = x;
135  break;
136  }
137 
138  this->defer([this, tp]() { this->send_touch_(tp); });
139  }
140  } else {
141  TouchPoint tp;
142  tp.id = (buffer[0] >> 4) & 0x0F;
143  tp.state = 0x06;
144 
145  uint16_t y = (uint16_t)((buffer[0 * 5 + 1] << 4) | ((buffer[0 * 5 + 3] >> 4) & 0x0F));
146  uint16_t x = (uint16_t)((buffer[0 * 5 + 2] << 4) | (buffer[0 * 5 + 3] & 0x0F));
147 
148  switch (this->rotation_) {
149  case ROTATE_0_DEGREES:
150  tp.y = this->display_height_ - y;
151  tp.x = x;
152  break;
153  case ROTATE_90_DEGREES:
154  tp.x = this->display_height_ - y;
155  tp.y = this->display_width_ - x;
156  break;
157  case ROTATE_180_DEGREES:
158  tp.y = y;
159  tp.x = this->display_width_ - x;
160  break;
161  case ROTATE_270_DEGREES:
162  tp.x = y;
163  tp.y = x;
164  break;
165  }
166 
167  this->defer([this, tp]() { this->send_touch_(tp); });
168  }
169 
170  this->status_clear_warning();
171 }
172 
174  ESP_LOGCONFIG(TAG, "Lilygo T5 47 Touchscreen:");
175  LOG_I2C_DEVICE(this);
176  LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
177 }
178 
179 } // namespace lilygo_t5_47
180 } // namespace esphome
static void gpio_intr(Store *store)
Definition: a4988.cpp:4