当前位置:网站首页>Hisilicon 35xx realizes gt911 touch screen function "suggestions collection"
Hisilicon 35xx realizes gt911 touch screen function "suggestions collection"
2022-06-28 13:04:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm your friend, Quan Jun .
Hayes 35xx adopt gpio simulation i2c Realization GT911 Touch function
1. Problems encountered
- The address has been wrong since it was selected , First, check the hardware problems , Then debug the driver part , Print debug from device ack( There is no logic analyzer ); It is found that the register address is always FF or 00, The inspection found that GT911 The addresses are 16bit, While reading and writing i2c Interface is 8 Bit ;
- After success, click the touch panel, and the click position is inconsistent with the actual position ; Coordinate conversion is possible ;
2. Download Online
GT91xx Programming guide file
Capacitive touch chip GT911 Datasheet file 3.Datasheet The key part
(1) gpio Simulation time , You may need to pay attention to this delay time ;
(2) Select the address as 0x28/0x29 or 0xBA/0xBB sequential
4. Part of the code
(1) Partial register definition
#define GT_CMD_WR 0x28 // Write the address
//#define GT_CMD_RD 0x29 // Read command My driver internal logic has handled , Just write the address
//GT91xx Partial register definition
#define GT_CTRL_REG 0X8040 //GT911 Control register
#define GT_CFGS_REG 0X8047 //GT911 Configure the start address register
#define GT_CHECK_REG 0X80FF //GT911 Checksum register
#define GT_FRESH_REG 0X8100 // Configure updated flag
#define GT_PID_REG 0X8140 //GT911 product ID register
#define GT_FIRMVERSION_REG 0x8144 // Firmware version
#define GT_GSTID_REG 0X814E //GT911 Currently detected touch condition
#define GT_TP1_REG 0X8150 // First touch point data address
#define GT_TP2_REG 0X8158 // The data address of the second touch point
#define GT_TP3_REG 0X8160 // The data address of the third touch point
#define GT_TP4_REG 0X8168 // The data address of the fourth touch point
#define GT_TP5_REG 0X8170 // The data address of the fifth touch point
const u32 GT911_TPX_TBL[5]={
GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};(2) To configure GT911 Slave device address 0x28/0x29 or 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);
}
}
// What I chose was 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 Set to input
msleep(60);
return;
}(3) i2c Write interface and drive interface reference
// gpio_i2c2_read 、 gpio_i2c2_write The reference of the driving part is as follows :
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 simulation i2c A little
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); // Just write the address here , It can be handled in other ways ;
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 The drive interfaces corresponding to the operation are as follows :
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;
}
// Reading and writing 16 Interface of bit register ;
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) Touch screen initialization
void TouchScreen::I2C_init()
{
//system("himm 0x120F08E0 0x230"); //SDA Pull up , High speed
//system("himm 0x120F08E4 0x230"); //SCL
SetGpio(12,7,1,1);
SetGpio(12,6,1,1);
}
// Below goodix_send_cfg as follows : I didn't use , I don't know if it's right or not
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
};// Factory initialization sequence
for(int i = 0; i < sizeof(imps2_param); i++)
{
writeI2c16(GT_CMD_WR,GT_CFGS_REG+i,imps2_param[i]);// Write configuration 0x8047~0x8100 common 186 individual
sum[0] += imps2_param[i];
readI2c16(GT_CMD_WR,GT_CFGS_REG+i);
}
sum[0] = (~sum[0])+1;// The checksum is a complement , Read the manual
sum[1]=1;
writeI2c16(GT_CMD_WR,GT_CHECK_REG,sum[0]);// Write checksum
writeI2c16(GT_CMD_WR,GT_FRESH_REG,sum[1]);// Configure update tags
msleep(10);
return 0;
}
void TouchScreen::TouchScreenInit()
{
SetGpio(6,3,1,0); //rst init See the hardware for details io mouth
SetGpio(13,5,1,0); //INT init
//system("himm 0x120F09B4 0x330");
I2C_init(); // Seems useless
goodix_init(); // IIC Address selection
writeI2c16(GT_CMD_WR,GT_CTRL_REG,0x02);// Soft reset GT911
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0);
u32 id = readI2c16(GT_CMD_WR,GT_CFGS_REG);
if((id & 0xff) < 0x69) //0x69 Is the first in the configuration
{
// to update GT911 Register configuration
goodix_send_cfg();// The manufacturer provides , No, don't mix it up , It may not work ;
}
writeI2c16(GT_CMD_WR,GT_CTRL_REG,0x00);// End soft reset
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0);// It doesn't matter if you write more
}(4) Main circulation
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) // Polling mode
{
if(0 == (t++)%50)
{
if(touchStatus & 0x80) //&& (((touchStatus & 0xF) > 0) && ((touchStatus & 0xF) < 6)))// The data is ready to read
{
if(touchStatus & 0x0F)// The number of touch points is greater than 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) // single click
{
msleep(140);// Delay to shake
//do something
}
else if((touchStatus & 0xff) == 0x82) // double-click
{
msleep(100);// Delay to shake
//do something
}
// Logical and physical coordinate conversion
touchPos.s32XPos = (buf[0] + (buf[1] << 8)) * m_TmpWidth / m_phyWidth;
touchPos.s32YPos = (buf[2] + (buf[3] << 8)) * m_TmpHeight / m_phyHeight;
// Processing coordinates ...
}
writeI2c16(GT_CMD_WR,GT_GSTID_REG,0x00);// Clear this flag
}
else
{
msleep(150);
}
}
}
}5. explain
(1) This article is for the record , Code for reference only , Mistakes are welcome to be corrected ; (2) The main loop can be polled or interrupted (3) In the code gpio See the hardware manual for details
6. Reference resources
https://blog.csdn.net/qlexcel/article/details/99696108https://www.cnblogs.com/DarkBright/p/10730346.html
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/150685.html Link to the original text :https://javaforall.cn
边栏推荐
- Deep understanding of Bayes theorem
- The press conference of Tencent cloud Database & CSDN engineer's ability lightweight certification is coming
- Flink流处理API大合集:掌握所有flink流处理技术,看这一篇就够了
- In the past four years, the number of users exceeded 100 million, and sun Ge led the wave field to a new high
- 全志V853芯片 如何在Tina V85x平台切换sensor?
- Customize MySQL connection pool
- Microservice stability guarantee
- 海思35xx实现GT911触摸屏功能「建议收藏」
- pytorch基础
- fastposter v2.8.4 发布 电商海报生成器
猜你喜欢

腾讯确认QQ大规模盗号,iPhone14无缘Type-C,第四大运营商5G正式放号,今日更多大新闻在此...

Vs2012 VC creates a new blank window application
![[cloud native] can self-service reports and Bi do so many things?](/img/80/2b797eb5875dc2b4c2876f2cb3d6f7.png)
[cloud native] can self-service reports and Bi do so many things?

How to find opportunities in a bear market?

Shareit a une force exceptionnelle et se connecte au top 7 de la liste mondiale des forces IAP

1015.摘花生

一文抄 10 篇!韩国发表的顶级会议论文被曝抄袭,第一作者是“原罪”?

【MySQL从入门到精通】【高级篇】(三)MySQL用户的创建_修改_删除以及密码的设置
JS class 并不只是简单的语法糖!

【历史上的今天】6 月 28 日:马斯克诞生;微软推出 Office 365;蔡氏电路的发明者出生
随机推荐
腾讯汤道生:面向数实融合新世界,开发者是最重要的“建筑师”
June 28, 2022 Daily: Lecun's latest paper: the road to autonomous machine intelligence
Scratch travel photo album Electronic Society graphical programming scratch grade examination level 1 true questions and answers analysis June 2022
弹性盒子自动换行小Demo
数启扬帆,智聚人才 | 腾讯云数据库 & CSDN 工程师能力轻量认证发布会重磅来袭!...
K3s one click installation script
How to find opportunities in a bear market?
小白创业做电商,选对商城系统很重要!
ASP. NET CORE Study08
《天天数学》连载53:二月二十二日
Flink stream processing API collection: master all Flink stream processing technologies. Just read this article
async-validator.js數據校驗器
An idea plug-in that automatically generates unit tests, which improves the development efficiency by more than 70%!
认识启动函数,找到用户入口
开源项目维权成功案例: Spug 开源运维平台成功维权
895. 最长上升子序列
The counter attack story of Fu Jie, a young secondary school student: I spent 20 years from the second undergraduate to the ICLR outstanding Thesis Award
FS7022方案系列FS4059A双节两节锂电池串联充电IC和保护IC
Google Earth Engine(GEE)——联合国粮农组织全球有机土壤面积(1992-2018年度)
电子元器件分销10亿俱乐部[通俗易懂]