CTP 调试指南
移植CTP流程示例:gt911
本指南将通过实例gt911,简明扼要地介绍如何进行CTP的移植与配置:
添加编译路径
bsp/peripheral/touch/SConscript
文件添加编译路径
c
if GetDepend('AIC_TOUCH_PANEL_GT911'):
CPPPATH.append(cwd + '/gt911/inc')
src += Glob('gt911/src/*.c')
1
2
3
2
3
添加menuconfig设备配置
bsp/peripheral/touch/Kconfig
添加CTP的相关配置
c
choice
prompt "Select CTP device"
default AIC_TOUCH_PANEL_GT911
depends on AIC_USING_CTP
config AIC_TOUCH_PANEL_GT911 //添加设备
bool "GT911"
config AIC_TOUCH_PANEL_NAME
string
default "gt911" if AIC_TOUCH_PANEL_GT911 //添加设备名
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
新增PANEL只需在设备和设备名那里添加相应的定义,其他公用的配置已经提取出来,只需根据原理图去对应设置
其他公用配置说明
c
config AIC_TOUCH_PANEL_I2C_CHAN //I2C总线号宏定义
string "Touch using I2C channel index"
default "i2c3"
depends on AIC_USING_CTP
config AIC_TOUCH_PANEL_RST_PIN //复位引脚宏定义
string "Touch reset pin"
default "PA.8"
depends on AIC_USING_CTP
config AIC_TOUCH_PANEL_INT_PIN //中断引脚宏定义
string "Touch irq pin"
default "PA.9"
depends on AIC_USING_CTP
config AIC_TOUCH_X_COORDINATE_RANGE //X轴范围宏定义
int "Touch x coordinate range"
default 1024
depends on AIC_USING_CTP
config AIC_TOUCH_Y_COORDINATE_RANGE //Y轴范围宏定义
int "Touch y coordinate range"
default 600
depends on AIC_USING_CTP
config AIC_TOUCH_X_FILP //X轴坐标翻转宏定义
bool "Touch filp x coordinate"
default n
depends on AIC_USING_CTP
config AIC_TOUCH_Y_FILP //Y轴坐标翻转宏定义
bool "Touch filp y coordinate"
default n
depends on AIC_USING_CTP
config AIC_TOUCH_90_DEGREE_ROTATION //坐标90度旋转宏定义
bool "Touch 90 degrees rotation"
default n
depends on AIC_USING_CTP
config AIC_TOUCH_270_DEGREE_ROTATION //坐标270度旋转宏定义
bool "Touch 270 degrees rotation"
default n
depends on AIC_USING_CTP
config AIC_TOUCH_REPORT_X_COORDINATE //X轴坐标范围上报宏定义
int
default AIC_TOUCH_Y_COORDINATE_RANGE if AIC_TOUCH_90_DEGREE_ROTATION
default AIC_TOUCH_Y_COORDINATE_RANGE if AIC_TOUCH_270_DEGREE_ROTATION
default AIC_TOUCH_X_COORDINATE_RANGE
depends on AIC_USING_CTP
config AIC_TOUCH_REPORT_Y_COORDINATE //Y轴坐标范围上报宏定义
int
default AIC_TOUCH_X_COORDINATE_RANGE if AIC_TOUCH_90_DEGREE_ROTATION
default AIC_TOUCH_X_COORDINATE_RANGE if AIC_TOUCH_270_DEGREE_ROTATION
default AIC_TOUCH_Y_COORDINATE_RANGE
depends on AIC_USING_CTP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
创建gt911驱动的源代码文件
文件清单如下:
c
bsp/peripheral/touch/gt911/inc/gt911.h //头文件
bsp/peripheral/touch/gt911/scr/gt911.c //源代码文件
1
2
2
这两个文件构成gt911触控驱动的基础框架
完成上述步骤后,gt911的移植工作即告一段落。可直接使用bsp/examples/test-ctp/test_touch.c进行测试,后续章节将会介绍
驱动文件解析
下面将以 gt911.c
文件对移植一款CTP进行详细的讲解
c
#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
#define DBG_TAG "gt911"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include "gt911.h"
//dev结构体定义,其他TP也需要定义这个变量
static struct rt_i2c_client gt911_client;
//这个是gt911特有的数组用于更改固件的,没这需求的可以不定义
static rt_uint8_t GT911_CFG_TBL[] = {
0x6b, 0x00, 0x04, 0x58, 0x02, 0x05, 0x0d, 0x00, 0x01, 0x0f, 0x28, 0x0f,
0x50, 0x32, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x8a, 0x2a, 0x0c, 0x45, 0x47, 0x0c, 0x08, 0x00, 0x00,
0x00, 0x40, 0x03, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x64, 0x32,
0x00, 0x00, 0x00, 0x28, 0x64, 0x94, 0xd5, 0x02, 0x07, 0x00, 0x00, 0x04,
0x95, 0x2c, 0x00, 0x8b, 0x34, 0x00, 0x82, 0x3f, 0x00, 0x7d, 0x4c, 0x00,
0x7a, 0x5b, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a,
0x08, 0x06, 0x04, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18,
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x24, 0x13, 0x12, 0x10, 0x0f,
0x0a, 0x08, 0x06, 0x04, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x79, 0x01,
};
/*
* I2C写函数,主要传参有三个:dev,要写入的数据,写入数据的长度
* 这个函数适用于所有的TP,编写的时候只需要更换函数名字,跟TP对应上即可
*/
static rt_err_t gt911_write_reg(struct rt_i2c_client *dev, rt_uint8_t *data,
rt_uint8_t len)
{
struct rt_i2c_msg msgs;
//从机的设备地址,在初始化的时候会进行赋值
msgs.addr = dev->client_addr;
//I2C读写标志,这里是写标志
msgs.flags = RT_I2C_WR;
//要发送的数据
msgs.buf = data;
//数据长度
msgs.len = len;
if (rt_i2c_transfer(dev->bus, &msgs, 1) == 1) {
return RT_EOK;
} else {
return -RT_ERROR;
}
}
/*
* I2C读函数,主要传参有四个:dev,要读取的寄存器地址,接受数据的buf,读取的长度
* 这个函数适用于所有的TP,编写的时候只需要更换函数名字,跟TP对应上即可
*/
static rt_err_t gt911_read_regs(struct rt_i2c_client *dev, rt_uint8_t *reg,
rt_uint8_t *data, rt_uint8_t len)
{
struct rt_i2c_msg msgs[2];
msgs[0].addr = dev->client_addr;
msgs[0].flags = RT_I2C_WR;
/*
* 要读取得寄存器地址,目前市面上有两种常见得TP,一种是16位寄存器地址的,一种是8位的
* 16位的寄存器地址需要先发送高8位,再发送低8位,分成两个buf
* 8位的直接发送即可
*/
msgs[0].buf = reg;
// 这里的长度对应上面的16位或者8位,16位长度为2,8位长度为1
msgs[0].len = GT911_REGITER_LEN;
msgs[1].addr = dev->client_addr;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = data;
msgs[1].len = len;
if (rt_i2c_transfer(dev->bus, msgs, 2) == 2) {
return RT_EOK;
} else {
return -RT_ERROR;
}
}
/*
* 这个函数主要用于获取TP的ID,有些TP并没有具体获取ID的寄存器公开,可以不添加
*/
static rt_err_t gt911_get_product_id(struct rt_i2c_client *dev,
rt_uint8_t *data, rt_uint8_t len)
{
rt_uint8_t reg[2];
// 这里就是将16位的寄存器地址拆开高8位低8位两个buf进行传输
reg[0] = (rt_uint8_t)(GT911_PRODUCT_ID >> 8);
reg[1] = (rt_uint8_t)(GT911_PRODUCT_ID & 0xff);
if (gt911_read_regs(dev, reg, data, len) != RT_EOK) {
LOG_E("read id failed");
return -RT_ERROR;
}
return RT_EOK;
}
/*
* 这个函数主要用于获取TP的参数,包括:xy的坐标范围最大值,触摸点的个数
*/
static rt_err_t gt911_get_info(struct rt_i2c_client *dev,
struct rt_touch_info *info)
{
rt_uint8_t reg[2];
rt_uint8_t out_info[7];
rt_uint8_t out_len = 7;
reg[0] = (rt_uint8_t)(GT911_CONFIG_REG >> 8);
reg[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
if (gt911_read_regs(dev, reg, out_info, out_len) != RT_EOK) {
LOG_E("read info failed");
return -RT_ERROR;
}
/*
* 这里是对获取到的数据进行组合得到参数信息
* 有些TP对这些寄存器并不开放,因此我们也可以通过直接赋值的方法设置参数
* 设置的参数要跟TP自带的固件对应上才能正常使用,具体操作如下
*/
info->range_x = (out_info[2] << 8) | out_info[1];
//info->range_x = AIC_TOUCH_X_COORDINATE_RANGE;
//这里的AIC_TOUCH_X_COORDINATE_RANGE就是公用参数那里可以配置的,所以不同TP都可通用
info->range_y = (out_info[4] << 8) | out_info[3];
//info->range_y = AIC_TOUCH_Y_COORDINATE_RANGE;
//这里的AIC_TOUCH_Y_COORDINATE_RANGE也是公用参数那里可以配置的,所以不同TP都可通用
info->point_num = out_info[5] & 0x0f;
//info->point_num = 5;
if (info->point_num > GT911_MAX_TOUCH) {
info->point_num = GT911_MAX_TOUCH;
rt_kprintf("Warning,tp support more than 5 points, limited to 5 points\n");
}
return RT_EOK;
}
/*
* 这里的静态变量主要是为了存储坐标点的数据,然后作逻辑判断
* GT911_MAX_TOUCH是最大的触摸点个数也就是上面info->point_num定义的5,所以数组赋值了5个-1作为初始值
* 不同的触摸个数这个数组大小不一样
*/
static int16_t pre_x[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
static int16_t pre_y[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
//这个pre_w是触摸面积的定义,有些TP并没有相关描述,所以不是必须的,但xy是必须要有
static int16_t pre_w[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
static rt_uint8_t s_tp_dowm[GT911_MAX_TOUCH] = {0};
static struct rt_touch_data *read_data = RT_NULL;
/*
* 这个是抬起事件上报函数,修改函数明即可使用
* 如果定义上面的静态数组的时候没有定义pre_w则下面代码关于pre_w的要删除
*/
static void gt911_touch_up(void *buf, int8_t id)
{
read_data = (struct rt_touch_data *)buf;
if (s_tp_dowm[id] == 1) {
s_tp_dowm[id] = 0;
read_data[id].event = RT_TOUCH_EVENT_UP;
} else {
read_data[id].event = RT_TOUCH_EVENT_NONE;
}
read_data[id].timestamp = rt_touch_get_ts();
//下面的这行可以删除
read_data[id].width = pre_w[id];
read_data[id].x_coordinate = pre_x[id];
read_data[id].y_coordinate = pre_y[id];
read_data[id].track_id = id;
pre_x[id] = -1; /* last point is none */
pre_y[id] = -1;
//下面的这行可以删除
pre_w[id] = -1;
}
/*
* 这个是移动和按下事件函数,修改函数明即可使用
* 如果定义上面的静态数组的时候没有定义pre_w则下面代码关于pre_w的要删除
* 包括函数传参里面的int16_t w也要删除
*/
static void gt911_touch_down(void *buf, int8_t id, int16_t x, int16_t y,
int16_t w)
{
read_data = (struct rt_touch_data *)buf;
if (s_tp_dowm[id] == 1) {
read_data[id].event = RT_TOUCH_EVENT_MOVE;
} else {
read_data[id].event = RT_TOUCH_EVENT_DOWN;
s_tp_dowm[id] = 1;
}
read_data[id].timestamp = rt_touch_get_ts();
//下面的这行可以删除
read_data[id].width = w;
read_data[id].x_coordinate = x;
read_data[id].y_coordinate = y;
read_data[id].track_id = id;
pre_x[id] = x; /* save last point */
pre_y[id] = y;
//下面的这行可以删除
pre_w[id] = w;
}
/*
* 这个读取坐标点数据的函数,必须实现
*/
static rt_size_t gt911_read_point(struct rt_touch_device *touch, void *buf,
rt_size_t read_num)
{
rt_uint8_t point_status = 0;
rt_uint8_t touch_num = 0;
rt_uint8_t write_buf[3];
rt_uint8_t cmd[2];
//要读取的数据的长度,一般是读取坐标数量*每一个坐标信息的buf长度+一些其他信息
rt_uint8_t read_buf[8 * GT911_MAX_TOUCH] = { 0 };
rt_uint8_t read_index;
int8_t read_id = 0;
int16_t input_x = 0;
int16_t input_y = 0;
int16_t input_w = 0;
//存储上一次触摸点个数
static rt_uint8_t pre_touch = 0;
//存储上一次坐标ID的数组
static int8_t pre_id[GT911_MAX_TOUCH] = { 0 };
//这里是对传参过来的buf清零,避免buf里面已有数据对坐标读取产生影响
rt_memset(buf, 0, sizeof(struct rt_touch_data) * read_num);
/* point status register */
cmd[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
cmd[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
if (gt911_read_regs(>911_client, cmd, &point_status, 1) != RT_EOK) {
LOG_D("read point failed\n");
read_num = 0;
goto exit_;
}
if (point_status == 0) /* no data */
{
read_num = 0;
goto exit_;
}
if ((point_status & 0x80) == 0) /* data is not ready */
{
read_num = 0;
goto exit_;
}
//触摸点个数赋值
touch_num = point_status & 0x0f; /* get point num */
if (touch_num > GT911_MAX_TOUCH) /* point num is not correct */
{
read_num = 0;
goto exit_;
}
cmd[0] = (rt_uint8_t)((GT911_POINT1_REG >> 8) & 0xFF);
cmd[1] = (rt_uint8_t)(GT911_POINT1_REG & 0xFF);
//读取坐标数据
if (gt911_read_regs(>911_client, cmd, read_buf,
read_num * GT911_POINT_INFO_NUM) != RT_EOK) {
LOG_D("read point failed\n");
read_num = 0;
goto exit_;
}
/*
* 下面是对坐标事件的处理,一般可以直接照抄,更换一下信息即可
*/
if (pre_touch > touch_num) /* point up */
{
for (read_index = 0; read_index < pre_touch; read_index++) {
rt_uint8_t j;
for (j = 0; j < touch_num; j++) /* this time touch num */
{
//坐标ID这里是需要更换的,要按照规格书来赋值
read_id = read_buf[j * 8] & 0x0F;
if (pre_id[read_index] == read_id) /* this id is not free */
break;
if (j >= touch_num - 1) {
rt_uint8_t up_id;
up_id = pre_id[read_index];
gt911_touch_up(buf, up_id);
}
}
}
}
if (touch_num) /* point down */
{
rt_uint8_t off_set;
for (read_index = 0; read_index < touch_num; read_index++) {
//这个offset是一个坐标信息的偏移,8代表一个坐标要读取8个byte,具体是多少按照规格书来
off_set = read_index * 8;
//坐标ID这里是需要更换的,要按照规格书来赋值
read_id = read_buf[off_set] & 0x0f;
pre_id[read_index] = read_id;
//下面的xyw也是需要按照规格书重新组合buf
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 */
gt911_touch_down(buf, read_id, input_x, input_y, input_w);
}
} else if (pre_touch) {
for (read_index = 0; read_index < pre_touch; read_index++) {
gt911_touch_up(buf, pre_id[read_index]);
}
}
//将当前的触摸点个数赋值给pre_touch
pre_touch = touch_num;
exit_:
//这里是gt911特有的每次读取完数据要发送0x00完成同步,没有这个要求的不需要实现
write_buf[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
write_buf[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
write_buf[2] = 0x00;
gt911_write_reg(>911_client, write_buf, 3);
//返回触摸点个数
return read_num;
}
/*
* TP的控制函数,一般来说只需要实现RT_TOUCH_CTRL_GET_INFO,其他的可以不管
*/
static rt_err_t gt911_control(struct rt_touch_device *touch, int cmd, void *arg)
{
if (cmd == RT_TOUCH_CTRL_GET_ID) {
return gt911_get_product_id(>911_client, arg, 6);
}
if (cmd == RT_TOUCH_CTRL_GET_INFO) {
return gt911_get_info(>911_client, arg);
}
rt_uint8_t buf[4];
rt_uint8_t i = 0;
rt_uint8_t *config;
config =
(rt_uint8_t *)rt_calloc(1, sizeof(GT911_CFG_TBL) + GT911_REGITER_LEN);
if (config == RT_NULL) {
LOG_D("malloc config memory failed\n");
return -RT_ERROR;
}
config[0] = (rt_uint8_t)((GT911_CONFIG_REG >> 8) & 0xFF);
config[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
memcpy(&config[2], GT911_CFG_TBL, sizeof(GT911_CFG_TBL));
switch (cmd) {
case RT_TOUCH_CTRL_SET_X_RANGE: {
rt_uint16_t x_range;
x_range = *(rt_uint16_t *)arg;
config[4] = (rt_uint8_t)(x_range >> 8);
config[3] = (rt_uint8_t)(x_range & 0xff);
GT911_CFG_TBL[2] = config[4];
GT911_CFG_TBL[1] = config[3];
break;
}
case RT_TOUCH_CTRL_SET_Y_RANGE: {
rt_uint16_t y_range;
y_range = *(rt_uint16_t *)arg;
config[6] = (rt_uint8_t)(y_range >> 8);
config[5] = (rt_uint8_t)(y_range & 0xff);
GT911_CFG_TBL[4] = config[6];
GT911_CFG_TBL[3] = config[5];
break;
}
case RT_TOUCH_CTRL_SET_X_TO_Y: {
config[8] ^= (1 << 3);
break;
}
case RT_TOUCH_CTRL_SET_MODE: {
rt_uint16_t trig_type;
trig_type = *(rt_uint16_t *)arg;
switch (trig_type) {
case RT_DEVICE_FLAG_INT_RX:
config[8] &= 0xFC;
break;
case RT_DEVICE_FLAG_RDONLY:
config[8] &= 0xFC;
config[8] |= 0x02;
break;
default:
break;
}
break;
}
default: {
break;
}
}
if (gt911_write_reg(>911_client, config,
sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN) != RT_EOK) {
LOG_D("send config failed");
return -1;
}
buf[0] = (rt_uint8_t)((GT911_CHECK_SUM >> 8) & 0xFF);
buf[1] = (rt_uint8_t)(GT911_CHECK_SUM & 0xFF);
buf[2] = 0;
for (i = GT911_ADDR_LEN; i < sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN; i++) {
buf[GT911_ADDR_LEN] += config[i];
}
buf[2] = (~buf[2]) + 1;
buf[3] = 1;
gt911_write_reg(>911_client, buf, 4);
rt_free(config);
return RT_EOK;
}
/*
* rt_touch_ops,主要是完成对读坐标和控制TP的函数注册
*/
static struct rt_touch_ops gt911_touch_ops = {
.touch_readpoint = gt911_read_point,
.touch_control = gt911_control,
};
/*
* 这个函数主要实现对TP的初始操作
*/
static int rt_hw_gt911_init(const char *name, struct rt_touch_config *cfg)
{
struct rt_touch_device *touch_device = RT_NULL;
touch_device =
(struct rt_touch_device *)rt_malloc(sizeof(struct rt_touch_device));
if (touch_device == RT_NULL) {
LOG_E("touch device malloc fail");
return -RT_ERROR;
}
rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device));
//这里是对TP一些上下电的操作,具体根据规格书来
/* hw init*/
// rst output 0
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);
//最后必须要对IRQ引脚设置回输入模式,不然会影响中断信号的获取
rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_INPUT);
gt911_client.bus =
(struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
if (gt911_client.bus == RT_NULL) {
LOG_E("Can't find %s device", cfg->dev_name);
return -RT_ERROR;
}
//打开设备中断模式用RT_DEVICE_FLAG_RDWR
if (rt_device_open((rt_device_t)gt911_client.bus, RT_DEVICE_FLAG_RDWR) !=
RT_EOK) {
LOG_E("open %s device failed", cfg->dev_name);
return -RT_ERROR;
}
//从机设备地址赋值
gt911_client.client_addr = GT911_ADDRESS_HIGH;
/* register touch device */
//赋值芯片的型号和类型
touch_device->info.type = RT_TOUCH_TYPE_CAPACITANCE;
touch_device->info.vendor = RT_TOUCH_VENDOR_GT;
rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
touch_device->ops = >911_touch_ops;
if (RT_EOK != rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL)) {
LOG_E("touch device gt911 init failed !!!");
return -RT_ERROR;
}
LOG_I("touch device gt911 init success");
return RT_EOK;
}
/*
* 这个函数主要实现对GPIO的初始化,这个函数只需修改函数名即可复用
*/
static int rt_gt911_gpio_cfg()
{
unsigned int g, p;
long pin;
// AIC_TOUCH_PANEL_RST_PIN是公用参数里面的复位引脚
pin = drv_pin_get(AIC_TOUCH_PANEL_RST_PIN);
g = GPIO_GROUP(pin);
p = GPIO_GROUP_PIN(pin);
hal_gpio_direction_input(g, p);
// AIC_TOUCH_PANEL_INT_PIN是公用参数里面的中断引脚
pin = drv_pin_get(AIC_TOUCH_PANEL_INT_PIN);
g = GPIO_GROUP(pin);
p = GPIO_GROUP_PIN(pin);
hal_gpio_direction_input(g, p);
hal_gpio_set_irq_mode(g, p, 0);
return 0;
}
/*
* 这个函数主要注册整个设备,改个名字即可复用
*/
static int rt_hw_gt911_port(void)
{
struct rt_touch_config cfg;
rt_uint8_t rst_pin;
rt_gt911_gpio_cfg();
rst_pin = drv_pin_get(AIC_TOUCH_PANEL_RST_PIN);
cfg.dev_name = AIC_TOUCH_PANEL_I2C_CHAN;
cfg.irq_pin.pin = drv_pin_get(AIC_TOUCH_PANEL_INT_PIN);
cfg.irq_pin.mode = PIN_MODE_INPUT;
cfg.user_data = &rst_pin;
#ifdef AIC_PM_DEMO
rt_pm_set_pin_wakeup_source(cfg.irq_pin.pin);
#endif
// AIC_TOUCH_PANEL_NAME这个是公用参数里面设备名字,也可以直接复用
rt_hw_gt911_init(AIC_TOUCH_PANEL_NAME, &cfg);
return 0;
}
//通过宏 ``INIT_DEVICE_EXPORT``,驱动在系统启动时自动加载,即可轻松适配不同型号的触控芯片
INIT_DEVICE_EXPORT(rt_hw_gt911_port);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
配置触摸屏
Luban-Lite 可以支持两种触摸屏:
电容屏:CTP;
电阻屏:RTP;
配置
CTP 配置部分,以 D211BBV-DEMO-V2-0 配置 GT911 为例:
数据通道采用 i2c3;
RST 引脚使用 PA8;
INT 引脚使用 PA9;
X轴范围 0 - 1024;
Y轴范围 0 - 600;
通过 scons --menuconfig
命令,进入配置页面,完成如下配置:
c
Board options --->
[*] Using I2c3
I2c3 Parameter --->
[ ] Using I2C3 10-bit Addr(default 7-bit addr) #默认7bit寻址,使能则是10bit寻址
[ ] Using I2C3 Stand Speed(default fast speed) #默认400k速率,使能则是100k速率
[ ] Using I2C3 Slave Mode(default master mode) #默认主机模式,使能则是从机模式
Rt-Thread options --->
RT-Thread Components --->
Device Drivers --->
[*] Using Touch device drivers
[*] touch irq use pin irq
Drivers options --->
Peripheral --->
Touch Panel Support --->
--- Touch Panel Support
Select touch device (CTP) ---> #选择CTP或者RTP
Select CTP device (GT911) ---> #选择不同的Touch设备
(i2c3) Touch using I2C channel index #设置I2C总线号
(PA.8) Touch reset pin #设置TP的复位引脚
(PA.9) Touch irq pin #设置TP的中断引脚
(1024) Touch x coordinate range #设置TP的X轴坐标最大值
(600) Touch y coordinate range #设置TP的Y轴坐标最大值
[ ] Touch filp x coordinate #设置X轴对称翻转
[ ] Touch filp y coordinate #设置Y对称轴翻转
[ ] Touch 90 degrees rotation #设置TP顺时针旋转90度
[ ] Touch 270 degrees rotation #设置TP顺时针旋转270度
Drivers examples --->
[*] Enable touch panel driver test command #TP测试程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
验证
使用LVGL
使用默认项目的 test_lvgl 程序验证 CTP 的功能,系统正常启动后,即可在触屏上点触、滑动,现在的框架已经对接好LVGL,不需要修改LVGL的代码即可正常使用。
使用 test_touch
打开TP测试程序,并取消test_lvgl :
c
Application options --->
[ ] ArtInChip lvgl demo
1
2
2
注意
测试程序运行之前,请务必保证没有 GUI 应用程序打开 gt911 设备。
系统驱动之后,运行 test_touch 命令,并在 CTP 上触摸滑动,观察调试串口输出如下:
c
aic/> test_touch gt911 # 运行测试程序
id = GT911 # 获取gt911 id
range_x = 1024 # 打印x范围
range_y = 600 # 打印y范围
point_num = 1
aic/>
aic/>
aic/>
aic/>
aic/> 0 844 379 2 #坐标id x坐标值 y坐标值 触摸事件(2:按下 3:移动 1:抬起)
0 844 379 3
0 844 379 3
0 834 379 3
0 822 379 3
0 801 380 3
0 785 382 3
0 769 384 3
0 754 387 3
0 735 389 3
0 714 391 3
0 692 397 3
0 670 404 3
0 645 414 3
0 645 414 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24