获取和配置 IC 关键信息
Read time: 6 minute(s)
执行 CTP 移植流程之前,须获取触摸 IC 的关键信息,包括但不限于:
-
从机设备地址
-
触摸坐标信息,须至少包含下列信息:
- 触摸点 ID 号
- X 轴坐标值
- Y 轴坐标值
- 触摸点个数
- 硬件上电时序
从机设备地址
获取触摸芯片的从机地址是主控和外设通信的关键步骤,常见的获取从机设备地址的方法如下所示:
-
执行硬件扫描:
通过i2c-tools
扫描硬件获取从机设备的地址,须确保硬件连接正常。详细流程如下:- 使能
i2c-tools
测试代码。Local packages options ---> Third-party packages options ---> [*] i2c-tools: a collection of i2c tools including scan/read/write
-
在任意串口执行
i2c scan i2c interface
命令,例如:i2c scan i2c1
i2c interface 需按照实际使用的接口进行设置。
系统输出示例如下,表示 GT911 当前的从机地址为 0x5D:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- 5D -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
注:i2c-tools
也可以用于检测主控与外设之间的硬件连接关系是否正常。如果执行上述命令后扫描不到任何从机地址,则需检查硬件是否正常以及 I2C 是否有外部上拉电阻等情况。 - 使能
-
从对应 IC 的规格书中获取信息。
通常情况下,IC 规格书会按照以下方式列示相关从机地址:-
直接提供 7 位从机地址。例如,GSL3676 的规格书中列示了 7 位从机地址为 0x40。如果直接列示了从机地址,则在新建或修改 CTP 驱动时,直接使用该从机地址,例如位 0x40。
#define GSL3676_SLAVE_ADDR 0x40 gsl3676_client.client_addr = GSL3676_SLAVE_ADDR;
-
列示含读写位(8 位)的从机地址。例如,GT911 的规格书给出 0xBA/ 0xBB 的从机地址,差值为 1,说明列示的地址为 8 位,含读写位。
如果列示了含读写位的 8 位从机地址,则在新建或修改 CTP 驱动时,须将地址右移 1 位,例如将 0xBA/0xBB 右移 1 位后得到 0x5D 的从机地址。#define GT911_ADDRESS_HIGH 0x5D gt911_client.client_addr = GT911_ADDRESS_HIGH;
-
触摸点 ID 号
坐标数据的数组内容存储都是以 ID 作为下标索引,可在规格书中搜索包含 ID 字样的字段,示例如下:
- Track ID 示例:
off_set = read_index * C145HAX01_POINT_INFO_LEN; read_id = (read_buf[off_set + 3] >> 4) & 0x0f; pre_id[read_index] = read_id; input_x = ((read_buf[off_set + 1] & 0x0f) << 8) | read_buf[off_set + 2]; input_y = ((read_buf[off_set + 3] & 0xf) << 8) | read_buf[off_set + 4];
- Touch ID 示例:
off_set = read_index * 8; read_id = read_buf[off_set] & 0x0f; pre_id[read_index] = read_id; input_x = read_buf[off_set + 1] | (read_buf[off_set + 2] << 8); /* x */ input_y = read_buf[off_set + 3] | (read_buf[off_set + 4] << 8); /* y */ input_w = read_buf[off_set + 5] | (read_buf[off_set + 6] << 8); /* size */
XY 坐标计算
常见 CTP 的 XY 在 16 bit 的数据范围内,一般由两个字节组合而成,需要通过一定的逻辑计算出真实的坐标值。
在处理 CTP 的 XY 坐标时,通常需要将两个字节组合成一个 16
位的数据。一个坐标值通常由高位和低位组合而成。以下是如何通过逻辑操作从读取缓冲区中提取坐标值并将其存储为变量的详细步骤:
off_set = read_index * 8; read_id = read_buf[off_set] & 0x0f; pre_id[read_index] = read_id; input_x = read_buf[off_set + 1] | (read_buf[off_set + 2] << 8); /* x */ input_y = read_buf[off_set + 3] | (read_buf[off_set + 4] << 8); /* y */ input_w = read_buf[off_set + 5] | (read_buf[off_set + 6] << 8); /* size */
触摸点个数
触摸事件可分为按下、移动和抬起,事件的获取是通过当前触摸点个数与上一次触摸点个数比较得到的,下面是几种比较常见的获取当前触摸点个数的方式:
-
从寄存器可以直接获取当前的触摸点个数
touch_num = point_status & 0x0f; /* get point num */
-
通过每根手指的触摸事件间接计算:
cmd[0] = (rt_uint8_t)((ST77922_TOUCH_INFO >> 8) & 0xFF); cmd[1] = (rt_uint8_t)(ST77922_TOUCH_INFO & 0xFF); /* read point num is touch_num */ if (st77922_read_regs(&st77922_client, cmd, read_buf, sizeof(read_buf)) != RT_EOK) { rt_kprintf("read point failed\n"); read_num = 0; goto __exit; } for (i = 0; i < ST77922_MAX_TOUCH; i++) { num_valid = ((read_buf[7 * i + 4] & 0x80) != 0) ? 1 : 0; touch_num += num_valid; }
TP 硬件上电时序
rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT); rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW); rt_thread_delay(10); // irq output 0 rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT); rt_pin_write(cfg->irq_pin.pin, PIN_LOW); rt_thread_delay(2); // rst output 1 rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT); rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH); rt_thread_delay(5); // rst input rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_INPUT); //irq output 0 rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT); rt_pin_write(cfg->irq_pin.pin, PIN_LOW); rt_thread_delay(50); rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_INPUT);