ARM-Linux驱动-触摸屏驱动分析
时间:11-20
来源:互联网
点击:
硬件平台:FL2440
内核版本:2.6.28
主机平台:Ubuntu 11.04
内核版本:2.6.39
1、下面是ADC和触摸屏接口的模块图
当触摸屏接口使用时,XM或YM接触摸屏接口的地
当触摸屏接口不使用时,XM或YM接模拟信号,做普通ADC使用。
2、触摸屏接口的几种操作模式
(1) 正常转换模式
通过设置ADCCON(adc控制寄存器)来完成初始化,并对ADCDAT0数据寄存器进行操作。
(2) 分离XY坐标模式
X坐标模式写X坐标转换数据到ADCDAT0,触摸屏接口产生中断到中断控制寄存器。Y坐标模式写Y坐标转换数据到ADCDAT1,触摸屏接口产生中断到中断控制寄存器。两种模
式可以选择一种模式工作。
相应的引脚连接:
(3) 自动XY坐标模式
触摸屏控制器连续的转换X和Y的坐标,在X坐标转换后的值存入ADCDAT0后,自动将Y坐标转换后的值存入ADCDAT1,触摸屏接口产生中断到中断控制器。
相应的引脚连接:
(4) 等待中断模式
当光标被按下,触摸屏控制器产生中断IRQ_TC,当产生中断信号时,等待中断模式必须被清除。
引脚定义如下:
3、下面是s3c2440触摸屏驱动的分析
- //#defineCONFIG_TOUCHSCREEN_S3C2410_DEBUG
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #defineTRUE1//CoAsiaadded
- #defineFALSE0//CoAsiaadded
- #defineFILTER_LIMIT25//CoAsiaadded
- /*Forts.dev.id.version*/
- #defineS3C2410TSVERSION0x0101
- #defineTSC_SLEEP(S3C2410_ADCTSC_PULL_UP_DISABLE|S3C2410_ADCTSC_XY_PST(0))
- #defineWAIT4INT(x)(((x)<8)|\
- S3C2410_ADCTSC_YM_SEN|S3C2410_ADCTSC_YP_SEN|S3C2410_ADCTSC_XP_SEN|\
- S3C2410_ADCTSC_XY_PST(3))
- #defineAUTOPST(S3C2410_ADCTSC_YM_SEN|S3C2410_ADCTSC_YP_SEN|S3C2410_ADCTSC_XP_SEN|\
- S3C2410_ADCTSC_AUTO_PST|S3C2410_ADCTSC_XY_PST(0))
- #defineDEBUG_LVL"<3>"//KERN_DEBUG
- staticchar*s3c2440ts_name="s3c2440TouchScreen";
- /*
- *Per-touchscreendata.
- */
- //定义s3c2440触摸屏使用的数据结构体
- structs3c2440ts{
- structinput_dev*dev;
- longxp;
- longyp;
- intcount;
- intshift;
- };
- staticstructs3c2440tsts;
- staticstructclk*adc_clock;
- //__iomem声明地址空间是设备地址映射空间
- staticvoid__iomem*base_addr;
- //函数声明
- staticvoidtouch_timer_fire(unsignedlongdata);
- staticirqreturn_ttc_irq(intirq,void*dev_id);
- staticirqreturn_tadc_irq(intirq,void*dev_id);
- staticint__inits3c2440ts_probe(structplatform_device*pdev);
- staticints3c2440ts_remove(structplatform_device*pdev);
- staticints3c2440ts_resume(structplatform_device*pdev);
- //定义定时器
- staticstructtimer_listtouch_timer=
- TIMER_INITIALIZER(touch_timer_fire,0,0);
- //IRQ_TC中断处理函数
- staticirqreturn_ttc_irq(intirq,void*dev_id)
- {
- //data0,data1用于存放读取的ADCDAT数据寄存器的值
- unsignedlongdata0;
- unsignedlongdata1;
- intupdown;//用于存放光标的按下或提起的状态
- //读取ADCDAT0、ADCDAT1数据寄存器的值
- data0=readl(base_addr+S3C2410_ADCDAT0);
- data1=readl(base_addr+S3C2410_ADCDAT1);
- //查看数据寄存器的第15位的值
- updown=(!(data0&S3C2410_ADCDAT0_UPDOWN))&&(!(data1&S3C2410_ADCDAT0_UPDOWN));
- /*TODOweshouldnevergetaninterruptwithupdownsetwhile
- *thetimerisrunning,butmaybeweoughttoverifythatthe
- *timerisntrunninganyways.*/
- //如果data0和data1的第15位都是0,则updown为1,则通过函数touch_timer_fire()函数来启动ADC转换
- if(updown)
- touch_timer_fire(0);
- returnIRQ_HANDLED;
- }
- staticvoidtouch_timer_fire(unsignedlongdata)
- {
- //用于存储数据寄存器ADCDAT0、ADCDAT1的值
- unsignedlongdata0;
- unsignedlongdata1;
- //用于存放光标是否被按下
- intupdown;
- data0=readl(base_addr+S3C2410_ADCDAT0);
- data1=readl(base_addr+S3C2410_ADCDAT1);
- updown=(!(data0&S3C2410_ADCDAT0_UPDOWN))&&(!(data1&S3C2410_ADCDAT0_UPDOWN));
- //printk("Thenumberofupdownis%d\n",updown);
- //如果光标被按下,执行
- if(updown)
- {
- //ts.count!=0表示ADC已经转换过,下面就报告事件和光标位置数据
- if(ts.count!=0)
- {
- ts.xp>>=ts.shift;//这里shift为2,这里实际上是求均值,四次的和/4,这样定位更加准确
- ts.yp>>=ts.shift;
- #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
- {
- structtimevaltv;
- do_gettimeofday(&tv);
- printk(DEBUG_LVL"T:%06d,X:%03ld,Y:%03ld\n",(int)tv.tv_usec,ts.xp,ts.yp);
- }
- #endif
- /*
- 下面的函数位于/inc
ARMLinux驱动触摸屏驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)