Reset the Elecrow's GT911 the way Elecrow's own V3.0 example does (0.2.96, firmware 0.2.82)
The 2 ms reset of ESPHome's expander support (0.2.81) left the chip silent: "Calibration error" with the PCA9557 answering at 0x18. A component of smart_display's (elecrow_touch_reset.h, setup priority 700: after the I2C bus, before the GT911 driver) writes the expander as Elecrow's V3.0 ESPHome example does: every pin an output and low, 20 ms, the reset released, 100 ms, the interrupt line back to an input. The driver's reset and interrupt pins are gone.
This commit is contained in:
@@ -7,12 +7,16 @@ into a screen's YAML.
|
||||
|
||||
`smart_display: partitions: 4mb_wide_slots` (firmware 0.2.79) builds with one of the partition tables of partitions.py
|
||||
instead of ESPHome's own: two update slots of 1,984 KB on a 4 MB ESP32-S3, which the Elecrow CrowPanel 7.0" needs.
|
||||
|
||||
`smart_display: elecrow_touch_reset: {i2c_id: ..., address: 0x18}` (firmware 0.2.82) brings the GT911 of the Elecrow
|
||||
CrowPanel 7.0" V3.0 out of reset through its PCA9557 before the touch driver runs (elecrow_touch_reset.h).
|
||||
"""
|
||||
import logging
|
||||
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import esp32
|
||||
from esphome.components import esp32, i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.core import CORE
|
||||
from esphome.helpers import write_file_if_changed
|
||||
|
||||
@@ -24,6 +28,10 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_LANGUAGE = "language"
|
||||
CONF_PARTITIONS = "partitions"
|
||||
CONF_ELECROW_TOUCH_RESET = "elecrow_touch_reset"
|
||||
|
||||
elecrow_ns = cg.global_ns.namespace("elecrow")
|
||||
TouchReset = elecrow_ns.class_("TouchReset", cg.Component, i2c.I2CDevice)
|
||||
|
||||
|
||||
def _language(value):
|
||||
@@ -36,6 +44,8 @@ def _language(value):
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_LANGUAGE, default="en"): _language,
|
||||
cv.Optional(CONF_PARTITIONS): cv.one_of(*partitions.TABLES, lower=True),
|
||||
cv.Optional(CONF_ELECROW_TOUCH_RESET): cv.Schema({cv.GenerateID(): cv.declare_id(TouchReset)})
|
||||
.extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x18)),
|
||||
})
|
||||
|
||||
|
||||
@@ -51,3 +61,9 @@ async def to_code(config):
|
||||
table = CORE.relative_build_path("smart_display_partitions.csv")
|
||||
write_file_if_changed(table, partitions.TABLES[config[CONF_PARTITIONS]])
|
||||
esp32.add_extra_build_file("partitions.csv", table)
|
||||
if CONF_ELECROW_TOUCH_RESET in config:
|
||||
conf = config[CONF_ELECROW_TOUCH_RESET]
|
||||
reset = cg.new_Pvariable(conf[CONF_ID])
|
||||
await cg.register_component(reset, conf)
|
||||
await i2c.register_i2c_device(reset, conf)
|
||||
cg.add_build_flag("-DESP_SCREENS_ELECROW_TOUCH_RESET=1")
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
// The GT911 of the Elecrow CrowPanel 7.0" V3.0 hangs on a PCA9557 I/O expander (I2C 0x18): IO0 is its reset, IO1 its
|
||||
// interrupt line, and it stays in reset until something drives them (firmware 0.2.82). This is Elecrow's own sequence
|
||||
// from their V3.0 ESPHome example, byte for byte: every expander pin an output and low (the reset held, the interrupt
|
||||
// line low so the chip takes address 0x5D), 20 ms, the reset released, 100 ms for the chip to come up, then the
|
||||
// interrupt line back to an input. It runs after the I2C bus is up and before the GT911 driver looks for the chip
|
||||
// (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.
|
||||
//
|
||||
// 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
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
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
|
||||
if (ok) {
|
||||
ESP_LOGI("touch", "GT911 reset through the PCA9557 at 0x%02X", this->address_);
|
||||
} 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_);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace elecrow
|
||||
#endif
|
||||
+7
-6
@@ -41,12 +41,13 @@ suits a screen that stands further away.
|
||||
|
||||
The GT911 is polled every 20 ms over I2C at 400 kHz. The **V3.0** has a PCA9557 I/O expander (I2C 0x18) on the
|
||||
GT911's reset (IO0) and interrupt (IO1) lines, and a unit tested here kept its GT911 in reset until something drove
|
||||
them (`touchscreen is marked FAILED: Calibration error` in the log, firmware 0.2.79 and 0.2.80). The board file
|
||||
(firmware 0.2.81) declares the expander as ESPHome's `pca9554` (the same register map) and hands the GT911 driver its
|
||||
reset and interrupt pins on it: the driver runs Elecrow's own sequence, reset low with the interrupt line low, reset
|
||||
high, then 56 ms, which also fixes the address at 0x5D. A V2.0 board without the expander boots its GT911 by the
|
||||
pull-up as before; the expander's setup fails there, harmlessly, and the driver tries 0x14 by itself when 0x5D does
|
||||
not answer, so no address override is ever needed.
|
||||
them (`touchscreen is marked FAILED: Calibration error` in the log, firmware 0.2.79 to 0.2.81; 0.2.81 tried ESPHome's
|
||||
own expander support, whose 2 ms reset pulse the chip ignored). `smart_display: elecrow_touch_reset` (firmware 0.2.82,
|
||||
`components/smart_display/elecrow_touch_reset.h`) runs the sequence of Elecrow's V3.0 ESPHome example before the
|
||||
driver looks for the chip: every expander pin an output and low (the reset held, the interrupt line low so the chip
|
||||
takes address 0x5D), 20 ms, the reset released, 100 ms, the interrupt line back to an input. The log says `GT911 reset
|
||||
through the PCA9557`. A V2.0 board without the expander boots its GT911 by the pull-up as before (the writes fail, the
|
||||
log says so), and the driver tries 0x14 by itself when 0x5D does not answer, so no address override is ever needed.
|
||||
|
||||
The bus is scanned at boot. For a diagnosis, give the screen `logger: level: DEBUG` in its Override YAML (Screen
|
||||
settings → Override YAML) and read its log: the scan lists 0x18 (the expander) and 0x5D or 0x14 (the GT911), and the
|
||||
|
||||
@@ -383,6 +383,10 @@ psram:
|
||||
# CLOSE_CARDS_HOOK, MAY_OPEN_EXTRA, TICK_HOOK, AWAY_EXTRA and ALERT_SHOW_HOOK emptied) it is 1,754 KB, 86.4 %.
|
||||
smart_display:
|
||||
partitions: 4mb_wide_slots
|
||||
# The GT911 out of reset through the V3.0's PCA9557 before the driver runs (elecrow_touch_reset.h, firmware 0.2.82).
|
||||
elecrow_touch_reset:
|
||||
i2c_id: touch_bus
|
||||
address: 0x18
|
||||
|
||||
# The icon fonts at 2 bits a pixel (four levels of edge smoothing instead of sixteen) where the text keeps its four:
|
||||
# the three sizes of the 314 tile icons are 312 KB at 4 bits, half that at 2. The text fonts are the sharper for it.
|
||||
@@ -487,29 +491,21 @@ text_sensor:
|
||||
update_interval: 60s
|
||||
lambda: 'return {"elecrow"};'
|
||||
|
||||
# Pinout of the CrowPanel 7.0" (DIS08070H, V2.0 and V3.0): Elecrow's wiki and the ESPHome devices page. The V3.0 has a
|
||||
# PCA9557 I/O expander at I2C 0x18 on the GT911's reset (IO0) and interrupt (IO1) lines, and the GT911 stays in reset
|
||||
# until something drives them (firmware 0.2.81: a unit whose touch never answered, "Calibration error" at setup). The
|
||||
# expander gets the same register map as the PCA9554 ESPHome knows, and the GT911 driver does Elecrow's own reset
|
||||
# through it: reset low with the interrupt line low (that picks address 0x5D), reset high, 56 ms. On a V2.0 without
|
||||
# the expander its setup fails, the GT911 boots by its pull-up as before, and the driver still finds it (it tries 0x14
|
||||
# by itself when 0x5D does not answer).
|
||||
# Pinout of the CrowPanel 7.0" (DIS08070H, V2.0 and V3.0): Elecrow's wiki and their V3.0 ESPHome example. The V3.0 has
|
||||
# a PCA9557 I/O expander at I2C 0x18 on the GT911's reset (IO0) and interrupt (IO1) lines, and the GT911 stays in
|
||||
# reset until something drives them: on a unit tested here the driver reported "Calibration error" at setup
|
||||
# (firmware 0.2.79 to 0.2.81, the last one through ESPHome's own expander support, whose 2 ms reset the chip ignored).
|
||||
# elecrow_touch_reset (below) runs Elecrow's own sequence before the driver looks for the chip; a V2.0 without the
|
||||
# expander boots its GT911 by the pull-up as before, and the driver tries 0x14 by itself when 0x5D does not answer.
|
||||
i2c:
|
||||
id: touch_bus
|
||||
sda: GPIO19
|
||||
scl: GPIO20
|
||||
frequency: 400kHz
|
||||
# The scan logs what answers on the bus (0x18 the expander, 0x5D or 0x14 the GT911), with `logger: level: DEBUG` in
|
||||
# a screen's Override YAML: which revision a screen is, and whether the bus is alive at all. It runs before the
|
||||
# GT911's reset, so it upsets nothing.
|
||||
# The scan logs what answers on the bus with `logger: level: DEBUG` in a screen's Override YAML: 0x18 is the
|
||||
# expander; the GT911 is still in reset at that moment and shows up in the driver's own line instead.
|
||||
scan: true
|
||||
|
||||
pca9554:
|
||||
- id: touch_expander
|
||||
i2c_id: touch_bus
|
||||
address: 0x18
|
||||
pin_count: 8
|
||||
|
||||
output:
|
||||
- platform: ledc
|
||||
pin: GPIO2
|
||||
@@ -533,12 +529,6 @@ touchscreen:
|
||||
i2c_id: touch_bus
|
||||
# The reset through the expander picks 0x5D; the driver tries 0x14 by itself when that does not answer.
|
||||
address: 0x5D
|
||||
reset_pin:
|
||||
pca9554: touch_expander
|
||||
number: 0
|
||||
interrupt_pin:
|
||||
pca9554: touch_expander
|
||||
number: 1
|
||||
display: my_display
|
||||
update_interval: 20ms
|
||||
transform:
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
# fonts/materialdesignicons-webfont.ttf (Apache 2.0, github.com/Templarian/MaterialDesign-Webfont).
|
||||
############################################################
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.81"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.82"
|
||||
DASHBOARD_INBOX_INTERNAL: "false"
|
||||
CALIBRATION_ON_BOOT: "false" # a bench build: start on the touch test page
|
||||
ROOM_NAME: "" # top left until ESP Screens sends the screen name
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## 0.2.96 (firmware 0.2.82)
|
||||
|
||||
The Elecrow's touch chip reset the way Elecrow does it.
|
||||
|
||||
- **Elecrow CrowPanel 7.0" V3.0: Elecrow's own reset sequence.** Firmware 0.2.81 reset the GT911 through ESPHome's expander support, a 2 ms pulse the chip ignored on the unit tested (its log still said `Calibration error`, with the PCA9557 answering at 0x18). The board file now runs the sequence of Elecrow's V3.0 ESPHome example, byte for byte, before the touch driver looks for the chip: every expander pin an output and low, 20 ms, the reset released, 100 ms, the interrupt line back to an input (`smart_display: elecrow_touch_reset`, components/smart_display/elecrow_touch_reset.h). The log says `GT911 reset through the PCA9557`, or that no expander answered (a V2.0 board, which boots its GT911 by the pull-up).
|
||||
- Needs firmware 0.2.82 on an Elecrow: press **Update** on the screen. Elecrow firmware: 1,866,128 bytes, 91.9 % of its update slot.
|
||||
|
||||
## 0.2.95 (firmware 0.2.81)
|
||||
|
||||
The Elecrow's touch chip brought out of reset.
|
||||
|
||||
@@ -54,7 +54,7 @@ REFS = {'cyd': 'main', 'guition': 'main', 'elecrow': 'main'}
|
||||
# is the small one. The Elecrow CrowPanel 7.0" (app 0.2.93) is the Guition's kind at 800x480, without the Rotation.
|
||||
LARGE_BOARDS = ('guition', 'elecrow')
|
||||
# Firmware shipped with this app release; screens below it get an update offer.
|
||||
FIRMWARE_VERSION = '0.2.81'
|
||||
FIRMWARE_VERSION = '0.2.82'
|
||||
# The Auto standby switch a screen offers Home Assistant automations.
|
||||
AUTO_STANDBY_MIN_FIRMWARE = '0.2.41'
|
||||
# The settings page the screen opens itself, and the screen.settings tile that opens it.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: ESP Screen Manager
|
||||
version: "0.2.95"
|
||||
version: "0.2.96"
|
||||
slug: esp_screen_manager
|
||||
description: Choose tiles for your CYD and Guition touchscreen, without reflashing.
|
||||
url: https://gittea.trippedonmy.name/Xandrossian/homeassistant_espscreen
|
||||
|
||||
@@ -57,10 +57,15 @@ class BoardFile(unittest.TestCase):
|
||||
self.assertIn('pin: GPIO2', TEXT)
|
||||
# The USB pins are the touch I2C: the header that frees them.
|
||||
self.assertIn('<esphome/components/smart_display/elecrow_usb_phy.h>', TEXT)
|
||||
# The V3.0's PCA9557 (as ESPHome's pca9554, the same registers) brings the GT911 out of reset (firmware 0.2.81).
|
||||
self.assertIn('address: 0x18', TEXT)
|
||||
for pin, number in (('reset_pin', 0), ('interrupt_pin', 1)):
|
||||
self.assertIn(f' {pin}:\n pca9554: touch_expander\n number: {number}', TEXT)
|
||||
# The V3.0's PCA9557 brings the GT911 out of reset before the driver runs (firmware 0.2.82).
|
||||
self.assertIn(' elecrow_touch_reset:\n i2c_id: touch_bus\n address: 0x18', TEXT)
|
||||
code = '\n'.join(line for line in TEXT.split('\n') if not line.lstrip().startswith('#'))
|
||||
self.assertNotIn('reset_pin', code)
|
||||
self.assertNotIn('interrupt_pin', code)
|
||||
header = (ROOT / 'components/smart_display/elecrow_touch_reset.h').read_text()
|
||||
for step in ('write(0x03, 0x00)', 'write(0x01, 0x00)', 'delay(20)', 'write(0x01, 0x01)', 'delay(100)', 'write(0x03, 0x02)'):
|
||||
self.assertIn(step, header)
|
||||
self.assertIn('return 700.0f', header)
|
||||
self.assertIn('assertion_level: SILENT', TEXT)
|
||||
|
||||
def test_the_flash_fits_by_three_measures(self):
|
||||
|
||||
Reference in New Issue
Block a user