当前位置:网站首页>海思35xx实现GT911触摸屏功能「建议收藏」
海思35xx实现GT911触摸屏功能「建议收藏」
2022-06-28 12:56:00 【全栈程序员站长】
大家好,又见面了,我是你们的朋友全栈君。
海思35xx通过gpio模拟i2c实现GT911触摸功能
1.遇到的问题
- 地址选配后一直不对,首先检测硬件问题,然后通过调试驱动部分,打印调试从设备给的ack(没有逻辑分析仪);发现寄存器地址一直为FF或00,检查发现GT911地址均为16bit,而读写i2c接口是8位的;
- 成功后点击触摸板点击位置与实际不一致;可以进行坐标转换;
2.网上下载
GT91xx编程指南文件
电容触摸芯片GT911 Datasheet 文件
3.Datasheet 重点部分
(1) gpio模拟时,可能需要注意这个延时时间;
(2) 选择地址为0x28/0x29或0xBA/0xBB时序
4.部分代码
(1) 部分寄存器定义
#define GT_CMD_WR 0x28 //写地址
//#define GT_CMD_RD 0x29 //读命令 我的驱动内部逻辑已处理,仅需要写地址就可以了
//GT91xx 部分寄存器定义
#define GT_CTRL_REG 0X8040 //GT911控制寄存器
#define GT_CFGS_REG 0X8047 //GT911配置起始地址寄存器
#define GT_CHECK_REG 0X80FF //GT911校验和寄存器
#define GT_FRESH_REG 0X8100 //配置已更新标志
#define GT_PID_REG 0X8140 //GT911产品ID寄存器
#define GT_FIRMVERSION_REG 0x8144 //固件版本
#define GT_GSTID_REG 0X814E //GT911当前检测到的触摸情况
#define GT_TP1_REG 0X8150 //第一个触摸点数据地址
#define GT_TP2_REG 0X8158 //第二个触摸点数据地址
#define GT_TP3_REG 0X8160 //第三个触摸点数据地址
#define GT_TP4_REG 0X8168 //第四个触摸点数据地址
#define GT_TP5_REG 0X8170 //第五个触摸点数据地址
const u32 GT911_TPX_TBL[5]={
GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};
(2) 配置GT911从设备地址0x28/0x29或0xBB/0xBA
void TouchScreen::GT911_INT(u8 cmd)
{
if(cmd){
CGpio::Instance()->SetGpio(13,5,1,1);
}else{
CGpio::Instance()->SetGpio(13,5,1,0);
}
}
void TouchScreen::GT911_RST(u8 cmd)
{
if(cmd){
CGpio::Instance()->SetGpio(6,3,1,1);
}else{
CGpio::Instance()->SetGpio(6,3,1,0);
}
}
//我选的是0x28/0x29
void TouchScreen::goodix_init()
{
GT911_RST(0);
GT911_INT(0);
msleep(50);
GT911_INT(1);
usleep(200);
GT911_RST(1);
msleep(10);
GT911_INT(0);
msleep(80);
Hi_Gpio_SetDir(13,5,0);//GPIO13_5设为输入
msleep(60);
return;
}
(3) i2c写接口及驱动接口参考
// gpio_i2c2_read 、 gpio_i2c2_write驱动部分参考如下:
EXPORT_SYMBOL(gpio_i2c2_read);
unsigned int gpio_i2c2_read(unsigned char devaddress, unsigned short address, int num_bytes)
{
unsigned char rxdata;
unsigned int ret = 0x00;
int i;
i2c_start_bit(); //gpio模拟i2c 略
i2c_send_byte((unsigned char)(devaddress));
i2c_receive_ack();
i2c_send_byte((unsigned char)((address >> 8) & 0xff));
i2c_receive_ack();
i2c_send_byte((unsigned char)(address & 0xff));
i2c_receive_ack();
i2c_start_bit();
i2c_send_byte((unsigned char)(devaddress) | 1); //只需要写地址的原因在这里,完全可以其他处理;
i2c_receive_ack();
for (i=0; i<num_bytes-1; i++) {
rxdata = i2c_receive_byte();
//i2c_send_ack();
ret |= rxdata;
ret <<= 8;
}
rxdata = i2c_receive_byte();
// i2c_send_ack();
i2c_stop_bit();
ret |= rxdata;
// printk("dev=%x, reg =%x, rxd=%x\n", devaddress, address, ret);
return ret;
}
EXPORT_SYMBOL(gpio_i2c2_write);
void gpio_i2c2_write(unsigned char devaddress, unsigned short address, unsigned int data, int num_bytes)
{
int i;
i2c_start_bit();
i2c_send_byte((unsigned char)(devaddress));
i2c_receive_ack();
i2c_send_byte((unsigned char)((address >> 8) & 0xff));
i2c_receive_ack();
i2c_send_byte((unsigned char)(address & 0xff));
i2c_receive_ack();
for (i=0; i<num_bytes; i++) {
i2c_send_byte((unsigned char)((data >> (i*8)) & 0xff));
i2c_receive_ack();
}
// i2c_send_byte((unsigned char)((data >> (i*8)) & 0xff));
i2c_stop_bit();
}
// ioctl 操作对应的驱动接口如下:
long gpioi2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
...
case GPIO_I2C_READ_SHORT:
val = *(unsigned int *)arg;
device_addr = (val&0xff000000)>>24;
reg_addr = (val&0xffff00)>>8;
reg_val = gpio_i2c2_read(device_addr, reg_addr, 2);
*(unsigned int *)arg = reg_val;
break;
case GPIO_I2C_WRITE_SHORT:
val = *(unsigned int *)arg;
device_addr = (val&0xff000000)>>24;
reg_addr = (val&0xffff00)>>8;
reg_val = val&0xffff;
gpio_i2c2_write(device_addr, reg_addr, reg_val, 2);
break;
}
//读写16位寄存器的接口;
int xxx::writeI2c16(int devaddr, int reg, int data)
{
int fd = -1;
int ret =0;
int value;
fd = open("/dev/gpioi2c", 0);
if(fd<0)
{
printf("Open gpioi2c error!\n");
return -1;
}
value = ((devaddr&0xff)<<24) | ((reg&0xffff)<<8) | (data&0xffff);
ret = ioctl(fd, GPIO_I2C_WRITE_SHORT, &value);
close(fd);
return ret;
}
(4) 触摸屏初始化
void TouchScreen::I2C_init()
{
//system("himm 0x120F08E0 0x230"); //SDA 上拉,高速
//system("himm 0x120F08E4 0x230"); //SCL
SetGpio(12,7,1,1);
SetGpio(12,6,1,1);
}
//下面的goodix_send_cfg如下:我没用到,不知道正确与否
int TouchScreen::goodix_send_cfg()
{
u8 sum[2] = {
0};
static unsigned char imps2_param [] =
{
0x69,0x00,0x04,0x58,0x02,0x05,0x0D,0x00,0x01,0x0A,0x1E,0x0F,0x64,0x46,0x03,
0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8C,0x2E,0x0E,
0x3C,0x3E,0x61,0x07,0x00,0x00,0x00,0x02,0x02,0x1D,0x00,0x01,0x00,0x00,0x00,
0x03,0x00,0x00,0x00,0x00,0x00,0x28,0x62,0x94,0xC5,0x02,0x07,0x00,0x00,0x04,
0xA1,0x2B,0x00,0x8C,0x34,0x00,0x7D,0x3E,0x00,0x6F,0x4B,0x00,0x66,0x59,0x00,
0x66,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,0x1C,0x1A,0x18,0x16,0x14,0x12,0x10,0x0E,
0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0F,
0x10,0x12,0x13,0x14,0x16,0x18,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x24,0x26,
0x28,0x29,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x38,0x01
};//厂家初始化序列
for(int i = 0; i < sizeof(imps2_param); i++)
{
writeI2c16(GT_CMD_WR,GT_CFGS_REG+i,imps2_param[i]);//写入配置 0x8047~0x8100 共186个
sum[0] += imps2_param[i];
readI2c16(GT_CMD_WR,GT_CFGS_REG+i);
}
sum[0] = (~sum[0])+1;//校验和为补码,看手册
sum[1]=1;
writeI2c16(GT_CMD_WR,GT_CHECK_REG,sum[0]);//写入校验和
writeI2c16(GT_CMD_WR,GT_FRESH_REG,sum[1]);//配置更新标记
msleep(10);
return 0;
}
void TouchScreen::TouchScreenInit()
{
SetGpio(6,3,1,0); //rst init 具体看硬件io口
SetGpio(13,5,1,0); //INT init
//system("himm 0x120F09B4 0x330");
I2C_init(); //好像没用处
goodix_init(); // IIC地址选择
writeI2c16(GT_CMD_WR,GT_CTRL_REG,0x02);//软复位GT911
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0);
u32 id = readI2c16(GT_CMD_WR,GT_CFGS_REG);
if((id & 0xff) < 0x69) //0x69为配置中的首位
{
//更新GT911寄存器配置
goodix_send_cfg();//厂家提供,没有不要乱配,可能导致不能用;
}
writeI2c16(GT_CMD_WR,GT_CTRL_REG,0x00);//结束软复位
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0);//多写几次无所谓
}
(4) 主循环
void TouchScreen::PthreadProc()
{
unsigned int t = 0 ;
int touchStatus = 0;
u8 buf[5];
time_t tim, last_monitor_tim = 0;
memset(&keyInfo,0,sizeof(keyInfo));
while(1) //轮询方式
{
if(0 == (t++)%50)
{
if(touchStatus & 0x80) //&& (((touchStatus & 0xF) > 0) && ((touchStatus & 0xF) < 6)))//数据准备好可读
{
if(touchStatus & 0x0F)//触摸点数大于1
{
for(int i = 0; i < 1; i++){
for(int j = 0; j < 5; j++){
buf[j] = readI2c16(GT_CMD_WR,GT911_TPX_TBL[i]+j);
}
}
if((touchStatus & 0xff) == 0x81) //单击
{
msleep(140);//延时去抖
//do something
}
else if((touchStatus & 0xff) == 0x82) //双击
{
msleep(100);//延时去抖
//do something
}
//逻辑与物理坐标转换
touchPos.s32XPos = (buf[0] + (buf[1] << 8)) * m_TmpWidth / m_phyWidth;
touchPos.s32YPos = (buf[2] + (buf[3] << 8)) * m_TmpHeight / m_phyHeight;
//处理坐标 ...
}
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0x00);//将此标志清零
}
else
{
msleep(150);
}
}
}
}
5.说明
(1) 本文为记录所用,代码仅供参考,错误地方欢迎指正; (2) 主循环可以用轮询或中断方式 (3) 代码中gpio具体看硬件手册
6. 参考
https://blog.csdn.net/qlexcel/article/details/99696108https://www.cnblogs.com/DarkBright/p/10730346.html
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/150685.html原文链接:https://javaforall.cn
边栏推荐
- IPETRONIK数据采集设备携手Softing Q-Vision软件致力于ADAS测试方案
- 企业源代码保密方案分享
- 专业英语历年题
- 思源官方付费同步使用指南
- 【云原生】自助报表和BI能做这么多事?
- Watermaker of the Flink core
- Tencent has confirmed that QQ has stolen numbers on a large scale, iphone14 has no chance of type-C, and 5g, the fourth largest operator, has officially released numbers. Today, more big news is here
- Mathematical principle derivation of structured light phase shift method + multifrequency heterodyne
- flink核心之watermarker
- Wechat authorized login
猜你喜欢
认识启动函数,找到用户入口
Understand leveldb write operation
思源官方付费同步使用指南
电脑无线网络不显示网络列表应该如何解决
ASP.NET CORE Study04
Unity releases webgl and wakes up keyboard input on the mobile terminal inputfield
一款自动生成单元测试的 IDEA 插件,开发效率提升 70% 以上!
1015.摘花生
The paging style flex is set to be displayed at the end (even if the number of pages is longer, there will be no line breaks at the end)
Go language learning notes - Gorm usage - database configuration, table addition | web framework gin (VII)
随机推荐
Unity webgl mobile end removal warning
Why does CAD export PDF have no color
从pdb源码到frame帧对象
JS class is not just a simple syntax sugar!
Après avoir échoué à l'examen d'entrée à l'Université de technologie de Harbin, vous devez rester à l'Université en tant que « chercheur » après avoir obtenu votre diplôme.
Jerry's wif interferes with Bluetooth [chapter]
K3s one click installation script
Jerry's SPI1 plug-in flash recording modification [part]
The Research Report of Analysys' 2022 China Banking privacy computing platform supplier strength matrix analysis' was officially launched
企业源代码保密方案分享
微服务稳定性保障
Performance test-01-introduction
移动Web实训-flex布局测试题1
Matplotlib_Study01
ASP. NET CORE Study03
VSCode 快捷键
BUUCTF:[WUSTCTF2020]朴实无华
ASP. NET CORE Study04
flink核心之watermarker
flex布局中的align-content属性