基于mini2440触摸屏驱动

发布时间:2024-06-28  

驱动路径:drivers/input/touchscreen/s3c2410_ts.c

在static int __init s3c2410ts_init(void)函数中注册了两个中断

1.if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
  "s3c2410_action", dev))

2.if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
   "s3c2410_action", dev))

中断处理函数stylus_action和stylus_updown。当点击触摸屏时进入该函数,在该函数中启动ad转换,转换完成就触发中断进入stylus_action在stylus_action中读取数据。

首先来看一下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.   

  7.     if (down_trylock(&ADC_LOCK) == 0) {      //判断是否adc可用,down_trylock可以用来获取信号量,不会休眠   

  8.         OwnADC = 1;   

  9.         data0 = ioread32(base_addr+S3C2410_ADCDAT0);   

  10.         data1 = ioread32(base_addr+S3C2410_ADCDAT1);   

  11.   

  12.         updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));   

  13.   

  14.         if (updown) {   //判断触摸屏是否按下   

  15.             touch_timer_fire(0);  //启动adc   

  16.         } else {   

  17.             OwnADC = 0;   

  18.             up(&ADC_LOCK);   

  19.         }   

  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.   

  7.     data0 = ioread32(base_addr+S3C2410_ADCDAT0);   

  8.     data1 = ioread32(base_addr+S3C2410_ADCDAT1);   

  9.   

  10.     updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));   

  11.   

  12.     if (updown) {  //判断现在是否还按下   

  13.         if (count != 0) {   //采样完成,count的值我下面会讲解   

  14.             long tmp;   

  15.                                                                                         //应为是240×320,需要x,y调换一下            

  16.             tmp = xp;   

  17.             xp = yp;   

  18.             yp = tmp;   

  19.                                                                                  //在stylus_action中取得是连续四次采样的结果需要处以4                   

  20.                         xp >>= 2;   

  21.                         yp >>= 2;   

  22.   

  23.             input_report_abs(dev, ABS_X, xp); //x,y坐标报告   

  24.             input_report_abs(dev, ABS_Y, yp);   

  25.   

  26.             input_report_key(dev, BTN_TOUCH, 1);   

  27.             input_report_abs(dev, ABS_PRESSURE, 1);   

  28.             input_sync(dev);  //同步   

  29.         }   

  30.   

  31.         xp = 0;   //否则开始采用   

  32.         yp = 0;   

  33.         count = 0;   

  34.   

  35.         iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);   

  36.         iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);   

  37.     } else {   //是否抬起   

  38.         count = 0;   

  39.   

  40.         input_report_key(dev, BTN_TOUCH, 0);   

  41.         input_report_abs(dev, ABS_PRESSURE, 0);   

  42.         input_sync(dev);   

  43.   

  44.         iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);   

  45.         if (OwnADC) {   

  46.             OwnADC = 0;   

  47.             up(&ADC_LOCK);   

  48.         }   

  49.     }   

  50. }  


注意:当第一次按下时,count==0,启动ad,当转换完成将触发中断,进入stylus_action中断处理函数,好家伙来看一下哦

  1. static irqreturn_t stylus_action(int irq, void *dev_id)   

  2. {   

  3.     unsigned long data0;   

  4.     unsigned long data1;   

  5.   

  6.     if (OwnADC) {   

  7.         data0 = ioread32(base_addr+S3C2410_ADCDAT0);   

  8.         data1 = ioread32(base_addr+S3C2410_ADCDAT1);   

  9.   

  10.         xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;   

  11.         yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;   

  12.         count++;   

  13.   

  14.         if (count < (1<<2)) {  //如果小于4,继续启动adc   

  15.             iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);   

  16.             iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);   

  17.         } else {  //已经采样了4次,等待1ms后调用touch_timer函数。   

  18.             mod_timer(&touch_timer, jiffies+1);   

  19.             iowrite32(WAIT4INT(1), base_addr+S3C2410_ADCTSC);   

  20.         }   

  21.     }   

  22.   

  23.     return IRQ_HANDLED;   

  24. }  


接下来就得看一下touch_timer在忙些什么请看招。。。。。。。。。。。

static struct timer_list touch_timer =
  TIMER_INITIALIZER(touch_timer_fire, 0, 0); 重新初始化


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>