mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 08:55:22 +01:00
Fixed touch release issue using the interrupt pin (#3925)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
ca09693efa
commit
0220934e4c
2 changed files with 76 additions and 85 deletions
|
@ -20,8 +20,6 @@ void XPT2046Component::setup() {
|
||||||
this->irq_pin_->setup(); // INPUT
|
this->irq_pin_->setup(); // INPUT
|
||||||
this->irq_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
this->irq_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
||||||
this->irq_pin_->setup();
|
this->irq_pin_->setup();
|
||||||
|
|
||||||
this->store_.pin = this->irq_pin_->to_isr();
|
|
||||||
this->irq_pin_->attach_interrupt(XPT2046TouchscreenStore::gpio_intr, &this->store_, gpio::INTERRUPT_FALLING_EDGE);
|
this->irq_pin_->attach_interrupt(XPT2046TouchscreenStore::gpio_intr, &this->store_, gpio::INTERRUPT_FALLING_EDGE);
|
||||||
}
|
}
|
||||||
spi_setup();
|
spi_setup();
|
||||||
|
@ -29,11 +27,11 @@ void XPT2046Component::setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XPT2046Component::loop() {
|
void XPT2046Component::loop() {
|
||||||
if ((this->irq_pin_ == nullptr) || (!this->store_.touch))
|
if ((this->irq_pin_ != nullptr) && (this->store_.touch || this->touched)) {
|
||||||
return;
|
|
||||||
this->store_.touch = false;
|
this->store_.touch = false;
|
||||||
check_touch_();
|
check_touch_();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void XPT2046Component::update() {
|
void XPT2046Component::update() {
|
||||||
if (this->irq_pin_ == nullptr)
|
if (this->irq_pin_ == nullptr)
|
||||||
|
@ -45,35 +43,30 @@ void XPT2046Component::check_touch_() {
|
||||||
bool touch = false;
|
bool touch = false;
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
|
||||||
this->z_raw = 0;
|
|
||||||
|
|
||||||
// In case the penirq pin is present only do the SPI transaction if it reports a touch (is low).
|
|
||||||
// The touch has to be also confirmed with checking the pressure over threshold
|
|
||||||
if ((this->irq_pin_ == nullptr) || !this->irq_pin_->digital_read()) {
|
|
||||||
enable();
|
enable();
|
||||||
|
|
||||||
int16_t touch_pressure_1 = read_adc_(0xB1 /* touch_pressure_1 */);
|
int16_t touch_pressure_1 = read_adc_(0xB1 /* touch_pressure_1 */);
|
||||||
int16_t touch_pressure_2 = read_adc_(0xC1 /* touch_pressure_2 */);
|
int16_t touch_pressure_2 = read_adc_(0xC1 /* touch_pressure_2 */);
|
||||||
|
|
||||||
this->z_raw = touch_pressure_1 + 4095 - touch_pressure_2;
|
this->z_raw = touch_pressure_1 + 0Xfff - touch_pressure_2;
|
||||||
|
|
||||||
touch = (this->z_raw >= this->threshold_);
|
touch = (this->z_raw >= this->threshold_);
|
||||||
if (touch) {
|
if (touch) {
|
||||||
read_adc_(0x91 /* Y */); // dummy Y measure, 1st is always noisy
|
read_adc_(0xD1 /* X */); // dummy Y measure, 1st is always noisy
|
||||||
data[0] = read_adc_(0xD1 /* X */);
|
data[0] = read_adc_(0x91 /* Y */);
|
||||||
data[1] = read_adc_(0x91 /* Y */); // make 3 x-y measurements
|
data[1] = read_adc_(0xD1 /* X */); // make 3 x-y measurements
|
||||||
data[2] = read_adc_(0xD1 /* X */);
|
data[2] = read_adc_(0x91 /* Y */);
|
||||||
data[3] = read_adc_(0x91 /* Y */);
|
data[3] = read_adc_(0xD1 /* X */);
|
||||||
data[4] = read_adc_(0xD1 /* X */);
|
data[4] = read_adc_(0x91 /* Y */);
|
||||||
}
|
}
|
||||||
|
|
||||||
data[5] = read_adc_(0x90 /* Y */); // Last Y touch power down
|
data[5] = read_adc_(0xD0 /* X */); // Last X touch power down
|
||||||
|
|
||||||
disable();
|
disable();
|
||||||
|
|
||||||
if (touch) {
|
if (touch) {
|
||||||
this->x_raw = best_two_avg(data[0], data[2], data[4]);
|
this->x_raw = best_two_avg(data[1], data[3], data[5]);
|
||||||
this->y_raw = best_two_avg(data[1], data[3], data[5]);
|
this->y_raw = best_two_avg(data[0], data[2], data[4]);
|
||||||
|
|
||||||
ESP_LOGVV(TAG, "Update [x, y] = [%d, %d], z = %d", this->x_raw, this->y_raw, this->z_raw);
|
ESP_LOGVV(TAG, "Update [x, y] = [%d, %d], z = %d", this->x_raw, this->y_raw, this->z_raw);
|
||||||
|
|
||||||
|
@ -124,17 +117,16 @@ void XPT2046Component::check_touch_() {
|
||||||
this->touched = true;
|
this->touched = true;
|
||||||
this->last_pos_ms_ = now;
|
this->last_pos_ms_ = now;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
this->x_raw = this->y_raw = 0;
|
|
||||||
if (this->touched) {
|
if (!touch && this->touched) {
|
||||||
|
this->x_raw = this->y_raw = this->z_raw = 0;
|
||||||
ESP_LOGV(TAG, "Released [%d, %d]", this->x, this->y);
|
ESP_LOGV(TAG, "Released [%d, %d]", this->x, this->y);
|
||||||
this->touched = false;
|
this->touched = false;
|
||||||
for (auto *listener : this->touch_listeners_)
|
for (auto *listener : this->touch_listeners_)
|
||||||
listener->release();
|
listener->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void XPT2046Component::set_calibration(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max) { // NOLINT
|
void XPT2046Component::set_calibration(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max) { // NOLINT
|
||||||
this->x_raw_min_ = std::min(x_min, x_max);
|
this->x_raw_min_ = std::min(x_min, x_max);
|
||||||
|
@ -203,6 +195,7 @@ int16_t XPT2046Component::read_adc_(uint8_t ctrl) { // NOLINT
|
||||||
uint8_t data[2];
|
uint8_t data[2];
|
||||||
|
|
||||||
write_byte(ctrl);
|
write_byte(ctrl);
|
||||||
|
delay(1);
|
||||||
data[0] = read_byte();
|
data[0] = read_byte();
|
||||||
data[1] = read_byte();
|
data[1] = read_byte();
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ using namespace touchscreen;
|
||||||
|
|
||||||
struct XPT2046TouchscreenStore {
|
struct XPT2046TouchscreenStore {
|
||||||
volatile bool touch;
|
volatile bool touch;
|
||||||
ISRInternalGPIOPin pin;
|
|
||||||
|
|
||||||
static void gpio_intr(XPT2046TouchscreenStore *store);
|
static void gpio_intr(XPT2046TouchscreenStore *store);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue