博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
触摸屏驱动分析和编程
阅读量:4459 次
发布时间:2019-06-08

本文共 5217 字,大约阅读时间需要 17 分钟。

一、触摸屏驱动分析
  1. static int __init tq2440ts_init(void)
  2. {
  3.     struct input_dev *input_dev;
  4.     adc_clock = clk_get(NULL, "adc");
  5.     if (!adc_clock)
  6.     {
  7.         printk(KERN_ERR "failed to get adc clock source\n");
  8.         return -ENOENT;
  9.     }
  10.     clk_enable(adc_clock);                                                          //使能ADC时钟
  11.     base_addr=ioremap(S3C2410_PA_ADC,0x20);                                         //将物理基地址转化成虚拟地址
  12.     if (base_addr == NULL)
  13.     {
  14.         printk(KERN_ERR "Failed to remap register block\n");
  15.         return -ENOMEM;
  16.     }
  17.     /* Configure GPIOs */
  18. //    tq2440_ts_connect();
  19.     iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),base_addr+S3C2410_ADCCON);            //设置寄存器
  20.     iowrite32(0xffff, base_addr+S3C2410_ADCDLY);
  21.     iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
  22.     /* Initialise input stuff */
  23.     input_dev = input_allocate_device();                                                //分配输入设备
  24.     if (!input_dev)
  25.     {
  26.         printk(KERN_ERR "Unable to allocate the input device !!\n");
  27.         return -ENOMEM;
  28.     }
  29.     dev = input_dev;
  30.     dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);                             //设置可能的上报事件(同步信息)(按键信息)(abs是坐标)
  31.     dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] = BIT(BTN_TOUCH);
  32.     input_set_abs_params(dev, ABS_X, 0, 0x3FF, 0, 0);
  33.     input_set_abs_params(dev, ABS_Y, 0, 0x3FF, 0, 0);
  34.     input_set_abs_params(dev, ABS_PRESSURE, 0, 1, 0, 0);
  35.     dev->name = tq2440ts_name;                                                           //填充一些设备信息
  36.     dev->id.bustype = BUS_RS232;
  37.     dev->id.vendor = 0xDEAD;
  38.     dev->id.product = 0xBEEF;
  39.     dev->id.version = S3C2410TSVERSION;
  40.     if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM, tq2440ts_name, dev))                      //注册ADC中断处理程序
  41.     {
  42.         printk(KERN_ERR "tq2440_ts.c: Could not allocate ts IRQ_ADC !\n");
  43.         iounmap(base_addr);
  44.         return -EIO;
  45.     }
  46.     if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, tq2440ts_name, dev))                                   //注册TOUCH_SCREEN中断
  47.     {
  48.         printk(KERN_ERR "tq2440_ts.c: Could not allocate ts IRQ_ADC !\n");
  49.         iounmap(base_addr);
  50.         return -EIO;
  51.     }
  52.     printk(KERN_INFO "%s successfully loaded\n", tq2440ts_name);
  53.     input_register_device(dev);                                                                     //注册输入型设备
  54.     return 0;
  55. }
在手按下触摸屏时,会触发TC中断,stylus_updown:
  1. static irqreturn_t stylus_updown(int irq, void *dev_id)
  2. {
  3.     unsigned long data0;
  4.     unsigned long data1;
  5.     int updown;
  6.     if (down_trylock(&ADC_LOCK) == 0)                                                                               //通过锁保护起来
  7.     {
  8.         OwnADC = 1;
  9.         data0 = ioread32(base_addr+S3C2410_ADCDAT0);                                                                //读取寄存器
  10.         data1 = ioread32(base_addr+S3C2410_ADCDAT1);
  11.         updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));                         //判断按下还是弹起
  12.         if (updown)                                                                                     //按下
  13.         {
  14.             touch_timer_fire(0);                                                                        //采样
  15.         }
  16.         else
  17.         {
  18.             OwnADC = 0;
  19.             up(&ADC_LOCK);                                                                               //释放锁
  20.         }
  21.     }
  22.     return IRQ_HANDLED;
  23. }
touch_timer_fire():
  1. static void touch_timer_fire(unsigned long data)
  2. {
  3.       unsigned long data0;
  4.       unsigned long data1;
  5.     int updown;
  6.       data0 = ioread32(base_addr+S3C2410_ADCDAT0);
  7.       data1 = ioread32(base_addr+S3C2410_ADCDAT1);
  8.      updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
  9.      if (updown) {
  10.          if (count != 0)                                                                                                               //如果count不是0,4次AD转换后进入
  11.          {
  12.             long tmp;
  13.                                                                                                  
  14.             tmp = xp;
  15.             xp = yp;
  16.             yp = tmp;
  17.                                                                                                  
  18.                         xp >>= 2;                                                                                                       //这是取平均值
  19.                         yp >>= 2;
  20.              input_report_abs(dev, ABS_X, xp);                                                                                          //可以上报XY坐标了
  21.              input_report_abs(dev, ABS_Y, yp);
  22.              input_report_key(dev, BTN_TOUCH, 1);                                                                                       //上报按键
  23.              input_report_abs(dev, ABS_PRESSURE, 1);                                                                                    //上报ABS按下
  24.              input_sync(dev);                                                                                                           //上报结束
  25.          }
  26.          xp = 0;
  27.          yp = 0;
  28.          count = 0;
  29.          iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);                                                  //启动xy转换
  30.          iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
  31.      }
  32.      else
  33.      {
  34.          count = 0;
  35.          input_report_key(dev, BTN_TOUCH, 0);
  36.          input_report_abs(dev, ABS_PRESSURE, 0);
  37.          input_sync(dev);
  38.          iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
  39.         if (OwnADC)
  40.         {
  41.             OwnADC = 0;
  42.             up(&ADC_LOCK);
  43.         }
  44.      }
  45. }
调用adc中断(stylus_action):
  1. static irqreturn_t stylus_action(int irq, void *dev_id)
  2. {
  3.     unsigned long data0;
  4.     unsigned long data1;
  5.     if (OwnADC)
  6.     {
  7.         data0 = ioread32(base_addr+S3C2410_ADCDAT0);
  8.         data1 = ioread32(base_addr+S3C2410_ADCDAT1);
  9.         xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;                                                     //获取X、Y坐标
  10.         yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
  11.         count++;
  12.         if (count < (1<<2))                                                                            //count<4,意味着获取了4次
  13.         {
  14.             iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
  15.             iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
  16.         }
  17.         else
  18.         {
  19.             mod_timer(&touch_timer, jiffies+1);                                                          //启动内核定时器,1个时间就调用touch_timer
  20.             iowrite32(WAIT4INT(1), base_addr+S3C2410_ADCTSC);
  21.         }
  22.     }
  23.     return IRQ_HANDLED;
  24. }
touch_timer:
  1. static struct timer_list touch_timer =
  2.         TIMER_INITIALIZER(touch_timer_fire, 0, 0);                                       //又调用了touch_timer_fire,不过此时count是4了
二、触摸屏驱动编程
  1. static void touch_timer_fire(unsigned long data)
  2. {
  3.       unsigned long data0;
  4.       unsigned long data1;
  5.     int updown;
  6.       data0 = ioread32(base_addr+S3C2410_ADCDAT0);
  7.       data1 = ioread32(base_addr+S3C2410_ADCDAT1);
  8.      updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
  9.      if (updown) {
  10.             if(count != 0)
  11.             {
  12.                 long tmp;
  13.                 /*交换XY坐标*/
  14.                 tmp = xp;
  15.                 xp = yp;
  16.                 yp = tmp;
  17.                 /*除以4*/
  18.                 xp >>= 2;
  19.                 yp >>= 2;
  20.                 /*上报XY坐标*/
  21.                 input_report_abs(dev, ABS_X, xp);
  22.                 input_report_abs(dev, ABS_Y, yp);
  23.                 
  24.                 input_report_key(dev, BTN_TOUCH, 1);
  25.                 input_report_abs(dev, ABS_PRESSURE, 1);
  26.                 input_sync(dev);
  27.                  
  28.                 printk("x=%d,y=%d\n",xp,yp);
  29.             }
  30.             
  31.             xp = 0;
  32.             yp = 0;
  33.             count = 0;
  34.             /*1.启动自动转换*/
  35.             iowrite32(1<<2, base_addr+S3C2410_ADCTSC);
  36.             iowrite32((ioread32(base_addr+S3C2410_ADCCON)|1<<0), base_addr+S3C2410_ADCCON);
  37.      }
  38.      else
  39.      {
  40.          count = 0;
  41.          input_report_key(dev, BTN_TOUCH, 0);
  42.          input_report_abs(dev, ABS_PRESSURE, 0);
  43.          input_sync(dev);
  44.          iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
  45.         if (OwnADC)
  46.         {
  47.             OwnADC = 0;
  48.             up(&ADC_LOCK);
  49.         }
  50.      }
  51. }

转载于:https://www.cnblogs.com/ch122633/p/7363299.html

你可能感兴趣的文章
bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
查看>>
NPOI新建和读取EXCEL
查看>>
【Spark】开发Spark选择Java还是Scala?
查看>>
【转载】String和StringBuffer的区别,以及StringBuffer的常用方法介绍
查看>>
下拉框选择效果的实现原理2
查看>>
第五周作业结对编程作业
查看>>
mysql tp5 find_in_set写法
查看>>
k8s service
查看>>
搭建redis的步骤
查看>>
eclipse插件集
查看>>
SQL练习之求解填字游戏
查看>>
2017年11月15日
查看>>
codeforces 949B A Leapfrog in the Array
查看>>
类似懒加载的js功能
查看>>
Mysql的DATE_FORMAT()日期格式转换
查看>>
vue实战教程
查看>>
使用disruptor 将5百多万数据从mysql导入到oracle
查看>>
HDU1028 Ignatius and the Princess III 求一个整数被分为多个数相加有多少种可能
查看>>
团队怎样去做技术规划
查看>>
m_Orchestrate learning system---网站的语言选择功能(中文英文)
查看>>