看了4天的datasheet,昨天终于开始写代码了。到目前为止,我做过的电容屏有 ite的,solomon的,focaltech的,eeti的,还有cypress的。说实话,写这些东西的驱动已是轻车熟路了,但是我今天还是有感而发!ATMEL的电容屏做的是最好的。针对驱动人员的接口做的非常完美,甚至用了面向对象的思想!做atmel的驱动真的是一种享受啊。这时你能体验到做一个驱动工程师的乐趣了!
接手这个工作源于我们公司被一个山寨手机公司给兼了。。。说是合并,其实说奸了也不为过。因为现在那个手机公司的老板说了算。曾经公司给我们的 一些承诺以及福利待遇,自这个山寨公司接手后都一一化为泡影。。。从此我们原班的这些人马就像一个个沦落青楼女子。。。。谁想上就上。。。。
光上上也就罢了。。。谁让咱命苦呢。。。可是上你,也不让你有高潮!,整个一个他上着你,还让你痛苦着。。。
本来是个IC设计公司,,可是现在却要接手一个手机方案的烂摊子。说是两个月后就要上市,说是遇到一些难题解决不了让我们给做。
上周给了我们资料让我做电容屏。
拿到手机后一看,我靠!电容屏报点整个都是偏移的,坐标都和LCD对不准,两指触摸时竟然无法释放其中一个点的触摸坐标。这么明显的bug都没有解决!看看svn的log好像四五个月前就开始做这个驱动了。竟然才做到这种程度。。。。 他们还用svn。。用svn管理android的代码!这足以说明这些人有多懒,为了不学习git竟然把这样的工程用svn来管理。。。。
看了下代码,四个字形容一下,不堪入目! 怎一个烂字了得!可以想象,一群这样的人组成的公司如果离开了FAE的支持就一个字 “死” !!!! 很明显现在把这个烂摊子交给我们就是因为marvel对他们的支持力度不够。。。(他们做到是个marvel的方案)
我已经放弃了去修补这份垃圾一样的驱动。。。
看来哥还是要从写一下驱动啊。。
等哥下周写好了,在把这个笔记完善一下吧!哥要在两周内解决。。。压力还是蛮大的。。。现在做这个驱动完全是哥对atmel的崇拜!如果哥所在的公司就这样一步步被转型为山寨手机公司的话,哥是要尽早考虑出路了。。。nnd
竟然说这个触摸屏每次开机都要校准。。。 真是扯淡!!!! 这是老板说的。。。老板被他的那帮“二刀子”工程师忽悠啊。。。。好残忍啊。。
201202291312:
我打算用中断+轮询的方式来读取报点信息,因此对中断引脚的状态需要读取。自然用了 gpio_get_value这个函数。却发现自始至终读出来的值都是0,郁闷啊。迫不得已我用示波器量了下实际电平,发现一切都是对的,电平有高有低,怎么读取的就不对呢?折腾了一早上,最后发现,gpio_get_value的返回值是整形int 而我却把这个返回值赋值给了一个u8,自然发生了截断,所以总是得到0,这是我的疏忽大意啊。
不过,这个函数是平台相关,有的返回值不是0就是1,这样就算我用u8来存返回值也不会出现问题,然而有的平台上这个函数的返回值可能是gpio相关寄存器的值,这是个32位的值,它会用掩码把其他无关位过滤掉,只留下一个表示value的位,所以就看到这32位中的某一个可能是1其他都是0,如果gpio_get_value返回这样一个32位的int值,那么我们只要根据这个值为0或者非0作出判断即可,如果像我这样把这个值赋值给一个小于32的类型的话,十有八九就要挂了。呵呵。大意了。。
atmel的firmware真好!给驱动提供的是面向对象的接口。这样驱动编程会变得比较方便,而且极大的提高了驱动的可移植性!
另外atmel提供一个8字节的user data 。这样,驱动就能在里面写入一些标志,如此便提高驱动的自适应能力。这关键要看驱动设计者能不能想到怎么用,怎么用的好了!
调触摸屏的时候最好能让设备一开机就自动运行相关的触摸屏测试应用,这样会极大方便调试工作,因为你也不能保证你的驱动上来就能用。以下的这些信息可以帮助我们实现在android中开机不要锁屏。
android 2.3中 如何禁止android开机锁屏:
frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
line:192
external apps(like the phone app) can tell us to disable the keyguard.
private boolean mExternallyEnabled = true //此处改为false即可
如何设置默认的自动锁屏时间
base/packages/SettingsProvider/res/values/defaults.xml
ling21:
def_screen_off_timeout 的默认时间是60000毫秒,即一分钟,改为你要的即可,注意不要越界了。
关于多点上报
kernel对多点上报的操作是按组来的。
见http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
Protocol Example A ------------------ Here is what a minimal event sequence for a two-contact touch would look like for a type A device: ABS_MT_POSITION_X x[0] ABS_MT_POSITION_Y y[0] SYN_MT_REPORT ABS_MT_POSITION_X x[1] ABS_MT_POSITION_Y y[1] SYN_MT_REPORT SYN_REPORT The sequence after moving one of the contacts looks exactly the same; the raw data for all present contacts are sent between every synchronization with SYN_REPORT. Here is the sequence after lifting the first contact: ABS_MT_POSITION_X x[1] ABS_MT_POSITION_Y y[1] SYN_MT_REPORT SYN_REPORT And here is the sequence after lifting the second contact: SYN_MT_REPORT SYN_REPORT If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the last SYN_REPORT will be dropped by the input core, resulting in no zero-contact event reaching userland.
所以如果触摸屏硬件也是按照一组一组来产生数据,即每个package包含本次检测到的所有点,这样便可以轻易的使用上边提到的sync方法。即上报了package中的每一个点后边追加一个syn_mt_report,然后在将本package中的所有点report完了之后,由driver追加一个syn_report来表示本轮上报结束。
但是这个atmel的firmware没有像我们期望的那样将报点分组。而是一个个顺序发送。所以要实现kernel的多点上报要求,便要驱动采用逻辑策略来实现。。。这个真有点儿不太方便。
不过,我已经想好了方法。。等验证好了在写吧。。
发现当通过上面提到的真对多点的上报方式上报两个点后,如果其中一个点释放了,这这时会发现这个点依然在屏幕上显示。并且只在下一次report完成后才消失。解决的办法就是把其中一个点释放的事件report后再把所有的事件report一次即可。这样就实现了,上次报n个点,这次报n-1个点。
201203120138
很悲剧,他们在量产在即的时候不知是什么原因却把这个电容屏的驱动给换了,换了后多点触摸都失效了,就剩一个单点了。但是就是这样的东西也被他们提交到了服务器。我对这个山寨公司越发的怀疑了。一周前我重写的驱动就已经完成了,考虑到他们马上要生产,我便没有提交我的代码,因为更换一个驱动后需要进行详细的长周期的测试才能确定一个驱动是否有潜在的问题。但是我怎么也没有想到在剩下十来天的时候,他们竟然更换了驱动,而且貌似都没有做什么测试就发布到中心服务器了。这或许是个迷。。。。。不过,和哥没关系。。
还好,我昨天已经把那个新驱动引发的多点失效问题解决了。说句实话,那个bug很低级。。。。。。
个人认为一个好的驱动工程师会花一周的时间研究datasheet,然后再花一周的时间去写代码。我做到了。但是很累。为这样的公司做这样的工作。真的不值得。