当前位置:首页 » 《关注互联网》 » 正文

Android Touch_95XX data sheet解析_couch_potato1的博客

21 人参与  2021年08月28日 07:43  分类 : 《关注互联网》  评论

点击全文阅读


 一.IIC总线简介。

1.IIC总线是Philips公司在八十年代初推出的一种串行、半双工总线主要用于近距离、低速的芯片之间的通信;IIC总线有两根双向的信号线,一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步;IIC总线硬件结构简单,成本较低,因此在各个领域得到了广泛应用。

IIC总线是Philips公司在八十年代初推出的一种串行、半双工总线

   IIC总线是以中国多主机总线,链接在IIC总线上的期间分为主机和从机,主机有权法医和结束一次通信,而从机只能被主机呼叫;当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误产生;每个连接到IIC总线上的期间都有一个唯一的地址(7bit),且每个器件都可以作为主机,也可以作为从机(同一时刻只能有一个主机),总线上的器件增加和删除不影响其他器件正常工作;IIC总线在通信上发送数据的器件为发送器,接收数据的器件为接收器。

 二.IIC总线通信过程

1.主机发送起始信号启用总线。

2.主机发送一个字节的数据指明从机地址和后续字节的传输方向。

3.被寻址的从机发送应答信号回应主机。

4.发送器发送一个字节的数据。

5.接收器发送应答信号回应发送器。

以此循环4.5步骤进行数据传输。

n.通信完成后主机发送停止信号释放总线。

三.IIC总线寻址方式

1.IIC上传输的数据是广义的,即包括地址,也包括真正的数据。

2.主机在发送启示信号后必须先发送一个字节的数据,该数据的高7位为从机地址,最低位表示后续字节的传输方向,其中'0'表示主机发送数据,'1'表示主机接收数据;总线上所有从机接收到该字节数据后都将这7位地址与自己的地址相比较,如果相同,则认为自己被主机寻址,然后在根据第8位将自己设定为接收器或发送器。

 3.IIC的启示信号和结束信号。

    SCL为高电平时,SDA由高变低表示启示信号。

    SCL为高电平时,SDA由低变高表示停止信号。

    起始信号和停止信号都是由主机发送,起始信号产生后总线处于占用状态,停止信号产生后总   线处于空闲状态。

 4.IIC从机应答。

 5.信号同步。

    在时钟线SCL为低电平时期,允许SDA上高低电平变化,时钟线为高电平时期,接收器从数据线上读取一位数据,在此期间SDA上的电平不允许发生变化,必须保持稳定。

6.典型的IIC时序。

    主机向从机发送数据。

    从机向主机发送数据

阴影部分表示主机向从机发送数据,无阴影部分表示数据从从机发送给主机;A表明应答A非表示非应答,S为启示信号,P为终止信号。 

 四。SIS_92XX data sheet芯片手册。

    读到这里的朋友是不是觉得偏离了主题?其实并不是,芯片SIS_95XX与CPU进行通讯的方式其实是采用的IIC,下面我们开始对应代码来解释SIS_95XX的通讯。

这是芯片手册给出的IIC通讯过程,我们可以看到从机(slave)的地址为0x5C。后续在开发过程中添加device tree时需要添加从机地址,从而内核启动时自动解析设备树。

1.Touch Package Format数据包格式:

当然看数据包并不能看懂其中缘由,下面就具体介绍数据包内容分别包含了什么内容。

     根据上述描述,数据包的内容基于Report ID。如果触点少于或等于5个,那么第二个包数据会全部置于0,那么我们这里会有一个疑问,如果有效触点小于5个,我们就可以不用读取第二个数据包,那么怎么判断是否触点有多少个呢?其实答案早已给出,在下面紧接着描述了第一个数据包的Touch CNT它代表这有几个touch data。到这里我们就可以看出程序在读取第一步时用do,while结构会更合理,效率执行更高。至于代码的执行效率为什么do while结构会更高,大家有兴趣可以查找高效C的使用,我们在本片文章就不多叙述了。

    从这里我们可以看到Report ID低四位触摸种类,高四位则是每个触点中包含了什么数据。

    这里是对每一个触点内包含的内容格式,其中state注解为该点的状态,如果是life point则需要去对report ID的高四位进行判断,从而读出具体的触点信息。

    这里我就着这张图来解答具体怎么去解析数据包中的信息。

    首先我们上文提到如果考虑C执行效率问题,我们选用了do,while结构。这里需要注意下,一个包为64个字节。

	do {
    ****************************************************
	} while (tmpbuf[P_REPORT_ID] != ALL_IN_ONE_PACKAGE &&
			tmpbuf[p_count] > 5);

     根据上图中ALL_IN_ONE_PACKAGE其实就是代表General I2C Touch的数据格式0x10,和我们之前讲到的Touch CNT来联合判断是否需要读取第二个包数据。这里我们讲解完,接下来我们看一下如何向I2C发送数据和通讯。

    内核中参照代码:

int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
{
	int ret;
	struct i2c_adapter *adap = client->adapter;
	struct i2c_msg msg;

	msg.addr = client->addr;
	msg.flags = client->flags & I2C_M_TEN;
	msg.len = count;
	msg.buf = (char *)buf;

	ret = i2c_transfer(adap, &msg, 1);

	/*
	 * If everything went ok (i.e. 1 msg transmitted), return #bytes
	 * transmitted, else error code.
	 */
	return (ret == 1) ? count : ret;
}

    根据内核已有的代码,我们可以仿照此代码的格式来自己写一个类似的代码:

static int sis_command_for_read(struct i2c_client *client, int rlength,
							unsigned char *rdata)
{
	int ret = SIS_ERR;
	struct i2c_msg msg[1];

	msg[0].addr = client->addr;
	msg[0].flags = I2C_M_RD;/*Read*/
	msg[0].len = rlength;
	msg[0].buf = rdata;
	ret = i2c_transfer(client->adapter, msg, 1);

	return ret;
}

    同样我们给出write的代码:

static int sis_command_for_write(struct i2c_client *client, int wlength,
							unsigned char *wdata)
{
	int ret = SIS_ERR;
	struct i2c_msg msg[1];

	msg[0].addr = client->addr;
	msg[0].flags = 0;/*Write*/
	msg[0].len = wlength;
	msg[0].buf = (unsigned char *)wdata;
	ret = i2c_transfer(client->adapter, msg, 1);

	return ret;
}

     到这里我们对整体的芯片手册基本都有了大概的了解。TP模块基本的框架就是通过IIC子系统去读写从机的数据,然后对具体数据进行解析来通过input子系统来给应用层上报具体事件。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

主要用于近距离、低速的芯片之间的通信;IIC总线有两根双向的信号线一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步;IIC总线硬件结构简单,成本较低,因此在各个领域得到了广泛的应用


点击全文阅读


本文链接:http://zhangshiyu.com/post/26391.html

总线  数据  主机  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1