Add touch_probe and touch_reset actions to the Elecrow for a diagnosis over the API (0.2.97, firmware 0.2.83)
This commit is contained in:
@@ -7,6 +7,10 @@
|
||||
// (setup priority 700, between the bus's 1000 and the driver's 600), so the driver finds it at 0x5D. A V2.0 board
|
||||
// has no expander: the writes fail, the log says so, and the GT911 boots by its pull-up as before.
|
||||
//
|
||||
// probe() and reset() are the touch_probe and touch_reset actions of the board file (firmware 0.2.83): the expander's
|
||||
// registers and whether a GT911 answers at 0x5D or 0x14 (its product id, "911"), and the same sequence with values of
|
||||
// one's own, for a diagnosis over the API without a new build.
|
||||
//
|
||||
// Only the Elecrow's board file builds this (`smart_display: elecrow_touch_reset:`, which sets the flag), so the
|
||||
// header adds nothing to a CYD, which has no I2C at all.
|
||||
#if defined(ESP_SCREENS_ELECROW_TOUCH_RESET) && ESP_SCREENS_ELECROW_TOUCH_RESET
|
||||
@@ -19,22 +23,54 @@ namespace elecrow {
|
||||
class TouchReset : public esphome::Component, public esphome::i2c::I2CDevice {
|
||||
public:
|
||||
float get_setup_priority() const override { return 700.0f; }
|
||||
void setup() override {
|
||||
auto write = [this](uint8_t reg, uint8_t value) {
|
||||
const uint8_t data[2] = {reg, value};
|
||||
return this->write(data, sizeof(data)) == esphome::i2c::ERROR_OK;
|
||||
};
|
||||
bool ok = write(0x03, 0x00); // configuration: every pin an output
|
||||
ok = write(0x01, 0x00) && ok; // output: reset low, interrupt low (address 0x5D), the rest low
|
||||
esphome::delay(20);
|
||||
ok = write(0x01, 0x01) && ok; // reset released, the interrupt line still low
|
||||
esphome::delay(100);
|
||||
ok = write(0x03, 0x02) && ok; // the interrupt line an input again; the GT911 drives it from here
|
||||
void setup() override { this->reset(0x00, 0x00, 0x01, 20, 100, 0x02); }
|
||||
|
||||
// Elecrow's sequence with its values: `config` the expander's configuration register during the reset (0 = every
|
||||
// pin an output), `low` its output register while the reset is held, `high` after the release, `final_config`
|
||||
// afterwards; then the probe.
|
||||
void reset(int config, int low, int high, int hold_ms, int wait_ms, int final_config) {
|
||||
bool ok = this->write_reg_(0x03, config);
|
||||
ok = this->write_reg_(0x01, low) && ok;
|
||||
esphome::delay(hold_ms);
|
||||
ok = this->write_reg_(0x01, high) && ok;
|
||||
esphome::delay(wait_ms);
|
||||
ok = this->write_reg_(0x03, final_config) && ok;
|
||||
if (ok) {
|
||||
ESP_LOGI("touch", "GT911 reset through the PCA9557 at 0x%02X", this->address_);
|
||||
ESP_LOGI("touch", "GT911 reset through the PCA9557 at 0x%02X: config 0x%02X, out 0x%02X -> 0x%02X, %d + %d ms, config 0x%02X",
|
||||
this->address_, config, low, high, hold_ms, wait_ms, final_config);
|
||||
} else {
|
||||
ESP_LOGW("touch", "No PCA9557 at 0x%02X: the GT911 was not reset (a V2.0 board boots it by its pull-up)", this->address_);
|
||||
}
|
||||
this->probe();
|
||||
}
|
||||
|
||||
// The expander's four registers and the GT911's answer at both addresses.
|
||||
void probe() {
|
||||
uint8_t regs[4] = {0, 0, 0, 0};
|
||||
bool ok = true;
|
||||
for (uint8_t reg = 0; reg < 4; ++reg) {
|
||||
ok = this->write(®, 1) == esphome::i2c::ERROR_OK && this->read(®s[reg], 1) == esphome::i2c::ERROR_OK && ok;
|
||||
}
|
||||
ESP_LOGI("touch", "PCA9557 at 0x%02X: %s input 0x%02X output 0x%02X polarity 0x%02X config 0x%02X", this->address_,
|
||||
ok ? "answers," : "no answer;", regs[0], regs[1], regs[2], regs[3]);
|
||||
for (uint8_t address : {0x5D, 0x14}) {
|
||||
esphome::i2c::I2CDevice chip;
|
||||
chip.set_i2c_bus(this->bus_);
|
||||
chip.set_i2c_address(address);
|
||||
const uint8_t product_id[2] = {0x81, 0x40};
|
||||
uint8_t id[4] = {0, 0, 0, 0};
|
||||
const bool written = chip.write(product_id, sizeof(product_id)) == esphome::i2c::ERROR_OK;
|
||||
const bool read = written && chip.read(id, sizeof(id)) == esphome::i2c::ERROR_OK;
|
||||
ESP_LOGI("touch", "GT911 at 0x%02X: %s%s product id %02X %02X %02X %02X (\"%c%c%c\")", address,
|
||||
written ? "write ok, " : "no write ack, ", read ? "read ok," : "no read,", id[0], id[1], id[2], id[3],
|
||||
id[0] >= 32 && id[0] < 127 ? id[0] : '.', id[1] >= 32 && id[1] < 127 ? id[1] : '.', id[2] >= 32 && id[2] < 127 ? id[2] : '.');
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool write_reg_(uint8_t reg, int value) {
|
||||
const uint8_t data[2] = {reg, static_cast<uint8_t>(value)};
|
||||
return this->write(data, sizeof(data)) == esphome::i2c::ERROR_OK;
|
||||
}
|
||||
};
|
||||
} // namespace elecrow
|
||||
|
||||
Reference in New Issue
Block a user