ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
xpt2046.cpp
Go to the documentation of this file.
1#include "xpt2046.h"
3#include "esphome/core/log.h"
4
5#include <algorithm>
6
7namespace esphome::xpt2046 {
8
9static constexpr uint8_t XPT_READ_Z1 = 0xB0;
10static constexpr uint8_t XPT_READ_Z2 = 0xC0;
11static constexpr uint8_t XPT_READ_X = 0xD0;
12static constexpr uint8_t XPT_READ_Y = 0x90;
13static constexpr uint8_t XPT_ADC_ON = 0x01;
14static constexpr uint8_t XPT_VREF_ON = 0x02;
15
16static const char *const TAG = "xpt2046";
17
19 if (this->irq_pin_ != nullptr) {
20 // The pin reports a touch with a falling edge. Unfortunately the pin goes also changes state
21 // while the channels are read and wiring it as an interrupt is not straightforward and would
22 // need careful masking. A GPIO poll is cheap so we'll just use that.
23
24 this->irq_pin_->setup(); // INPUT
26 this->irq_pin_->setup();
28 }
29 this->spi_setup();
30 this->read_adc_(XPT_READ_X); // ADC powerdown, enable PENIRQ pin
31}
32
34 int16_t data[6], x_raw, y_raw, z_raw;
35 bool touch = false;
36
37 enable();
38
39 int16_t touch_pressure_1 = this->read_adc_(XPT_READ_Z1 | XPT_ADC_ON);
40 int16_t touch_pressure_2 = this->read_adc_(XPT_READ_Z2 | XPT_ADC_ON);
41 z_raw = touch_pressure_1 + 0xfff - touch_pressure_2;
42 ESP_LOGVV(TAG, "Touchscreen Update z = %d", z_raw);
43 touch = (z_raw >= this->threshold_);
44 if (touch) {
45 read_adc_(XPT_READ_X | XPT_ADC_ON); // dummy X measure, 1st is always noisy
46 // make 3 x-y measurements
47 data[0] = this->read_adc_(XPT_READ_Y | XPT_ADC_ON);
48 data[1] = this->read_adc_(XPT_READ_X | XPT_ADC_ON);
49 data[2] = this->read_adc_(XPT_READ_Y | XPT_ADC_ON);
50 data[3] = this->read_adc_(XPT_READ_X | XPT_ADC_ON);
51 data[4] = this->read_adc_(XPT_READ_Y | XPT_ADC_ON);
52 }
53
54 data[5] = this->read_adc_(XPT_READ_X); // Last X touch power down
55
56 disable();
57
58 if (touch) {
59 x_raw = best_two_avg(data[1], data[3], data[5]);
60 y_raw = best_two_avg(data[0], data[2], data[4]);
61
62 ESP_LOGD(TAG, "Touchscreen Update [%d, %d], z = %d", x_raw, y_raw, z_raw);
63
64 this->add_raw_touch_position_(0, x_raw, y_raw, z_raw);
65 }
66}
67
69 ESP_LOGCONFIG(TAG,
70 "XPT2046:\n"
71 " X min: %d\n"
72 " X max: %d\n"
73 " Y min: %d\n"
74 " Y max: %d\n"
75 " Swap X/Y: %s\n"
76 " Invert X: %s\n"
77 " Invert Y: %s\n"
78 " threshold: %d",
79 this->x_raw_min_, this->x_raw_max_, this->y_raw_min_, this->y_raw_max_, YESNO(this->swap_x_y_),
80 YESNO(this->invert_x_), YESNO(this->invert_y_), this->threshold_);
81 LOG_PIN(" IRQ Pin: ", this->irq_pin_);
82 LOG_UPDATE_INTERVAL(this);
83}
84
85// float XPT2046Component::get_setup_priority() const { return setup_priority::DATA; }
86
87int16_t XPT2046Component::best_two_avg(int16_t value1, int16_t value2, int16_t value3) {
88 int16_t delta_a, delta_b, delta_c;
89 int16_t reta = 0;
90
91 delta_a = (value1 > value2) ? value1 - value2 : value2 - value1;
92 delta_b = (value1 > value3) ? value1 - value3 : value3 - value1;
93 delta_c = (value3 > value2) ? value3 - value2 : value2 - value3;
94
95 if (delta_a <= delta_b && delta_a <= delta_c) {
96 reta = (value1 + value2) >> 1;
97 } else if (delta_b <= delta_a && delta_b <= delta_c) {
98 reta = (value1 + value3) >> 1;
99 } else {
100 reta = (value2 + value3) >> 1;
101 }
102
103 return reta;
104}
105
106int16_t XPT2046Component::read_adc_(uint8_t ctrl) {
107 uint8_t data[3];
108
109 data[0] = ctrl;
110 data[1] = 0;
111 data[2] = 0;
112
113 this->transfer_array(data, sizeof(data));
114
115 return ((data[1] << 8) | data[2]) >> 3;
116}
117
118} // namespace esphome::xpt2046
virtual void pin_mode(gpio::Flags flags)=0
virtual void setup()=0
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)
int16_t read_adc_(uint8_t ctrl)
Definition xpt2046.cpp:106
static int16_t best_two_avg(int16_t value1, int16_t value2, int16_t value3)
Definition xpt2046.cpp:87
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:49
@ FLAG_PULLUP
Definition gpio.h:28
@ FLAG_INPUT
Definition gpio.h:25