[gt911] Fix the interrupt pin initialisation after reset (#15021)

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
t2bottom
2026-10-12 15:42:24 -10:00
committed by GitHub
co-authored by pre-commit-ci-lite[bot] J. Nick Koston
parent 88fdf822cd
commit a035c17e04
2 changed files with 15 additions and 21 deletions
@@ -24,9 +24,13 @@ static const size_t MAX_BUTTONS = 4; // max number of buttons scanned
return; \
}
// Reset sequence (Goodix GT911 datasheet): INT held low while RST is released selects address 0x5D, then
// T3 + T4 pass before INT is handed back to the chip as its interrupt output
static constexpr uint32_t RESET_LOW_MS = 10;
static constexpr uint32_t RESET_SETTLE_MS = 5 + 50 + 1;
void GT911Touchscreen::setup() {
if (this->reset_pin_ != nullptr) {
// temporarily set the interrupt pin to output to control address selection
this->reset_pin_->setup();
this->reset_pin_->digital_write(false);
if (this->interrupt_pin_ != nullptr) {
@@ -34,20 +38,19 @@ void GT911Touchscreen::setup() {
this->interrupt_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->interrupt_pin_->digital_write(false);
}
delay(2);
this->reset_pin_->digital_write(true);
// wait at least T3+T4 ms as per the datasheet
this->set_timeout(5 + 50 + 1, [this] { this->setup_internal_(); });
this->set_timeout(RESET_LOW_MS, [this] {
this->reset_pin_->digital_write(true);
this->set_timeout(RESET_SETTLE_MS, [this] { this->setup_internal_(); });
});
return;
}
this->setup_internal_();
}
void GT911Touchscreen::setup_internal_() {
if (this->interrupt_pin_ != nullptr) {
if (this->interrupt_pin_->is_internal())
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT);
}
// Expander pins must leave output mode too, or the chip cannot drive its interrupt line
if (this->interrupt_pin_ != nullptr)
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT);
uint8_t data[4];
i2c::ErrorCode err = this->write(GET_SWITCHES, sizeof(GET_SWITCHES));
@@ -72,7 +75,7 @@ void GT911Touchscreen::setup_internal_() {
ESP_LOGD(TAG, "Interrupt pin: hardware interrupt, active %s",
active_high ? LOG_STR_LITERAL("HIGH") : LOG_STR_LITERAL("LOW"));
} else {
// IO expander pin: leave as output for configuration only.
// IO expander pin: no hardware interrupt, the touch state is polled.
ESP_LOGD(TAG, "Interrupt pin: IO expander polling mode, active %s",
active_high ? LOG_STR_LITERAL("HIGH") : LOG_STR_LITERAL("LOW"));
}
@@ -14,17 +14,8 @@ class GT911ButtonListener {
class GT911Touchscreen final : public touchscreen::Touchscreen, public i2c::I2CDevice {
public:
/// @brief Initialize the GT911 touchscreen.
///
/// If @ref reset_pin_ is set, the touchscreen will be hardware reset,
/// and the rest of the setup will be scheduled to run 50ms later using @ref set_timeout()
/// to allow the device to stabilize after reset.
///
/// If @ref interrupt_pin_ is set, it will be temporarily configured during reset
/// to control I2C address selection.
///
/// After the timeout, or immediately if no reset is performed, @ref setup_internal_()
/// is called to complete the initialization.
/// With a reset pin the chip is reset with the interrupt pin held low, which selects address 0x5D, and the
/// rest of the setup runs from timeouts once the chip is ready. Without one setup_internal_() runs at once.
void setup() override;
void dump_config() override;
bool can_proceed() override { return this->setup_done_; }