# esp_lcd_touch_gsl3680
(English | [中文](README_zh.md) | [日本語](README_ja.md))
Silead GSL3680 capacitive touch driver for ESP-IDF, implementing the
[`esp_lcd_touch`](https://components.espressif.com/components/espressif/esp_lcd_touch)
interface.
## Install
```bash
idf.py add-dependency "mangoo1/esp_lcd_touch_gsl3680^1.0.0"
```
Or add it to your `main/idf_component.yml`:
```yaml
dependencies:
mangoo1/esp_lcd_touch_gsl3680: "^1.0.0"
```
## Usage
The controller sits on I2C at address `0x40`. Reset and interrupt are active low.
```c
#include "esp_lcd_gsl3680.h"
// 1. Touch shares an existing I2C master bus
esp_lcd_panel_io_i2c_config_t io_cfg = ESP_LCD_TOUCH_IO_I2C_GSL3680_CONFIG();
io_cfg.scl_speed_hz = 400 * 1000;
esp_lcd_panel_io_handle_t io = NULL;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &io_cfg, &io));
// 2. Match x_max/y_max to your panel's native resolution
esp_lcd_touch_config_t tp_cfg = {
.x_max = 800,
.y_max = 1280,
.rst_gpio_num = GPIO_NUM_22,
.int_gpio_num = GPIO_NUM_21,
.levels = {
.reset = 0, // active low
.interrupt = 0, // active low
},
.flags = {
.swap_xy = 0,
.mirror_x = 0,
.mirror_y = 1,
},
};
esp_lcd_touch_handle_t tp = NULL;
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gsl3680(io, &tp_cfg, &tp));
```
### Reading coordinates
```c
uint16_t x[1], y[1], strength[1];
uint8_t count = 0;
esp_lcd_touch_read_data(tp);
if (esp_lcd_touch_get_coordinates(tp, x, y, strength, &count, 1)) {
printf("touch at %d,%d\n", x[0], y[0]);
}
```
### With LVGL
```c
#include <esp_lvgl_port.h>
const lvgl_port_touch_cfg_t touch_cfg = {
.disp = lv_display_get_default(),
.handle = tp,
};
lvgl_port_add_touch(&touch_cfg);
```
### Orientation
`swap_xy` / `mirror_x` / `mirror_y` must match how your display panel is
oriented, otherwise touch coordinates will not line up with what is drawn.
They can also be changed at runtime:
```c
esp_lcd_touch_set_mirror_y(tp, true);
```
### Optional touch
Probe the address first if the panel may be absent, so a board without a
touch panel still boots:
```c
if (i2c_master_probe(i2c_bus, ESP_LCD_TOUCH_IO_I2C_GSL3680_ADDRESS, 100) != ESP_OK) {
ESP_LOGW(TAG, "no touch controller, continuing without it");
return;
}
```
## Startup timing
The driver uploads firmware to the controller on init. This takes roughly
**800ms** — budget for it in your boot sequence, and do not call it from a
context with a short watchdog.
## Known issue
After the firmware upload the driver logs:
```
gsl3680 startup_chip failed read 0xb0 = 5a,5a,5a,5a
```
then reports success and continues. `5a5a5a5a` is a placeholder pattern, so the
chip is not returning a real startup status. The upload itself succeeds and the
controller responds on I2C, but this path has not been traced to a root cause.
## Fixes over the vendor source
Two integer-type bugs in the gesture path:
**`chazhi` was `uint16_t`.** It holds `distance - pre_distance`, a signed
difference, so the `chazhi < -900` zoom-out branch was unreachable and pinch-out
gestures never fired. Now `int32_t`.
**`distance` was `uint16_t`.** It holds a squared pixel distance,
`(x1-x2)² + (y1-y2)²`, which reaches 2278400 on an 800×1280 panel and
overflowed. `pre_distance` was already `uint32_t`, so the two were inconsistent.
Both are `uint32_t` now.
## Tested on
Guition JC8012P4A1C — ESP32-P4, 10.1" 800×1280 JD9365 panel, ESP-IDF v6.0.2.
Firmware upload and controller initialization are confirmed. Coordinate
reporting has not been systematically verified.
## License
**GPL-2.0-or-later.**
`gsl_point_id.c` is Silead's touch tracking algorithm, carried over from the
Linux kernel driver at `drivers/input/touchscreen/mediatek/gslX680/`
(© 2010–2016 Silead Inc.). It links into the same library, so the component as
a whole is GPL-2.0-or-later.
**If your project is MIT or Apache licensed**, do not vendor these sources into
your tree — that would place your whole codebase under GPL. Depend on this
component instead, which keeps the license boundary intact.
`esp_lcd_gsl3680.c` and the headers came from the Guition JC8012P4A1C vendor SDK
carrying no license headers of their own; they are distributed here under the
same terms.
idf.py add-dependency "mangoo1/esp_lcd_touch_gsl3680^1.0.0"