Skip to content
Display Engineer
Troubleshooting

GT911 Touch Not Working? I2C Address, Reset Timing, Config and Coordinate Fixes

A step-by-step checklist for a GT911 capacitive touch controller that isn't detected, gives no touches or reports the wrong coordinates: power and I2C scan, the INT/RST address-select sequence, the 0x814E status register, interrupt edge, resolution and axis fixes for Linux, ESP-IDF and ESPHome.

DEDisplay Engineer Applications Team · Display application engineersUpdated Oct 19, 2026

Start here: match the symptom

Symptom

Most likely cause

Go to

Nothing at 0x5D or 0x14 on an I2C scan

No power to the controller, missing pull-ups, or the chip is held in reset

Step 1

Found at 0x14 when the driver expects 0x5D (or the other way round), or the address changes between boots

INT pin level during reset

Step 2

Detected, product ID reads correctly, but no touches arrive

Status register not cleared, interrupt edge wrong, or INT not wired

Step 3

Touches arrive but land in the wrong place, mirrored or rotated

Resolution in the GT911 config doesn't match the panel, or axes need swapping

Step 4

Tempted to write a new config block

Read this first

Step 5

Work through the steps in order. The register addresses and timings below come from the Linux goodix driver, Espressif's esp_lcd_touch_gt911 component and the ESPHome documentation; links are in the Sources section.

1. Confirm the GT911 is powered and answering on I2C

Power and pull-ups

The Linux device-tree binding for Goodix controllers names two supplies: AVDD28 (analog) and VDDIO (the logic I/O rail). On a module or FPC both are usually fed from the host connector, so measure them at the connector before suspecting firmware. SDA and SCL also need pull-up resistors somewhere on the bus; many display modules don't include them.

Scan the bus

Run an I2C scanner sketch or i2cdetect. A GT911 answers at one of two 7-bit addresses:

7-bit address

8-bit write / read bytes (as some datasheets list them)

0x5D

0xBA / 0xBB

0x14

0x28 / 0x29

The 8-bit pairs come from a comment in the Linux driver's reset code. If a vendor sheet says "address 0xBA", it is the same device as 7-bit 0x5D; enter 0x5D in Arduino, ESP-IDF and Linux.

Read the product ID

Registers on the GT911 are 16-bit addresses. The Linux driver reads 6 bytes from 0x8140: the first 4 bytes are the product ID as ASCII text and the last 2 are the firmware version (little-endian). A GT911 reports the string 911. If you get 911, the bus, power and address are all fine and the problem is further down this list.

If nothing answers at either address, check that the reset line isn't being held low. On many modules RST is an input to the GT911 and has to be driven high by the host (or pulled up on the board) before the controller runs.

2. Get the reset and address-select sequence right

The GT911 picks its I2C address from the level on its INT pin at the moment reset is released. In the words of the Linux binding, the INT line "is sampled by the device on reset deassertion to select the I2C client address".

INT level when RST goes high

I2C address

Low

0x5D

High

0x14

The sequence the Linux driver uses

  1. Drive RST low and wait more than 10 ms (the driver waits 20 ms).
  2. Drive INT to the level for the address you want: high for 0x14, low for 0x5D.
  3. Wait more than 100 µs.
  4. Drive RST high and wait more than 5 ms (the driver waits 6–10 ms).
  5. Drive INT low for 50 ms, then switch INT to an input.

If INT floats during step 4, the address can differ from one power-up to the next. That is the classic "works after flashing, fails after a cold boot" report.

ESP-IDF: esp_lcd_touch_gt911

Espressif's component defines ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS as 0x5D and ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP as 0x14. It only runs the address-select sequence when all three of these are set:

  • rst_gpio_num is a real GPIO (not GPIO_NUM_NC),
  • int_gpio_num is a real GPIO,
  • driver_data points to an esp_lcd_touch_io_gt911_config_t whose dev_addr is the address you want.

Otherwise it logs I2C address initialization procedure skipped - using default GT9xx setup and does a plain reset. In that case the address is whatever the board's wiring gives, and the I2C panel-IO address you pass must match the scan result. The component's default I2C clock in ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG() is 100 kHz.

Boards where the host doesn't control INT

If INT isn't connected to the host, the host can't choose the address, so scan both addresses and use the one that answers. On the Sunton ESP32-8048S043C, for example, the GT911 interrupt isn't wired to a GPIO by default (see our board page). ESPHome's GT911 page notes that when INT goes through an IO expander, the pin is still used to set the address at boot, but touch is polled instead of interrupt-driven.

3. Detected, but no touch events

Read and clear the status register

Touch data starts at 0x814E. The first byte is a status byte:

  • Bit 7 (0x80): buffer ready. New data is valid only when this is set.
  • Bits 0–3: number of touch points. The Linux driver rejects counts above the configured maximum.
  • Bit 4: a key (button) is pressed.

Each touch point that follows is 8 bytes: a track ID, then X, Y and size as little-endian 16-bit values.

After reading, both the Linux driver and esp_lcd_touch_gt911 write 0 to 0x814E. If you write your own driver, do the same; skipping that write is a common reason a hand-written driver sees only the first touch.

Match the interrupt edge

The trigger type is in the GT911's own configuration: bits 0–1 of the config byte at 0x804D (offset 6 from the config start at 0x8047). The Linux driver maps it like this:

Value

Interrupt type

0

Rising edge

1

Falling edge

2

Low level

3

High level

Set your GPIO interrupt to match. In esp_lcd_touch_gt911, levels.interrupt = 1 selects a rising-edge interrupt and 0 a falling edge.

No INT line? Poll

Polling works fine for HMI use. ESPHome polls every 50 ms by default (update_interval) when no interrupt_pin is set. The Linux driver, when it does have an interrupt, waits up to 20 ms for the ready bit before giving up on a frame.

4. Touch lands in the wrong place

Check the resolution stored in the GT911

The GT911 reports coordinates in the resolution written in its configuration, not in your display's resolution. Per the Linux driver, X maximum is the little-endian 16-bit value at 0x8048 and Y maximum at 0x804A. Read them. If the controller is configured for 1024×600 and your panel is 800×480, touches land to the right of and below your finger and the far edges fall off-screen. The fix is to scale (or set the driver's limits to the controller's values).

Where each stack takes the limits from:

Stack

Resolution source

Swap and mirror

Linux goodix

Read from the GT911 config; falls back to 4095 × 4095 when the config has none

Device-tree touchscreen-swapped-x-y, touchscreen-inverted-x, touchscreen-inverted-y, touchscreen-size-x/y

ESP-IDF esp_lcd_touch_gt911

Your x_max / y_max in esp_lcd_touch_config_t (the driver doesn't read the chip's resolution)

flags.swap_xy, flags.mirror_x, flags.mirror_y

ESPHome gt911

Touchscreen calibration (x_min, x_max, y_min, y_max)

transform: swap_xy / mirror_x / mirror_y

Calibrate from raw values

ESPHome's touchscreen page suggests logging touch.x_raw and touch.y_raw in an on_touch lambda, touching the corners at the edge pixels a few times, and entering the minimum and maximum raw values as the calibration. The same method works on any platform: print raw X and Y, touch the four corners, and map the range onto the screen.

Fix orientation in this order: first get X and Y on the right axes (swap_xy), then flip whichever axis runs backwards (mirror_x / mirror_y). The display's logical (0, 0) must be top-left.

5. Rewriting the GT911 config: last resort

The configuration block starts at 0x8047. For the GT911 the Linux driver treats it as 186 bytes:

  • Byte 0 (0x8047): config version.
  • Bytes 1–4: X and Y resolution (see step 4).
  • Byte 5 (0x804C): maximum touch points, low 4 bits.
  • Byte 6 (0x804D): interrupt trigger type, low 2 bits.
  • Byte 184 (0x80FF): checksum, the 8-bit two's complement of the sum of bytes 0–183.
  • Byte 185 (0x8100): config_fresh, which must be 1.

The Linux driver itself only writes a config when it has both the INT and RST GPIOs and finds a firmware file (default name goodix_911_cfg.bin, or the name in a goodix,config-name property). Without that file, it uses the config already stored in the chip.

Before you write anything, read all 186 bytes and save them. Fix resolution and orientation in software where you can. A config block made for a different touch panel can stop touch working on yours, so get the file from the panel's supplier if you really need to change it.

Choosing a capacitive-touch module

If you're picking a CTP display for a new design, ask the supplier three things before you order samples: which touch controller it uses, which I2C address it ships at, and whether INT and RST reach the connector. Send your size, interface and host processor through Ask an Engineer, and we'll include those three answers with the modules we suggest.

Frequently asked questions

What is the I2C address of the GT911?

Either 0x5D or 0x14 (7-bit). The controller samples its INT pin when reset is released: INT low selects 0x5D, INT high selects 0x14. Datasheets that list 0xBA/0xBB or 0x28/0x29 are giving the same addresses as 8-bit write/read bytes.

Why does my GT911 change address after a reboot?

INT is floating or driven by something else when reset is released, so the controller samples a different level each time. Drive INT low (for 0x5D) or high (for 0x14) before releasing RST, wait more than 5 ms, hold INT low for 50 ms, then make it an input. If the host can't control INT, scan both addresses.

Why do I only get one touch from the GT911?

After reading the touch data at 0x814E, write 0 to 0x814E. The Linux goodix driver and Espressif's esp_lcd_touch_gt911 both do this after every read; a driver that skips it typically stops seeing new touches.

Why are GT911 touch coordinates scaled or offset?

The GT911 reports in the resolution stored in its own config (X at 0x8048, Y at 0x804A). If that differs from your panel, scale the values or set your driver's x_max/y_max to the controller's resolution, then use swap_xy and mirror_x/mirror_y for orientation.

Does the GT911 work without the INT pin?

Yes. Poll the 0x814E status register instead of using an interrupt. ESPHome polls every 50 ms by default when no interrupt_pin is set. Without INT the host also can't choose the address, so use whichever of 0x5D or 0x14 answers.

Should I rewrite the GT911 configuration?

Only as a last resort. Read and save the existing 186-byte block from 0x8047 first, prefer fixing resolution and orientation in software, and use the touch panel supplier's config file if you must write one. The block ends with an 8-bit checksum at 0x80FF and a config_fresh byte at 0x8100 that must be 1.

Sources

  1. Linux kernel: drivers/input/touchscreen/goodix.c
  2. Linux kernel: drivers/input/touchscreen/goodix.h (register addresses)
  3. Linux kernel: Goodix touchscreen device-tree binding (goodix.yaml)
  4. Espressif ESP-BSP: esp_lcd_touch_gt911 driver source
  5. Espressif ESP-BSP: esp_lcd_touch_gt911 header (I2C addresses)
  6. ESPHome: GT911 touchscreen
  7. ESPHome: Touchscreen components (transform, calibration)

Not sure which display fits your design?

Send us your size, interface and host processor. A display engineer replies within 12 hours with 2–3 options, datasheets and init code. Samples from 1 pc.