tq2416触摸驱动问题的终极解决方法
此问题可能是我自己的问题而不是厂商提供的源码问题,但是网上很多人在问,既然解决了我就分享一下自己的方法。
具体表现是设备老化一段时间后发现可能小概率出现触摸挂掉,快速连点几分钟可以加速此bug的重现。
半成品解决方法如下:
http://www.armbbs.net/forum.php?mod=viewthread&tid=14621
移植2440驱动过去,实测一周时间,确实解决触摸屏问题,但是此时的ADC驱动是没法用到采样上去,2440和2416的寄存器定义有区别。
继续修改ADC驱动
EmbedSky_adc.c中:
#define ADC_INPUT(x) ((x) << 3)
#define START_ADC_AIN(ch, prescale)
do{ ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ;
ADCCON |= ADC_START;
}while(0)
此处看出设置ADC通道是操作了ADCCON的第3位。
2440寄存器定义如下:
2416定义:
由于2416是10bit的ADC,所以修改:
#define ADC_INPUT(x) ((x) << 3)
改为
#define ADC_INPUT(x) ((0) << 3)
设置为10bit
继续看2416手册,设置通道的ADCMUX寄存器
所以代码中添加:
//channel select
#define ADCMUX (*(volatile unsigned long *)(base_addr + 0x18))
然后:
#define START_ADC_AIN(ch, prescale)
do{ ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ;
ADCCON |= ADC_START;
}while(0)
改为:
#define START_ADC_AIN(ch, prescale)
do{ ADCMUX=(ch); ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((0)) ;
ADCCON |= ADC_START;
}while(0)
继续看tq2440_adc_read内:
开始、结束转换时并没有保存、恢复寄存器的值,会导致AD采样后,触摸挂掉,因为ADC寄存器的值被改变了。
在**START_ADC_AIN(adcdev.channel, adcdev.prescale);**前添加:
s3c_adctsc_save();//保存寄存器
在adc_data = ADCDAT0 & 0x3ff;//取得模数转换数值后添加:
s3c_adctsc_restore();//恢复寄存器
2个函数如下:
static unsigned int adctsc = 0;
static int ADCCON_VALUE = 0;
static inline void s3c_adctsc_save(void) {
adctsc = ADCTSC;
ADCCON_VALUE=ADCCON;
}
static inline void s3c_adctsc_restore(void) {
ADCTSC = adctsc;
ADCCON=ADCCON_VALUE;
}
然后编译、烧录,目测完美运行。
最后说一点:
ADCTSC这个寄存器的赋值我全删掉了,因为我没有用到触摸那几个AD通道
在__init dev_init中:
ADCTSC = 0;我是删掉了的,read内的也删掉了。2440源码是在read内将寄存器设置为normal adc,而这个设置是将触摸的通道设置为普通AD,既然用到了触摸,就没必要修改了。
很久没做过linux了,如果哪里写得有问题欢迎提出来探讨。