mangoo1/esp_lcd_touch_gsl3680

1.0.0

Latest
uploaded 2 days ago
Silead GSL3680 capacitive touch controller driver for esp_lcd_touch

Readme (zh)

# esp_lcd_touch_gsl3680

([English](README.md) | 中文 | [日本語](README_ja.md))

Silead GSL3680 电容触摸驱动,实现 ESP-IDF 的
[`esp_lcd_touch`](https://components.espressif.com/components/espressif/esp_lcd_touch)
接口。

## 安装

```bash
idf.py add-dependency "mangoo1/esp_lcd_touch_gsl3680^1.0.0"
```

或写进 `main/idf_component.yml`:

```yaml
dependencies:
  mangoo1/esp_lcd_touch_gsl3680: "^1.0.0"
```

## 用法

芯片挂在 I2C 上,地址 `0x40`。复位和中断都是**低电平有效**。

```c
#include "esp_lcd_gsl3680.h"

// 1. 触摸复用已有的 I2C 主机总线
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. x_max/y_max 要填屏幕的原生分辨率
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,   // 低电平有效
        .interrupt = 0,   // 低电平有效
    },
    .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));
```

### 读坐标

```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("触摸位置 %d,%d\n", x[0], y[0]);
}
```

### 配合 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);
```

### 方向

`swap_xy` / `mirror_x` / `mirror_y` 必须跟你显示屏的方向设置一致,否则**触摸坐标会和画面对不上**。也可以运行时改:

```c
esp_lcd_touch_set_mirror_y(tp, true);
```

### 触摸可选

如果这块板子可能没装触摸屏,先探测地址,让没有触摸的板子也能正常启动:

```c
if (i2c_master_probe(i2c_bus, ESP_LCD_TOUCH_IO_I2C_GSL3680_ADDRESS, 100) != ESP_OK) {
    ESP_LOGW(TAG, "未检测到触摸控制器,跳过");
    return;
}
```

## 启动耗时

初始化时驱动会向芯片上传固件,**约 800ms**。安排启动流程时要预留这段时间,也不要在看门狗超时很短的上下文里调用。

## 已知问题

固件上传完成后,驱动会打印:

```
gsl3680 startup_chip failed read 0xb0 = 5a,5a,5a,5a
```

然后照常报告成功并继续。`5a5a5a5a` 是占位模式,说明芯片没有返回真实的启动状态。固件上传本身是成功的,芯片也能在 I2C 上响应,但这条路径**尚未定位到根因**。

## 相对厂商源码的修复

手势判断路径上的两个整数类型 bug:

**`chazhi` 原本是 `uint16_t`。** 它存的是 `distance - pre_distance`,一个**有符号**差值,所以 `chazhi < -900` 这个缩小分支永远进不去,**双指缩小手势从来不会触发**。现已改为 `int32_t`。

**`distance` 原本也是 `uint16_t`。** 它存的是距离的**平方** `(x1-x2)² + (y1-y2)²`,在 800×1280 屏上最大可达 2278400,**必然溢出**。而 `pre_distance` 本身却是 `uint32_t`,两者类型不一致。现在都是 `uint32_t`。

## 实测环境

晶彩 JC8012P4A1C —— ESP32-P4,10.1" 800×1280 JD9365 屏,ESP-IDF v6.0.2。

固件上传和控制器初始化已确认正常。**坐标上报未经系统性验证。**

## 许可证

**GPL-2.0-or-later。**

`gsl_point_id.c` 是 Silead 的触摸跟踪算法,源自 Linux 内核驱动
`drivers/input/touchscreen/mediatek/gslX680/`(© 2010–2016 Silead Inc.)。它和其余代码链接进同一个库,因此**整个组件都是 GPL-2.0-or-later**。

**如果你的项目是 MIT 或 Apache 许可**,不要把这些源码直接拷进你的代码树 —— 那会让你**整个项目被迫变成 GPL**。请以组件方式依赖它,这样许可证边界才是清晰的。

`esp_lcd_gsl3680.c` 和头文件来自晶彩 JC8012P4A1C 的厂商 SDK,原文件没有许可证声明,此处按相同条款分发。

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "mangoo1/esp_lcd_touch_gsl3680^1.0.0"

download archive

Stats

  • Archive size
    Archive size ~ 55.71 KB
  • Downloaded in total
    Downloaded in total 3 times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 3 times

Badge

mangoo1/esp_lcd_touch_gsl3680 version: 1.0.0
|