微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动-触摸屏驱动分析

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触摸屏驱动的分析

  1. //#defineCONFIG_TOUCHSCREEN_S3C2410_DEBUG
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12. #include
  13. #include
  14. #include
  15. #include
  16. #include
  17. #defineTRUE1//CoAsiaadded
  18. #defineFALSE0//CoAsiaadded
  19. #defineFILTER_LIMIT25//CoAsiaadded
  20. /*Forts.dev.id.version*/
  21. #defineS3C2410TSVERSION0x0101
  22. #defineTSC_SLEEP(S3C2410_ADCTSC_PULL_UP_DISABLE|S3C2410_ADCTSC_XY_PST(0))
  23. #defineWAIT4INT(x)(((x)<8)|\
  24. S3C2410_ADCTSC_YM_SEN|S3C2410_ADCTSC_YP_SEN|S3C2410_ADCTSC_XP_SEN|\
  25. S3C2410_ADCTSC_XY_PST(3))
  26. #defineAUTOPST(S3C2410_ADCTSC_YM_SEN|S3C2410_ADCTSC_YP_SEN|S3C2410_ADCTSC_XP_SEN|\
  27. S3C2410_ADCTSC_AUTO_PST|S3C2410_ADCTSC_XY_PST(0))
  28. #defineDEBUG_LVL"<3>"//KERN_DEBUG
  29. staticchar*s3c2440ts_name="s3c2440TouchScreen";
  30. /*
  31. *Per-touchscreendata.
  32. */
  33. //定义s3c2440触摸屏使用的数据结构体
  34. structs3c2440ts{
  35. structinput_dev*dev;
  36. longxp;
  37. longyp;
  38. intcount;
  39. intshift;
  40. };
  41. staticstructs3c2440tsts;
  42. staticstructclk*adc_clock;
  43. //__iomem声明地址空间是设备地址映射空间
  44. staticvoid__iomem*base_addr;
  45. //函数声明
  46. staticvoidtouch_timer_fire(unsignedlongdata);
  47. staticirqreturn_ttc_irq(intirq,void*dev_id);
  48. staticirqreturn_tadc_irq(intirq,void*dev_id);
  49. staticint__inits3c2440ts_probe(structplatform_device*pdev);
  50. staticints3c2440ts_remove(structplatform_device*pdev);
  51. staticints3c2440ts_resume(structplatform_device*pdev);
  52. //定义定时器
  53. staticstructtimer_listtouch_timer=
  54. TIMER_INITIALIZER(touch_timer_fire,0,0);
  55. //IRQ_TC中断处理函数
  56. staticirqreturn_ttc_irq(intirq,void*dev_id)
  57. {
  58. //data0,data1用于存放读取的ADCDAT数据寄存器的值
  59. unsignedlongdata0;
  60. unsignedlongdata1;
  61. intupdown;//用于存放光标的按下或提起的状态
  62. //读取ADCDAT0、ADCDAT1数据寄存器的值
  63. data0=readl(base_addr+S3C2410_ADCDAT0);
  64. data1=readl(base_addr+S3C2410_ADCDAT1);
  65. //查看数据寄存器的第15位的值
  66. updown=(!(data0&S3C2410_ADCDAT0_UPDOWN))&&(!(data1&S3C2410_ADCDAT0_UPDOWN));
  67. /*TODOweshouldnevergetaninterruptwithupdownsetwhile
  68. *thetimerisrunning,butmaybeweoughttoverifythatthe
  69. *timerisntrunninganyways.*/
  70. //如果data0和data1的第15位都是0,则updown为1,则通过函数touch_timer_fire()函数来启动ADC转换
  71. if(updown)
  72. touch_timer_fire(0);
  73. returnIRQ_HANDLED;
  74. }
  75. staticvoidtouch_timer_fire(unsignedlongdata)
  76. {
  77. //用于存储数据寄存器ADCDAT0、ADCDAT1的值
  78. unsignedlongdata0;
  79. unsignedlongdata1;
  80. //用于存放光标是否被按下
  81. intupdown;
  82. data0=readl(base_addr+S3C2410_ADCDAT0);
  83. data1=readl(base_addr+S3C2410_ADCDAT1);
  84. updown=(!(data0&S3C2410_ADCDAT0_UPDOWN))&&(!(data1&S3C2410_ADCDAT0_UPDOWN));
  85. //printk("Thenumberofupdownis%d\n",updown);
  86. //如果光标被按下,执行
  87. if(updown)
  88. {
  89. //ts.count!=0表示ADC已经转换过,下面就报告事件和光标位置数据
  90. if(ts.count!=0)
  91. {
  92. ts.xp>>=ts.shift;//这里shift为2,这里实际上是求均值,四次的和/4,这样定位更加准确
  93. ts.yp>>=ts.shift;
  94. #ifdefCONFIG_TOUCHSCREEN_S3C2410_DEBUG
  95. {
  96. structtimevaltv;
  97. do_gettimeofday(&tv);
  98. printk(DEBUG_LVL"T:%06d,X:%03ld,Y:%03ld\n",(int)tv.tv_usec,ts.xp,ts.yp);
  99. }
  100. #endif
  101. /*
  102. 下面的函数位于/inc

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top