ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
st7123_touchscreen.cpp
Go to the documentation of this file.
2
4#include "esphome/core/log.h"
5
6namespace esphome::st7123 {
7
8static const char *const TAG = "st7123.touchscreen";
9
11 if (this->reset_pin_ != nullptr) {
12 this->reset_pin_->setup();
13 this->reset_pin_->digital_write(true);
14 delay(5);
15 this->reset_pin_->digital_write(false); // TP_RESX is active low, assert for at least tRSTW (2ms)
16 delay(5);
17 this->reset_pin_->digital_write(true);
18 // The controller needs up to 20ms to initialize after reset before it can be accessed.
19 this->setup_time_ = millis() + 30;
20 }
21}
22
24 // check if setup is complete
25 if (this->setup_time_ != 0) {
26 if (this->setup_time_ > millis())
27 return;
28
29 uint8_t status;
30 if (this->read_register16(ST7123_REG_STATUS, &status, 1) != i2c::ERROR_OK) {
31 this->mark_failed(LOG_STR("Failed to read status register")); // will stop updates
32 return;
33 }
34 if ((status & 0x0F) == ST7123_STATUS_INIT) {
35 ESP_LOGD(TAG, "Controller still initializing");
36 return;
37 }
38 if (this->interrupt_pin_ != nullptr) {
39 this->interrupt_pin_->setup();
40 // INT is held high when idle and pulses low when touch data is ready.
42 }
43
44 ESP_LOGD(TAG, "Status is %X", status);
45
46 uint8_t data;
47 if (this->read_register16(ST7123_REG_MAX_TOUCHES, &data, 1) == i2c::ERROR_OK && data != 0 &&
48 data <= ST7123_MAX_TOUCHES) {
49 this->max_touches_ = data;
50 }
51
52 // If no calibration was supplied, read the native coordinate resolution from the controller.
53 if (this->x_raw_max_ == this->x_raw_min_ || this->y_raw_max_ == this->y_raw_min_) {
54 uint8_t res[4];
55 if (this->read_register16(ST7123_REG_MAX_X, res, sizeof(res)) == i2c::ERROR_OK) {
56 this->x_raw_max_ = encode_uint16(res[0] & ST7123_COORD_HIGH_MASK, res[1]);
57 this->y_raw_max_ = encode_uint16(res[2] & ST7123_COORD_HIGH_MASK, res[3]);
58 if (this->swap_x_y_)
59 std::swap(this->x_raw_max_, this->y_raw_max_);
60 } else {
61 this->mark_failed(LOG_STR("Failed to read calibration"));
62 return;
63 }
64 ESP_LOGD(TAG, "Read dimensions %d/%d", this->x_raw_max_, this->y_raw_max_);
65 }
66 this->setup_time_ = 0; // flag setup complete
67 }
68 Touchscreen::update();
69}
70
72 // Read the reporting table from the advanced touch info register through the last touch point.
73 // Reading from this register also clears the INT pin so the controller can report the next frame.
74 uint8_t data[(ST7123_REG_TOUCH_DATA - ST7123_REG_ADV_TOUCH_INFO) + ST7123_MAX_TOUCHES * ST7123_TOUCH_STRIDE];
75 const size_t len = (ST7123_REG_TOUCH_DATA - ST7123_REG_ADV_TOUCH_INFO) + this->max_touches_ * ST7123_TOUCH_STRIDE;
76 if (this->read_register16(ST7123_REG_ADV_TOUCH_INFO, data, len) != i2c::ERROR_OK) {
77 this->skip_update_ = true;
78 this->status_set_warning();
79 return;
80 }
82
83 const uint8_t *points = data + (ST7123_REG_TOUCH_DATA - ST7123_REG_ADV_TOUCH_INFO);
84 for (uint8_t i = 0; i != this->max_touches_; i++) {
85 const uint8_t *p = points + i * ST7123_TOUCH_STRIDE;
86 if ((p[0] & ST7123_TOUCH_VALID) == 0)
87 continue;
88 uint16_t x = encode_uint16(p[0] & ST7123_COORD_HIGH_MASK, p[1]);
89 uint16_t y = encode_uint16(p[2] & ST7123_COORD_HIGH_MASK, p[3]);
90 uint8_t intensity = p[5];
91 ESP_LOGV(TAG, "Touch %u: x=%u, y=%u, intensity=%u", i, x, y, intensity);
92 this->add_raw_touch_position_(i, x, y, intensity);
93 }
94}
95
97 ESP_LOGCONFIG(TAG,
98 "ST7123 Touchscreen:\n"
99 " Max touches: %u\n"
100 " X Raw Min: %d, X Raw Max: %d\n"
101 " Y Raw Min: %d, Y Raw Max: %d",
102 this->max_touches_, this->x_raw_min_, this->x_raw_max_, this->y_raw_min_, this->y_raw_max_);
103 LOG_I2C_DEVICE(this);
104 LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
105 LOG_PIN(" Reset Pin: ", this->reset_pin_);
106}
107
108} // namespace esphome::st7123
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
void status_clear_warning()
Definition component.h:289
virtual void setup()=0
virtual void digital_write(bool value)=0
ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:29
void attach_interrupt_(InternalGPIOPin *irq_pin, esphome::gpio::InterruptType type)
Call this function to send touch points to the on_touch listener and the binary_sensors.
void add_raw_touch_position_(uint8_t id, int16_t x_raw, int16_t y_raw, int16_t z_raw=0)
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:49
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14
const void size_t len
Definition hal.h:64
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:873
void HOT delay(uint32_t ms)
Definition hal.cpp:85
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:28
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6