Gt911 Register Map //top\\ <360p 2024>
Diving Deep into the GT911 Register Map: A Touch Controller Developer’s Guide If you’ve worked with capacitive touch screens on Raspberry Pi, ESP32, or STM32 projects, you’ve likely encountered the GT911 . This popular touch controller from Goodix is everywhere—from cheap 7-inch LCD displays to industrial HMI panels. While the driver code is often copy-pasted from GitHub, understanding the register map is what separates "it works" from "I can debug and optimize it." Let’s pull back the curtain and map out the GT911’s internal memory. The Basics: I2C and Addressing The GT911 communicates over I2C. Two common addresses exist:
0x5D (default, with INT pin pulled high during reset) 0x14 (alternative)
The device uses 16-bit register addresses . This means any I2C transaction requires sending a 2-byte address (high byte first) before reading or writing data. The GT911 Register Map (Key Sections) Below is the essential register map broken into functional groups. All addresses are in hex. 1. Product Information (Read-Only) | Register | Description | Example Value | |----------|-------------|----------------| | 0x8140 | Product ID (first byte: '9') | 0x39 | | 0x8141 | Product ID (second byte: '1') | 0x31 | | 0x8142 | Product ID (third byte: '1') | 0x31 | | 0x8143 | Firmware version (major) | Varies | | 0x8144 | Firmware version (minor) | Varies | | 0x814E | Config version | 0x01 | Pro tip: Read 0x8140 to 0x8144 to verify I2C communication. A returned "911" confirms you're talking to the right chip. 2. Config Registers (Write-Only during init) | Start Addr | Size | Description | |------------|------|-------------| | 0x8040 | 1 | Config checksum | | 0x8041 | 1 | Config version number | | 0x8042 | 184 | Main configuration block (touch thresholds, XY mapping, etc.) | The GT911 loads its working configuration from internal flash at boot. You can override it by writing to 0x8040 – 0x80FF then sending the "update config" command. 3. Gesture & Status Registers | Register | R/W | Description | |-----------|-----|-------------| | 0x8100 | R | Gesture ID (0 = no gesture, 0x01 = move up, 0x02 = move down, etc.) | | 0x8101 | R | Number of touch points (0–5) | | 0x8102 | R | Large touch indicator / proximity | | 0x8103 | R | Reserved | Pro tip: Poll 0x8101 first. If it returns >0, then read the touch data. 4. Touch Point Data (5 Points, 8 bytes each) Each touch point occupies 8 consecutive bytes. Point 1 starts at 0x8150 . | Offset | Description | |--------|-------------| | +0 | Track ID (changes on each new touch) | | +1 | X coordinate (low byte) | | +2 | X coordinate (high byte) | | +3 | Y coordinate (low byte) | | +4 | Y coordinate (high byte) | | +5 | Touch size (pressure/area) | | +6 | Reserved | | +7 | Reserved | Address mapping for each point:
Point 1: 0x8150 – 0x8157 Point 2: 0x8158 – 0x815F Point 3: 0x8160 – 0x8167 Point 4: 0x8168 – 0x816F Point 5: 0x8170 – 0x8177 gt911 register map
5. Checksum & Configuration Control | Register | Description | |----------|-------------| | 0x80FE | Config checksum (calculated by host) | | 0x80FF | Config update flag (write 0x01 to reload config from host) | After writing a new configuration block to 0x8040 – 0x80FD , you must:
Calculate an 8-bit checksum (sum of all bytes from 0x8040 to 0x80FD , then take lower byte) Write that checksum to 0x80FE Write 0x01 to 0x80FF
The GT911 will then reset its touch engine with the new settings. Practical Example: Reading a Single Touch Let’s walk through a minimal read sequence on an ESP32 or Arduino: // Read number of touch points uint8_t touch_count = 0; i2c_read(0x5D, 0x8101, &touch_count, 1); if(touch_count > 0) { uint8_t touch_data[8]; // Read point 1 data i2c_read(0x5D, 0x8150, touch_data, 8); uint16_t x = ((uint16_t)touch_data[2] << 8) | touch_data[1]; uint16_t y = ((uint16_t)touch_data[4] << 8) | touch_data[3]; uint8_t track_id = touch_data[0]; uint8_t size = touch_data[5]; Diving Deep into the GT911 Register Map: A
printf("Touch %d: X=%d Y=%d Size=%d\n", track_id, x, y, size);
}
Common Pitfalls (and How to Fix Them) 1. Stale touch data The GT911 does not clear touch registers automatically. Always re-read 0x8101 after processing to see when a finger lifts (value returns to 0). 2. Checksum mismatches If you update the config but forget the checksum, the GT911 ignores your changes. Verify by reading back 0x814E (config version) after update. 3. I2C clock stretching The GT911 sometimes stretches the clock during touch scanning. Ensure your I2C driver supports clock stretching, or add small delays between reads. 4. Interrupt management Most designs connect the GT911’s INT pin to a GPIO. After reading touch data, write 0x00 to register 0x814E to clear the interrupt; otherwise, you won't get new interrupts. Where to Get the Full Register Map Goodix does not publicly release complete datasheets. However, the community has reverse-engineered nearly everything. For a full reference: The Basics: I2C and Addressing The GT911 communicates
Look for GT911 Datasheet (unofficial PDFs exist) Check Linux kernel driver: drivers/input/touchscreen/gt911.c Browse GitHub repositories by goodix_gt9xx – many contain commented register maps
Final Thoughts The GT911 is a workhorse, but its register map is surprisingly straightforward once you know where to look. You don’t need a full driver library—just 8-10 register addresses and proper I2C handling. Next time your touch screen acts up, skip the high-level driver and probe 0x8100 through 0x8177 . You’ll see exactly what the controller sees. Have you struggled with GT911 configuration or interrupt handling? Let me know in the comments below.