Просмотр исходного кода

update:更新extp触摸扩展库

江访 4 месяцев назад
Родитель
Сommit
9f7853328d
1 измененных файлов с 168 добавлено и 75 удалено
  1. 168 75
      script/libs/extp.lua

+ 168 - 75
script/libs/extp.lua

@@ -2,8 +2,8 @@
 --[[
 @module  extp
 @summary 触摸系统拓展库
-@version 1.0.5
-@date    2025.10.16
+@version 1.1.1
+@date    2025.11.20
 @author  江访
 @usage
 核心业务逻辑为:
@@ -34,13 +34,13 @@
    如果时间小于500ms判定为单击,按下至抬手的时间大于500ms判定为长按
 
 本文件的对外接口有5个:
-1、extp.init(args)                      -- 触摸设备初始化函数
-2、extp.setPublishEnabled(msg_type, enabled) -- 设置消息发布状态
-3、extp.getPublishEnabled(msg_type)          -- 获取消息发布状态
-4、extp.setSlideThreshold(threshold)         -- 设置滑动判定阈值
-5、extp.setLongPressThreshold(threshold)     -- 设置长按判定阈值
+1、extp.init(param)                      -- 触摸设备初始化函数
+2、extp.set_publish_enabled(msg_type, enabled) -- 设置消息发布状态
+3、extp.get_publish_enable(msg_type)          -- 获取消息发布状态
+4、extp.set_swipe_threshold(threshold)         -- 设置滑动判定阈值
+5、extp.set_long_press_threshold(threshold)     -- 设置长按判定阈值
 
-所有触摸事件均通过sys.publish("baseTouchEvent", event_type, ...)发布
+所有触摸事件均通过sys.publish("BASE_TOUCH_EVENT", event_type, ...)发布
 ]]
 
 local extp = {}
@@ -50,20 +50,20 @@ local state = "IDLE"             -- 当前状态:IDLE(空闲), DOWN(按下), M
 local touch_down_x = 0           -- 按下时的X坐标
 local touch_down_y = 0           -- 按下时的Y坐标
 local touch_down_time = 0        -- 按下时的时间戳
-local slide_threshold = 45       -- 滑动判定阈值(像素)
+local swipe_threshold = 45       -- 滑动判定阈值(像素)
 local long_press_threshold = 500 -- 长按判定阈值(毫秒)
-local slide_direction = nil      -- 滑动方向(用于MOVE状态)
+local swipe_direction = nil      -- 滑动方向(用于MOVE状态)
 
 -- 消息发布控制表,默认全部打开
 local publish_control = {
-    RAW_DATA = true,    -- 原始触摸数据
-    TOUCH_DOWN = true,  -- 按下事件
-    MOVE_X = true,      -- 水平移动
-    MOVE_Y = true,      -- 垂直移动
-    SWIPE_LEFT = true,  -- 向左滑动
-    SWIPE_RIGHT = true, -- 向右滑动
-    SWIPE_UP = true,    -- 向上滑动
-    SWIPE_DOWN = true,  -- 向下滑动
+    RAW_DATA = false,   -- 原始触摸数据
+    TOUCH_DOWN = false,  -- 按下事件
+    MOVE_X = false,     -- 水平移动
+    MOVE_Y = false,     -- 垂直移动
+    SWIPE_LEFT = false,  -- 向左滑动
+    SWIPE_RIGHT = false, -- 向右滑动
+    SWIPE_UP = false,    -- 向上滑动
+    SWIPE_DOWN = false,  -- 向下滑动
     SINGLE_TAP = true,  -- 单击
     LONG_PRESS = true   -- 长按
 }
@@ -72,19 +72,39 @@ local publish_control = {
 local tp_configs = {
     cst820 = { i2c_speed = i2c.FAST, tp_model = "cst820" },
     gt9157 = { i2c_speed = i2c.FAST, tp_model = "gt9157" },
+    cst9220 = { i2c_speed = i2c.SLOW, tp_model = "cst9220" },
     jd9261t = { i2c_speed = i2c.FAST, tp_model = "jd9261t" },
-    AirLCD_1001 = { i2c_speed = i2c.SLOW, tp_model = "gt911" },
-    Air780EHM_LCD_3 = { i2c_speed = i2c.SLOW, tp_model = "gt911" },
+    gt911 = { i2c_speed = i2c.SLOW, tp_model = "gt911" },
+    AirLCD_1010 = { i2c_speed = i2c.SLOW, tp_model = "gt911" },
     Air780EHM_LCD_4 = { i2c_speed = i2c.SLOW, tp_model = "gt911" },
     AirLCD_1020 = { i2c_speed = i2c.SLOW, tp_model = "gt911" }
 }
 
+-- 特殊型号的默认配置
+local special_tp_configs = {
+    Air780EHM_LCD_4 = {
+        i2c_id = 1,
+        pin_rst = 1,
+        pin_int = 22
+    },
+    AirLCD_1010 = {
+        i2c_id = 0,
+        pin_rst = 20,
+        pin_int = gpio.WAKEUP0
+    },
+    AirLCD_1020 = {
+        i2c_id = i2c.createSoft(0, 1),
+        pin_rst = 28,
+        pin_int = 7
+    }
+}
+
 -- 设置消息发布状态
--- @param msg_type 消息类型 ("RAW_DATA", "TOUCH_DOWN", "MOVE_X", "MOVE_Y", "SWIPE_LEFT", "SWIPE_RIGHT", "SWIPE_UP", "SWIPE_DOWN", "SINGLE_TAP", "LONG_PRESS", 或 "all")
+-- @param msg_type 消息类型 ("RAW_DATA", "TOUCH_DOWN", "MOVE_X", "MOVE_Y", "SWIPE_LEFT", "SWIPE_RIGHT", "SWIPE_UP", "SWIPE_DOWN", "SINGLE_TAP", "LONG_PRESS", 或 "ALL")
 -- @param enabled 是否启用 (true/false)
 -- @return boolean 操作是否成功
-function extp.setPublishEnabled(msg_type, enabled)
-    if msg_type == "all" then
+function extp.set_publish_enabled(msg_type, enabled)
+    if msg_type == "ALL" then
         for k, _ in pairs(publish_control) do
             publish_control[k] = enabled
         end
@@ -101,10 +121,10 @@ function extp.setPublishEnabled(msg_type, enabled)
 end
 
 -- 获取消息发布状态
--- @param msg_type 消息类型 ("all", "RAW_DATA", "TOUCH_DOWN", "MOVE_X", "MOVE_Y", "SWIPE_LEFT", "SWIPE_RIGHT", "SWIPE_UP", "SWIPE_DOWN", "SINGLE_TAP", "LONG_PRESS")
--- @return boolean|table 发布状态 (true/false) 或所有状态表(当msg_type为"all"时)
-function extp.getPublishEnabled(msg_type)
-    if msg_type == "all" then
+-- @param msg_type 消息类型 ("ALL", "RAW_DATA", "TOUCH_DOWN", "MOVE_X", "MOVE_Y", "SWIPE_LEFT", "SWIPE_RIGHT", "SWIPE_UP", "SWIPE_DOWN", "SINGLE_TAP", "LONG_PRESS")
+-- @return boolean|table 发布状态 (true/false) 或所有状态表(当msg_type为"ALL"时)
+function extp.get_publish_enable(msg_type)
+    if msg_type == "ALL" then
         -- 返回完整的发布控制表
         return publish_control
     elseif publish_control[msg_type] ~= nil then
@@ -118,9 +138,9 @@ end
 -- 设置滑动判定阈值
 -- @param threshold number 滑动判定阈值(像素)
 -- @return boolean 操作是否成功
-function extp.setSlideThreshold(threshold)
+function extp.set_swipe_threshold(threshold)
     if type(threshold) == "number" and threshold > 0 then
-        slide_threshold = threshold
+        swipe_threshold = threshold
         log.info("extp", "滑动判定阈值设置为:", threshold)
         return true
     else
@@ -132,7 +152,7 @@ end
 -- 设置长按判定阈值
 -- @param threshold number 长按判定阈值(毫秒)
 -- @return boolean 操作是否成功
-function extp.setLongPressThreshold(threshold)
+function extp.set_long_press_threshold(threshold)
     if type(threshold) == "number" and threshold > 0 then
         long_press_threshold = threshold
         log.info("extp", "长按判定阈值设置为:", threshold)
@@ -146,24 +166,20 @@ end
 -- 触摸回调函数
 -- 参数: tp_device-触摸设备对象, tp_data-触摸数据
 local function tp_callback(tp_device, tp_data)
-    -- 发布原始数据(如果启用)
+    -- 发布原始数据
     if publish_control.RAW_DATA then
-        sys.publish("TP", tp_device, tp_data) --当前消息
-        -- sys.publish("baseTouchEvent", "RAW_DATA", moveX, 0) 统一格式可以适配此条消息
+        sys.publish("BASE_TOUCH_EVENT", "RAW_DATA", tp_device, tp_data)
     end
 
-    -- 兼容多种数据结构:数组[1]或直接单点表;字段名兼容 x/x_coordinate, y/y_coordinate
-    local p = nil
-    if type(tp_data) == "table" then
-        p = tp_data[1] or tp_data
-    end
-    if type(p) ~= "table" then return end
+    if type(tp_data[1]) ~= "table" then return end
 
-    local event_type = p.event or p.type or p.evt
-    local x = p.x or p.x_coordinate or 0
-    local y = p.y or p.y_coordinate or 0
-    local ms_h, ms_l = mcu.ticks2(1)
-    local timestamp = ms_l or p.timestamp or p.ts or 0
+    local event_type = tp_data[1].event
+    local x = tp_data[1].x
+    local y = tp_data[1].y
+    -- 获取高精度时间戳
+    local _, ms_l = mcu.ticks2(1)
+    -- 使用系统时间戳或触摸数据中的时间戳
+    local timestamp = ms_l or tp_data[1].timestamp
     if not event_type then return end
 
     if event_type == 2 then -- 抬手事件
@@ -171,21 +187,21 @@ local function tp_callback(tp_device, tp_data)
             local moveX = x - touch_down_x
             local moveY = y - touch_down_y
 
-            if moveX < -slide_threshold then
+            if moveX < -swipe_threshold then
                 if publish_control.SWIPE_LEFT then
-                    sys.publish("baseTouchEvent", "SWIPE_LEFT", moveX, 0)
+                    sys.publish("BASE_TOUCH_EVENT", "SWIPE_LEFT", moveX, 0)
                 end
-            elseif moveX > slide_threshold then
+            elseif moveX > swipe_threshold then
                 if publish_control.SWIPE_RIGHT then
-                    sys.publish("baseTouchEvent", "SWIPE_RIGHT", moveX, 0)
+                    sys.publish("BASE_TOUCH_EVENT", "SWIPE_RIGHT", moveX, 0)
                 end
-            elseif moveY < -slide_threshold then
+            elseif moveY < -swipe_threshold then
                 if publish_control.SWIPE_UP then
-                    sys.publish("baseTouchEvent", "SWIPE_UP", 0, moveY)
+                    sys.publish("BASE_TOUCH_EVENT", "SWIPE_UP", 0, moveY)
                 end
-            elseif moveY > slide_threshold then
+            elseif moveY > swipe_threshold then
                 if publish_control.SWIPE_DOWN then
-                    sys.publish("baseTouchEvent", "SWIPE_DOWN", 0, moveY)
+                    sys.publish("BASE_TOUCH_EVENT", "SWIPE_DOWN", 0, moveY)
                 end
             else
                 -- 计算按下时间
@@ -194,11 +210,11 @@ local function tp_callback(tp_device, tp_data)
                 -- 判断是单击还是长按
                 if press_time < long_press_threshold then
                     if publish_control.SINGLE_TAP then
-                        sys.publish("baseTouchEvent", "SINGLE_TAP", touch_down_x, touch_down_y)
+                        sys.publish("BASE_TOUCH_EVENT", "SINGLE_TAP", touch_down_x, touch_down_y)
                     end
                 else
                     if publish_control.LONG_PRESS then
-                        sys.publish("baseTouchEvent", "LONG_PRESS", touch_down_x, touch_down_y)
+                        sys.publish("BASE_TOUCH_EVENT", "LONG_PRESS", touch_down_x, touch_down_y)
                     end
                 end
             end
@@ -211,45 +227,45 @@ local function tp_callback(tp_device, tp_data)
             touch_down_x = x
             touch_down_y = y
             touch_down_time = timestamp
-            slide_direction = nil
+            swipe_direction = nil
 
             -- 发布按下事件
             if publish_control.TOUCH_DOWN then
-                sys.publish("baseTouchEvent", "TOUCH_DOWN", x, y)
+                sys.publish("BASE_TOUCH_EVENT", "TOUCH_DOWN", x, y)
             end
         elseif state == "DOWN" and event_type == 3 then
             -- 在按下状态下接收到移动事件
-            if math.abs(x - touch_down_x) >= slide_threshold or math.abs(y - touch_down_y) >= slide_threshold then
+            if math.abs(x - touch_down_x) >= swipe_threshold or math.abs(y - touch_down_y) >= swipe_threshold then
                 state = "MOVE"
                 -- 确定滑动方向
                 if math.abs(x - touch_down_x) > math.abs(y - touch_down_y) then
                     -- 水平滑动
                     if x - touch_down_x < 0 then
-                        slide_direction = "LEFT"
+                        swipe_direction = "LEFT"
                     else
-                        slide_direction = "RIGHT"
+                        swipe_direction = "RIGHT"
                     end
                 else
                     -- 垂直滑动
                     if y - touch_down_y < 0 then
-                        slide_direction = "UP"
+                        swipe_direction = "UP"
                     else
-                        slide_direction = "DOWN"
+                        swipe_direction = "DOWN"
                     end
                 end
             end
         elseif state == "MOVE" and event_type == 3 then
             -- 在移动状态下接收到移动事件
             -- 根据滑动方向发布相应的移动事件
-            if slide_direction == "LEFT" or slide_direction == "RIGHT" then
+            if swipe_direction == "LEFT" or swipe_direction == "RIGHT" then
                 -- 水平滑动,发布MOVE_X事件
                 if publish_control.MOVE_X then
-                    sys.publish("baseTouchEvent", "MOVE_X", x - touch_down_x, 0)
+                    sys.publish("BASE_TOUCH_EVENT", "MOVE_X", x - touch_down_x, 0)
                 end
             else
                 -- 垂直滑动,发布MOVE_Y事件
                 if publish_control.MOVE_Y then
-                    sys.publish("baseTouchEvent", "MOVE_Y", 0, y - touch_down_y)
+                    sys.publish("BASE_TOUCH_EVENT", "MOVE_Y", 0, y - touch_down_y)
                 end
             end
         end
@@ -257,41 +273,118 @@ local function tp_callback(tp_device, tp_data)
 end
 
 -- 初始化触摸功能
--- @param args table 初始化参数表,包含以下字段:
---   TP_MODEL: string 触摸芯片型号 ("cst820", "gt9157", "jd9261t", "AirLCD_1001", "Air780EHM_LCD_3", "Air780EHM_LCD_4")
+-- @param param table 初始化参数表,包含以下字段:
+--   tp_model: string 触摸芯片型号 ("gt911"、"cst820"、"gt9157"、"jd9261t"、"AirLCD_1010", "AirLCD_1020", "Air780EHM_LCD_4")
 --   i2c_id: number I2C总线ID
 --   pin_rst: number 复位引脚
 --   pin_int: number 中断引脚
+--   w: number 可选,屏幕宽度
+--   h: number 可选,屏幕高度
 -- @return boolean 初始化是否成功
-function extp.init(args)
-    if type(args) ~= "table" then
+function extp.init(param)
+    if type(param) ~= "table" then
         log.error("extp", "参数必须为表")
         return false
     end
 
     -- 检查必要参数
-    if not args.TP_MODEL then
-        log.error("extp", "缺少必要参数: TP_MODEL")
+    if not param.tp_model then
+        log.error("extp", "缺少必要参数: tp_model")
         return false
     end
 
-    local TP_MODEL, tp_i2c_id, tp_pin_rst, tp_pin_int = args.TP_MODEL, args.i2c_id, args.pin_rst, args.pin_int
+    local tp_model = param.tp_model
 
     -- 检查是否支持该型号
-    local config = tp_configs[TP_MODEL]
+    local config = tp_configs[tp_model]
     if not config then
-        log.error("extp", "不支持的触摸型号:", TP_MODEL)
+        log.error("extp", "不支持的触摸型号:", tp_model)
         return false
     end
 
+    -- 特殊型号参数处理
+    local final_param = {}
+    final_param.tp_model = tp_model
+
+    -- 处理特殊型号的默认配置
+    if special_tp_configs[tp_model] then
+        local default_config = special_tp_configs[tp_model]
+
+        if tp_model == "Air780EHM_LCD_4" then
+            -- Air780EHM_LCD_4: 强制使用默认配置,忽略传入的其他参数
+            final_param.i2c_id = default_config.i2c_id
+            final_param.pin_rst = default_config.pin_rst
+            final_param.pin_int = default_config.pin_int
+            log.info("extp", "Air780EHM_LCD_4使用固定配置")
+        else
+            -- AirLCD_1010 和 AirLCD_1020: 使用传入参数,如果未传入则使用默认配置
+            final_param.i2c_id = param.i2c_id or default_config.i2c_id
+            final_param.pin_rst = param.pin_rst or default_config.pin_rst
+            final_param.pin_int = param.pin_int or default_config.pin_int
+
+            -- 记录使用的配置来源
+            if param.i2c_id then
+                log.info("extp", tp_model, "使用传入的i2c_id")
+            else
+                log.info("extp", tp_model, "使用默认i2c_id")
+            end
+
+            if param.pin_rst then
+                log.info("extp", tp_model, "使用传入的pin_rst")
+            else
+                log.info("extp", tp_model, "使用默认pin_rst")
+            end
+
+            if param.pin_int then
+                log.info("extp", tp_model, "使用传入的pin_int")
+            else
+                log.info("extp", tp_model, "使用默认pin_int")
+            end
+        end
+    else
+        -- 其他型号:直接使用传入参数
+        final_param.i2c_id = param.i2c_id
+        final_param.pin_rst = param.pin_rst
+        final_param.pin_int = param.pin_int
+    end
+
+    local tp_i2c_id, tp_pin_rst, tp_pin_int = final_param.i2c_id, final_param.pin_rst or 255, final_param.pin_int
+
+    -- 构建tp.init的参数表,增加w和h可选参数
+    local tp_init_params = {
+        port = tp_i2c_id, 
+        pin_rst = tp_pin_rst, 
+        pin_int = tp_pin_int
+    }
+    
+    -- 如果传入了w和h参数,则添加到参数表中
+    if param.w then
+        tp_init_params.w = param.w
+        log.info("extp", "设置屏幕宽度:", param.w)
+    end
+    
+    if param.h then
+        tp_init_params.h = param.h
+        log.info("extp", "设置屏幕高度:", param.h)
+    end
+
     -- 统一初始化流程
     if type(tp_i2c_id) ~= "userdata" and config.i2c_speed ~= nil then
         i2c.setup(tp_i2c_id, config.i2c_speed)
     end
-    local tp_device = tp.init(config.tp_model, { port = tp_i2c_id, pin_rst = tp_pin_rst, pin_int = tp_pin_int },
-    tp_callback)
+    
+    -- 使用包含w和h参数的table调用tp.init
+    local tp_device = tp.init(config.tp_model, tp_init_params, tp_callback)
     if tp_device ~= nil then return true end
 
+    if tp_device == nil then
+        -- 如果第一次初始化失败,尝试不带pin_rst的初始化
+        tp_init_params.pin_rst = 255
+        local tp_device = tp.init(config.tp_model, tp_init_params, tp_callback)
+
+        if tp_device ~= nil then return true end
+    end
+
     -- 若硬件触摸初始化失败,尝试PC触摸回退
     log.warn("extp", "触摸初始化失败,尝试PC触摸回退")
     local ok_pc, dev_pc = pcall(tp.init, "pc", { port = 0 }, tp_callback)