⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410-ts.c

📁 本程序为基于创维特触摸屏及相应测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/drivers/char/s3c2410_ts.c * *  Copyright (C) 2002  SAMSUNG ELECTRONICS SW.LEE <hitchcar@sec.samsung.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ /* * Using the hareware timer1 instead of software timer (struct timer_list) * raw device not implemented * calibration not implemented */#include <linux/module.h>#include <linux/types.h>#include <linux/wait.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/poll.h>#include <linux/miscdevice.h>#include <linux/init.h>#include <linux/compiler.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/hardware.h>#include "s3c2410-ts.h"#include <asm/arch/S3C2410.h>#include <asm/arch/cpu_s3c2410.h>/* * TSBUF_SIZE must be a power of two */#define S3C2410_TS_MINOR	0#define H3600_TS_MODULE_NAME    "ts"#define INCBUF(x,mod)          (((x)+1) & ((mod) - 1))#define MOUSEBUF_SIZE           32#define DOWN_PRESS              1#define UP_PRESS                0#define NO_PRESS                0#define TS_FILTER_LENGTH        8#define XLIMIT                  0x8 #define YLIMIT                  0x10#define TOUCH_ORG_OFFSET_X      0x110//75#define TOUCH_ORG_OFFSET_Y      0xe8//40#define TOUCH_ADC_MAX_X         0x3b6//880/* org 1000 */#define TOUCH_ADC_MAX_Y         0x3b7//890/* org  980 */#define TOUCH_STOP_BUT_QUIVER   3/* * I used  "h3600_ts" name to use the ramdisk image containing x demo *  from www.handhelds.org  * */static char *g_ts_id = "h3600_ts ChangeMe";             /* global touch screen id  for irq*/static char *g_ts_timer_id = "touchscreen timer"; /* global touch screen timer id for irq */#define  ADC_FREQ       2000000           // 2MHz AD convert freq 030918static int PreScale_n;                        // PCLK / (PreScale_n+1) = ADConversion freq.struct s3c2410_ts_general {	unsigned int          head, tail;        /* Position in the event buffer */	struct fasync_struct *async_queue;       /* Asynchronous notification    */	wait_queue_head_t     waitq;             /* Wait queue for reading       */	struct semaphore      lock;              /* Mutex for reading            */	unsigned int          usage_count;       /* Increment on each open       */	unsigned int          total;             /* Total events                 */	unsigned int          processed;	unsigned int          dropped;  };typedef struct config_data{    int x0,y0,x1,y1,x2,y2,x3,y3; // touch screen verify}config_data;struct config_data cfg_data = {0x110, 0xe8, 0, 0, 0, 0, 0x3b6, 0x3b7};struct s3c2410_ts_device {	struct s3c2410_ts_general  d;        struct s3c2410_ts_calibration   cal;          /* ts calibration parameters */        struct s3c2410_ts_event   buf[MOUSEBUF_SIZE];        struct s3c2410_ts_event   cur_data, samples[3],last_data;};/*  I think.. *  if multiple open happens, global_tc ==> global_ts[open_count]  */struct s3c2410_ts_device global_ts;enum pen_state {	PEN_UP = 0,	PEN_DOWN ,	PEN_SAMPLE};enum  ts_timer {        TTIMER_SETUP,	TTIMER_START,	TTIMER_STOP};int     global_ts_justified = 1;int     global_ts_justify_status = 0;int     global_ts_status = PEN_UP;struct  ts_pen_data {	enum pen_state state;	unsigned short x[TS_FILTER_LENGTH];  // Unfiltered data points	unsigned short y[TS_FILTER_LENGTH];	unsigned short count;   // Number of points recorded in this "DOWN" or "DISCARD" series	unsigned short index;   // Location in ring buffer of last stored data value	int            last_cal_x;  // Last reported X value to the user	int            last_cal_y;  // Last reported Y value to the user};struct ts_pen_data pen_data;static void s3c2410_ts_handler(void);static int ts_timer_operation(enum ts_timer tt);static int data_processing(void){      struct s3c2410_ts_device * dev = &global_ts;      int diff0, diff1, diff2;      int RetVal = 0;		/* default valid  */      struct s3c2410_ts_event *samples =dev->samples ;      dev->cur_data.x = samples[0].x;      dev->cur_data.y = samples[0].y;	/*          * Check the variance between X samples (discard if not similar), 	 * then choose the closest pair 	 */      diff0 = abs(samples[0].x - samples[1].x);      diff1 = abs(samples[1].x - samples[2].x);      diff2 = abs(samples[2].x - samples[0].x);//      if (diff0 > XLIMIT || diff1 > XLIMIT || diff2 > XLIMIT )//	return XLIMIT ;		/* invalid  */      if (diff1 < diff2)      {	 if (diff1 < diff0)	    dev->cur_data.x = (samples[1].x + samples[2].x) / 2;	 else	    dev->cur_data.x = (samples[0].x + samples[1].x) / 2;      }      else      {	 if (diff2 < diff0)	    dev->cur_data.x = (samples[2].x + samples[0].x) / 2;	 else	    dev->cur_data.x = (samples[0].x + samples[1].x) / 2;      }/* Do the same for Y */      diff0 = abs(samples[0].y - samples[1].y);      diff1 = abs(samples[1].y - samples[2].y);      diff2 = abs(samples[2].y - samples[0].y);  //      if (diff0 > YLIMIT || diff1 > YLIMIT || diff2 > YLIMIT )//	 return YLIMIT;      if (diff1 < diff2)      {	 if (diff1 < diff0)	    dev->cur_data.y = (samples[1].y + samples[2].y) / 2;	 else	    dev->cur_data.y = (samples[0].y + samples[0].y) / 2;      }      else      {	 if (diff2 < diff0)	    dev->cur_data.y = (samples[2].y + samples[0].y) / 2;	 else	    dev->cur_data.y = (samples[0].y + samples[1].y) / 2;      }       if(global_ts_justified == 0) {                if(global_ts_status == PEN_DOWN){                }                else if(global_ts_status == PEN_UP){                        return;                }else{                        global_ts_status = pen_data.state;                        return;                }          if(global_ts_status == PEN_SAMPLE)                return;          if(global_ts_justify_status == 0) {                printk("the left top point (0x%x, 0x%x)\n", dev->cur_data.x, dev->cur_data.y);                cfg_data.x0      = dev->cur_data.x;                cfg_data.y0      = dev->cur_data.y;                global_ts_justify_status = 1;                global_ts_status = PEN_SAMPLE;          }else if(global_ts_justify_status == 1) {                printk("the right bottom point (0x%x, 0x%x)\n", dev->cur_data.x, dev->cur_data.y);                cfg_data.x3         = dev->cur_data.x;                cfg_data.y3         = dev->cur_data.y;                global_ts_justify_status = 0;                global_ts_justified = 1;                global_ts_status = PEN_SAMPLE;          }      }#if 0        printk("cur_data.x = 0x%x, cur_data.y = 0x%x\n", dev->cur_data.x, dev->cur_data.y);#endif      return RetVal;           dev->cur_data.x   -= cfg_data.x0;      if ( dev->cur_data.x > 40000) dev->cur_data.x = 0;      dev->cur_data.y   -= cfg_data.y3;      if ( dev->cur_data.y > 40000) dev->cur_data.y = 0;                                                                                                                     dev->cur_data.x  = (dev->cur_data.x*CURRENT_LCD_X)/(cfg_data.x3 - cfg_data.x0);      dev->cur_data.y  = CURRENT_LCD_Y - (dev->cur_data.y*CURRENT_LCD_Y)/(cfg_data.y0 - cfg_data.y3);                                                                                                                     if(dev->cur_data.x > CURRENT_LCD_X )        dev->cur_data.x  = CURRENT_LCD_X;                                                                                                                     if(dev->cur_data.y > CURRENT_LCD_Y )        dev->cur_data.y  = CURRENT_LCD_Y;#if 0      printk("dev->cur_data.x = %d, dev->cur_data.y = %d\n", dev->cur_data.x, dev->cur_data.y);#endif      if ( (abs(dev->last_data.x - dev->cur_data.x) <= TOUCH_STOP_BUT_QUIVER) &&            (abs(dev->last_data.y - dev->cur_data.y) <= TOUCH_STOP_BUT_QUIVER) ) {	       dev->cur_data = dev->last_data;      }      else {               dev->last_data = dev->cur_data;      }      return RetVal;}static void touch_timer_irq(int irq, void *dev_id, struct pt_regs *regs){        if( (ADCDAT0&0x8000)||(ADCDAT1&0x8000)) {                  ts_timer_operation(TTIMER_STOP);                  pen_data.state = PEN_UP;                  s3c2410_ts_handler();		  return;	}	switch(pen_data.state) {	case PEN_UP:                     ts_timer_operation(TTIMER_STOP);		     s3c2410_ts_handler();		     return;	case PEN_DOWN:	             pen_data.state = PEN_SAMPLE;		     s3c2410_ts_handler();		     return;	case PEN_SAMPLE:	             if( (ADCDAT0&0x8000)||(ADCDAT1&0x8000)) {		           ts_timer_operation(TTIMER_STOP);			   pen_data.state = PEN_UP;			   s3c2410_ts_handler();			   return;		     } else {		           pen_data.state = PEN_SAMPLE;                           s3c2410_ts_handler();			   return;		     }	default:	printk(__FUNCTION__ "  UNEXPECTED ERROR %d  \n",pen_data.state);	}}/* * Interrupt handler and standard file operations */static void ts_down_interrupt(int irq, void *dev_id, struct pt_regs *regs){	if ( (ADCDAT1&0x8000)|| (ADCDAT0&0x8000) ) {                 pen_data.state = PEN_UP;        }        else {                 pen_data.state = PEN_DOWN;        }        s3c2410_ts_handler();}static void ts_up_interrupt(int irq, void *dev_id, struct pt_regs *regs){        if ( (ADCDAT1&0x8000)|| (ADCDAT0&0x8000) ) {                 pen_data.state = PEN_UP;        }        else {                 pen_data.state = PEN_DOWN;        }                                                                                                                                                       s3c2410_ts_handler();}static void s3c2410_ts_handler(){        int index_ret;        struct s3c2410_ts_device * dev = &global_ts;	unsigned int  nhead            = INCBUF( dev->d.head, MOUSEBUF_SIZE );	struct s3c2410_ts_event *event = &dev->buf[dev->d.head];	switch (pen_data.state) {	case PEN_UP:                global_ts_status = PEN_UP;          	ts_timer_operation(TTIMER_STOP);                ADCTSC &= 0xff;		//pen_data.state = PEN_DOWN;	        break;	  	case PEN_DOWN:                if(global_ts_status == PEN_UP)                         global_ts_status = PEN_DOWN;	        ts_timer_operation(TTIMER_START);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -