Files
arcs/arcs-sdk/drivers/lisa_touch
2026-08-13 16:50:52 +08:00
..

Touch 驱动

基于 lisa_device 框架的 Touch 设备驱动,为 ARCS 平台提供统一的触摸屏接口。

功能特性

  • 多芯片支持: 支持 CST328、AXS15231B、FT5336、CST816D、ST77921、BL6133 等触摸芯片
  • 总线接口: I2C 接口通信,自动配置 I2C 总线参数
  • 工作模式: 支持轮询模式和中断模式
  • 中断优化: 中断模式下使用驱动内部任务处理 I2C 读取,回调在任务上下文中安全执行
  • 线程安全: 内部使用互斥锁保护并发访问,自动判断线程和中断上下文
  • 灵活配置: 通过 Kconfig 选择启用的芯片,节省资源

配置选项

prj.conf 中启用驱动并选择芯片:

CONFIG_LISA_TOUCH_DEVICE=y
CONFIG_LISA_TOUCH_ARCS_CST328=y       # 启用 CST328 芯片
# CONFIG_LISA_TOUCH_ARCS_AXS15231B=y  # 启用 AXS15231B 芯片
# CONFIG_LISA_TOUCH_ARCS_FT5336=y     # 启用 FT5336 芯片
# CONFIG_LISA_TOUCH_ARCS_CST816D=y    # 启用 CST816D 芯片
# CONFIG_LISA_TOUCH_ARCS_ST77921=y    # 启用 ST77921 芯片
# CONFIG_LISA_TOUCH_ARCS_BL6133=y     # 启用 BL6133 芯片

CONFIG_LISA_I2C=y                     # 依赖 I2C 驱动
CONFIG_LISA_GPIO_DEVICE=y             # 依赖 GPIO 驱动

根据需要选择启用一个或多个触摸芯片。每个芯片注册为独立设备,可同时使用。

支持的芯片

芯片型号 设备名称 I2C地址 分辨率 状态
CST328 touch_cst328 0x1D 240x320 已验证
AXS15231B touch_axs15231b 0x3B 390x390 ⚠️ 待验证
FT5336 touch_ft5336 0x38 480x272 ⚠️ 待验证
CST816D touch_cst816d 0x15 240x240 ⚠️ 待验证
ST77921 touch_st77921 0x55 480x480 ⚠️ 待验证
BL6133 touch_bl6133 0x2C 320x386 ⚠️ 待验证

API 接口

总线配置

int lisa_touch_attach_bus(lisa_device_t *dev, const lisa_touch_bus_config_t *bus_config);

配置触摸设备的总线接口I2C。I2C 总线将自动配置为标准速度100kHz

触摸控制

int lisa_touch_enable(lisa_device_t *dev);
int lisa_touch_disable(lisa_device_t *dev);
int lisa_touch_get_capabilities(lisa_device_t *dev, lisa_touch_capabilities_t *caps);

启用/禁用触摸设备,获取设备能力信息(分辨率、最大触摸点数等)。

事件读取

int lisa_touch_read_event(lisa_device_t *dev, lisa_touch_event_t *event);

读取触摸事件(按下、释放、坐标等)。

事件类型说明:

  • LISA_TOUCH_EVENT_NONE: 无事件
  • LISA_TOUCH_EVENT_PRESS: 按下事件(检测到触摸时返回,包含坐标信息)
  • LISA_TOUCH_EVENT_RELEASE: 释放事件(检测到释放时返回)

行为说明:

  • 检测到触摸时返回 PRESS 事件,包含当前坐标
  • 检测到释放时返回 RELEASE 事件
  • 轮询模式下,每次读取时如果触摸状态为按下,都会返回 PRESS 事件(坐标可能更新)

返回值:

  • LISA_DEVICE_OK (0): 成功读取事件
  • LISA_DEVICE_ERR_INVALID: 参数无效
  • LISA_DEVICE_ERR_NOT_READY: 设备未启用或 I2C 未就绪
  • LISA_DEVICE_ERR_NOT_SUPPORT: 当前处于中断模式,不支持轮询读取
  • LISA_DEVICE_ERR_IO: 读取失败(无有效触摸数据)

重要提示:

  • ⚠️ 中断模式下禁止调用此函数:如果已通过 lisa_touch_set_int_mode(INTERRUPT) 设置为中断模式,再调用 lisa_touch_read_event() 将返回 LISA_DEVICE_ERR_NOT_SUPPORT
  • 这是为了避免轮询读取与中断任务产生资源竞争,导致状态混乱
  • 中断模式下请使用回调函数接收触摸事件

中断模式

int lisa_touch_set_callback(lisa_device_t *dev, lisa_touch_callback_t callback, void *user_data);
int lisa_touch_set_int_mode(lisa_device_t *dev, lisa_touch_int_mode_t mode);

设置触摸中断回调函数和中断模式(中断模式/轮询模式)。

使用方法

基本步骤

  1. 配置引脚: 将对应的 GPIO 引脚配置为 I2C 和 GPIO 功能
  2. 获取设备: 通过 lisa_device_get() 获取触摸设备、I2C 设备和 GPIO 设备
  3. 配置总线: 调用 lisa_touch_attach_bus() 配置 I2C 总线
  4. 设置模式: 调用 lisa_touch_set_int_mode() 设置工作模式(轮询/中断)
  5. 启用设备: 调用 lisa_touch_enable() 启用设备
  6. 读取事件: 调用 lisa_touch_read_event() 读取触摸事件(轮询模式)或设置回调(中断模式)

轮询模式

#include "lisa_touch.h"
#include "lisa_gpio.h"
#include "IOMuxManager.h"
#include "board.h"
#include "pinmux.h"

// 1. 配置 I2C 和 GPIO 引脚(通过 pinmux 重定向或直接配置)
#ifdef CONFIG_BOARD_ARCS_EVB
void lisa_i2c0_pinmux()
{
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 22, 8);  // SDA
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 23, 8);  // SCL
}

void lisa_gpioa_pinmux()
{
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 25, 0);  // RST
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 24, 0);  // INT
}
#endif

// 2. 获取设备
lisa_device_t *touch = lisa_device_get("touch_cst328");
lisa_device_t *i2c_dev = lisa_device_get("i2c0");
lisa_device_t *gpio_dev = lisa_device_get("gpioa");

if (!touch || !i2c_dev || !gpio_dev) {
    return -1;
}

// 3. 配置总线
lisa_touch_bus_config_t bus_config = {
    .bus_type = LISA_TOUCH_BUS_I2C,
    .config = {
        .i2c = {
            .i2c_dev = i2c_dev,
            .int_gpio = gpio_dev,
            .int_pin = 24,
            .rst_gpio = gpio_dev,
            .rst_pin = 25,
        }
    }
};
lisa_touch_attach_bus(touch, &bus_config);

// 4. 设置轮询模式(可选,默认就是轮询模式)
lisa_touch_set_int_mode(touch, LISA_TOUCH_INT_MODE_POLLING);

// 5. 启用设备
lisa_touch_enable(touch);

// 6. 获取设备能力
lisa_touch_capabilities_t caps;
lisa_touch_get_capabilities(touch, &caps);
printf("Touch: max_x=%d, max_y=%d, max_points=%d\n",
       caps.max_x, caps.max_y, caps.max_points);

// 7. 循环读取触摸事件
while (1) {
    lisa_touch_event_t event;
    int ret = lisa_touch_read_event(touch, &event);
    
    if (ret == LISA_DEVICE_OK) {
        switch (event.type) {
            case LISA_TOUCH_EVENT_PRESS:
                // 按下事件
                if (event.point_count > 0) {
                    printf("Touch: x=%4d, y=%4d, type=PRESS\n",
                           event.points[0].x, event.points[0].y);
                }
                break;
            case LISA_TOUCH_EVENT_RELEASE:
                printf("Touch: RELEASE\n");
                break;
        }
    }
    
    vTaskDelay(pdMS_TO_TICKS(50));  // 50ms 采样间隔
}

中断模式

// 触摸事件回调函数(在任务上下文中调用,由驱动内部任务触发)
void touch_event_callback(const lisa_touch_event_t *event, void *user_data)
{
    (void)user_data;
    
    // 此回调在驱动内部的任务上下文中调用,可以安全使用 printf
    switch (event->type) {
        case LISA_TOUCH_EVENT_PRESS:
            // 按下事件
            if (event->point_count > 0) {
                printf("Touch: x=%4d, y=%4d, type=PRESS\n",
                       event->points[0].x, event->points[0].y);
            }
            break;
        case LISA_TOUCH_EVENT_RELEASE:
            // 释放事件
            printf("Touch: type=RELEASE\n");
            break;
    }
}

int main(void)
{
    // ... 配置引脚和总线(同上)...
    
    // 设置触摸事件回调函数
    lisa_touch_set_callback(touch, touch_event_callback, NULL);
    
    // 设置中断模式
    lisa_touch_set_int_mode(touch, LISA_TOUCH_INT_MODE_INTERRUPT);
    
    // 启用设备
    lisa_touch_enable(touch);

    // 主循环:触摸事件通过回调自动处理
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000));
        printf("System running, waiting for touch events...\n");
    }
}

中断模式说明:

  • 驱动内部创建专用任务处理 I2C 读取
  • GPIO 中断回调只发送任务通知,不执行耗时操作
  • 用户回调在任务上下文中调用,可以安全使用 printfmalloc 等操作
  • 回调直接收到完整的触摸数据(包括坐标),无需再次读取
  • ⚠️ 中断模式下不能调用 lisa_touch_read_event(),会返回 LISA_DEVICE_ERR_NOT_SUPPORT 错误

模式切换

轮询模式和中断模式可以动态切换,但同一时间只能使用一种模式:

// 从轮询模式切换到中断模式
lisa_touch_set_callback(touch, touch_event_callback, NULL);  // 先设置回调
lisa_touch_set_int_mode(touch, LISA_TOUCH_INT_MODE_INTERRUPT);  // 切换到中断模式
// 此后不能再调用 lisa_touch_read_event()

// 从中断模式切换回轮询模式
lisa_touch_set_int_mode(touch, LISA_TOUCH_INT_MODE_POLLING);  // 切换到轮询模式
// 此后可以调用 lisa_touch_read_event(),回调不再触发

重要提示:

  • 中断模式下禁止调用 lisa_touch_read_event(),避免资源竞争
  • 轮询模式下回调函数不会被调用(即使已设置)
  • 切换模式前无需禁用设备,可以动态切换

硬件配置

引脚复用配置

Touch 驱动依赖 I2C 和 GPIO 驱动,引脚复用配置由 I2C 和 GPIO 驱动在初始化时自动完成。

配置位置:

  • I2C 引脚: boards/<板型名>/pinmux.c 中的 lisa_i2c0_pinmux()lisa_i2c1_pinmux() 函数
  • GPIO 引脚: boards/<板型名>/pinmux.c 中的 lisa_gpioa_pinmux()lisa_gpiob_pinmux() 函数
  • 调用时机: I2C 和 GPIO 设备初始化时自动调用

示例 (参考 boards/arcs_evb/pinmux.c):

void lisa_i2c0_pinmux()
{
    /* I2C0: PA22=SDA, PA23=SCL, 功能码 8 */
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 22, 8);
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 23, 8);
}

void lisa_gpioa_pinmux()
{
    /* GPIO: PA25=RST, PA24=INT, 功能码 0 */
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 25, 0);
    IOMuxManager_PinConfigure(CSK_IOMUX_PAD_A, 24, 0);
}

注意:

  • 该函数由板型相关代码实现,不同板型的引脚配置可能不同
  • 如需自定义引脚配置,可在 sample 中重写 pinmux 函数(参考 samples/drivers/devices/lisa_touch/interrupt_mode/src/main.c
  • 触摸驱动需要以下引脚:
    • I2C SDA/SCL用于 I2C 通信
    • INT触摸中断引脚中断模式需要
    • RST芯片复位引脚

芯片特性

不同芯片的 I2C 地址、分辨率、触发方式可能不同,请参考具体芯片手册和"支持的芯片"表格。

工作模式对比

特性 轮询模式 中断模式
响应速度 取决于轮询间隔(通常 50ms 立即响应(< 1ms
CPU 占用 高(持续轮询) 低(事件驱动)
功耗
实现复杂度 简单 中等
适用场景 简单应用、对响应时间不敏感 需要快速响应、低功耗应用
回调上下文 任务上下文(安全) 任务上下文(安全)

注意事项

  1. I2C 自动配置: lisa_touch_attach_bus() 会自动配置 I2C 总线为标准速度100kHz无需手动调用 lisa_i2c_configure()

  2. 引脚配置: 使用前需配置对应的 GPIO 引脚,驱动初始化时会自动调用 pinmux 函数,或通过 pinmux 重定向自定义引脚

  3. 设备依赖: 需要确保 I2C 和 GPIO 设备已就绪(通过 lisa_device_ready() 检查)

  4. 中断回调: 中断模式下,用户回调在驱动内部任务上下文中调用,可以安全使用 printfmalloc 等操作

  5. 线程安全: 驱动内部已实现线程保护,可在多线程环境中使用

  6. 芯片特性: 不同芯片的坐标系、分辨率、触发方式可能不同,请参考具体芯片手册

  7. 设备选择: 使用前需在 prj.conf 中启用对应的触摸芯片和依赖驱动I2C、GPIO

  8. 多芯片使用: 每个芯片注册为独立设备,可同时使用多个触摸芯片

文件说明

  • lisa_touch.h - 驱动头文件,包含所有 API 和类型定义
  • lisa_touch_cst328.c - CST328 芯片驱动实现
  • lisa_touch_axs15231b.c - AXS15231B 芯片驱动实现
  • lisa_touch_ft5336.c - FT5336 芯片驱动实现
  • lisa_touch_cst816d.c - CST816D 芯片驱动实现
  • lisa_touch_st77921.c - ST77921 芯片驱动实现
  • lisa_touch_bl6133.c - BL6133 芯片驱动实现
  • Kconfig - 主配置选项
  • Kconfig.arcs.* - 各芯片配置选项
  • CMakeLists.txt - 构建配置
  • README.md - 驱动使用说明