我的触摸屏驱动源代码.doc_第1页
我的触摸屏驱动源代码.doc_第2页
我的触摸屏驱动源代码.doc_第3页
我的触摸屏驱动源代码.doc_第4页
我的触摸屏驱动源代码.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

我的触摸屏驱动源代码 /*C头文件*/#include au_types.h#defineDEVICE_NAME tpanel#define IRQ_1 7#define GPIO_1_PORT GPIO_1#define GPIO_1_PORT_ADDR GPIO_1_BASE/ 触摸屏返回值结构体typedef struct uint32 pressure;uint32 x;uint32 y;TS_RET;/ 校准值结构体typedef structint32 x;int32 y;TS_POINT;static TS_POINTTsPoint10;#defineTS_IOC_MAGIC0xd9#defineCALIBRATE_IOW(TS_IOC_MAGIC, 1, sizeof(TsPoint)#defineCALIBRATE_START_IOW(TS_IOC_MAGIC, 2, sizeof(uint8)/ 以下为触摸屏控制器管脚设置#define ADS7843_CSS()writew(0xff, (GPIO_1_PORT_ADDR + 0x200)/ cs = 1 (p1.7)#define ADS7843_CSC()writew(0x00, (GPIO_1_PORT_ADDR + 0x200)/ cs = 0#define ADS7843_DCLKS()writew(0xff, (GPIO_1_PORT_ADDR + 0x40)/ dclk = 1(p1.4)#define ADS7843_DCLKC()writew(0x00, (GPIO_1_PORT_ADDR + 0x40)/ dclk = 0#define ADS7843_DINS()writew(0xff, (GPIO_1_PORT_ADDR + 0x20)/ din = 1(p.3)#define ADS7843_DINC()writew(0x00, (GPIO_1_PORT_ADDR + 0x20)/ din = 0#define ADS7843_DOUTR()readw(GPIO_1_PORT_ADDR + 0x10)/ dout p1.2/ ADS7843控制字 #define AIN_X 0xD4#define AIN_Y 0x94/ ADS7846控制字/#define AIN_X 0xD0 /#define AIN_Y 0x90 /#define DELAY_200NS200/ 操作时序控制宏(即延时控制值)#define DELAY_200NS400/ 操作时序控制宏(即延时控制值)#definePEN_DOWN1/ 笔按下#definePEN_UP2/ 笔抬起#definePEN_FLEETING4/ 笔拖拽#defineMAX_TS_BUF16/ 最大缓冲区数#defineBUF_HEAD(TsDev.bufTsDev.head)/ 取队列头值#defineBUF_TAIL(TsDev.bufTsDev.tail)/ 取队列尾值#defineINCBUF(x, mod)(+(x) & (mod)-1)/ 位移加一#defineTS_TIMER_DELAY(HZ/28) / 定时时长为36ms/#defineTS_TIMER_DELAY(HZ/15)#defineTS_TIMER_DELAY1(HZ/10)/ 定时时长为100ms/*C源代码*/#include #include #include #include #include / printk#include / file结构#include #include #include #include #include #include #include #include #include #include #include #include #include #include hi_gpio.h#include touch_screen.h#define_CALIBRATE_1/ 使用校准参数,否则使用固定的校准值/ 以下为触摸屏较正用#define SCREEN_WIDTH800#define SCREEN_HEIGHT460#define NR_EQUATIONS6#define LSHIFT(x) (x)12)static int VarsNR_EQUATIONS*4;static int CalibrateOk = FALSE; / 是否校准过#define Vars1Vars#define Vars2(Vars + NR_EQUATIONS)#define Vars3(Vars + NR_EQUATIONS * 2)#define Vars4(Vars + NR_EQUATIONS * 3)/ 触摸屏设备结构体typedef struct uint32penStatus;TS_RETbufMAX_TS_BUF;uint32head, tail;wait_queue_head_twq;spinlock_tlock;TS_DEV;staticTS_DEVTsDev;static struct timer_list ts_timer;/ 定义定时器变量staticuint32touch_screen_major = 0;/ 触摸屏设备号static uint8 Ready = 1;/* 名称:DelayNo()* 功能:短软件延时。* 入口参数:i 延时参数,值越大,延时越久* 出口参数:无*/void DelayNo(uint32 i) for(; i0; i-);/* 名称:TestDelayNo()* 功能:测试短软件延时,以便于产生正确的时序。* 入口参数:无* 出口参数:无*/void TestDelayNo(void) while(1) ADS7843_DCLKS(); DelayNo(DELAY_200NS); ADS7843_DCLKC(); DelayNo(DELAY_200NS); /* 名称:ADS7843_IOInit()* 功能:初始化ADS7843的控制I/O,CS=1,DCLK=0,DIN=0。* 入口参数:无* 出口参数:无*/void ADS7843_IOInit(void) ADS7843_CSS(); / CS = 1 ADS7843_DCLKC(); / DCLK = 0 ADS7843_DINC();/ DIN = 0 DelayNo(DELAY_200NS);/* 名称:ADS7843_IRQR()* 功能:ADS7843的PENIRQ引脚测量,返回当前此引脚的电平值。* 入口参数:无* 出口参数:返回为0表示PENIRQ为低电平状态,否则为高电平。*/uint8 ADS7843_IRQR(void)uint8 dat3;uint8val;DelayNo(1);val = readw(GPIO_1_PORT_ADDR + 0x80); if(val) dat0 = 1; else dat0 = 0;/DelayNo(1);val = readw(GPIO_1_PORT_ADDR + 0x80); if(val) dat1 = 1; else dat1 = 0;/DelayNo(1);val = readw(GPIO_1_PORT_ADDR + 0x80); if(val) dat2 = 1; else dat2 = 0;/DelayNo(1); if(dat0 + dat1 + dat2) 1) return(1); else return(0);/* 名称:ADS7843_WriteRead()* 功能:对ADS7843进行读写操作。操作按照ADS7843的规定,*24Clocks,先写8位控制数据,然后读取12位的转换结果。* 入口参数:data控制数据* 出口参数:返回值为读出的数据*/ void ADS7843_WriteRead(uint8 data, uint16 *ret) uint8 i; uint16 ret_dat;data = data | 0x80;/ 设置S位ADS7843_IOInit();ADS7843_CSC();/ CS = 0for(i=0; i8; i+) if( (data&0x80) != 0 ) ADS7843_DINS();/ DIN = 1 else ADS7843_DINC();/ DIN = 0DelayNo(DELAY_200NS);ADS7843_DCLKS();/ DCLK = 1DelayNo(DELAY_200NS);ADS7843_DCLKC();/ DCLK = 0 data = data1;ADS7843_DINC();/ DIN = 0DelayNo(DELAY_200NS * 3);ADS7843_DCLKS();/ DCLK = 1DelayNo(DELAY_200NS);ADS7843_DCLKC(); / DCLK = 0ret_dat = 0;for(i=0; i12; i+) ret_dat = ret_dat1; DelayNo(DELAY_200NS); ADS7843_DCLKS();/ DCLK = 1 if( ADS7843_DOUTR() != 0 ) ret_dat = ret_dat | 1; DelayNo(DELAY_200NS);ADS7843_DCLKC(); / DCLK = 0 if(i = 6) DelayNo(DELAY_200NS * 2); for(i=0; i3; i+) DelayNo(DELAY_200NS); ADS7843_DCLKS();/ DCLK = 1 DelayNo(DELAY_200NS);ADS7843_DCLKC();/ DCLK = 0 DelayNo(DELAY_200NS);ADS7843_CSS();/ CS = 1*ret = ret_dat;/* 名称:DoGaussianElimination* 功能:* 入口参数:* 出口参数:*/ static uint8 DoGaussianElimination(int* x, const TS_POINT* src_pts, const TS_POINT* dst_pts) int x12, x23, y12, y23, nx12, nx23, ny12, ny23; int numerator, denominator1, denominator2; x12 = (src_pts0.x - src_pts1.x); x23 = (src_pts1.x - src_pts2.x); y12 = (src_pts0.y - src_pts1.y); y23 = (src_pts1.y - src_pts2.y); nx12 = (dst_pts0.x - dst_pts1.x); nx23 = (dst_pts1.x - dst_pts2.x); ny12 = (dst_pts0.y - dst_pts1.y); ny23 = (dst_pts1.y - dst_pts2.y); denominator1 = x12*y23 - x23*y12; if (denominator1 = 0) return FALSE; denominator2 = y12*x23 - y23*x12; if (denominator2 = 0) return FALSE; numerator = nx12*y23 - nx23*y12; x 0 = LSHIFT (numerator) / denominator1; numerator = nx12*x23 - nx23*x12; x 1 = LSHIFT (numerator) / denominator2; x 2 = LSHIFT (dst_pts 0.x) - x 0 * src_pts 0.x - x 1 * src_pts 0.y; numerator = ny12*y23 - ny23*y12; x 3 = LSHIFT (numerator) / denominator1; numerator = ny12*x23 - ny23*x12; x 4 = LSHIFT (numerator) / denominator2; x 5 = LSHIFT (dst_pts 0.y) - x 3 * src_pts 0.x - x 4 * src_pts 0.y; return TRUE;/* 名称:SetMouseCalibrationParameters* 功能:* 入口参数:* 出口参数:*/ static uint8 SetMouseCalibrationParameters(const TS_POINT* src_pts, const TS_POINT* dst_pts) TS_POINT my_src_pts 3; TS_POINT my_dst_pts 3; my_src_pts0 = src_pts0; my_src_pts1 = src_pts1; my_src_pts2 = src_pts4; my_dst_pts0 = dst_pts0; my_dst_pts1 = dst_pts1; my_dst_pts2 = dst_pts4; if (!DoGaussianElimination(Vars1, my_src_pts, my_dst_pts) return FALSE; my_src_pts0 = src_pts1; my_src_pts1 = src_pts2; my_src_pts2 = src_pts4; my_dst_pts0 = dst_pts1; my_dst_pts1 = dst_pts2; my_dst_pts2 = dst_pts4; if (!DoGaussianElimination(Vars2, my_src_pts, my_dst_pts) return FALSE; my_src_pts0 = src_pts2; my_src_pts1 = src_pts3; my_src_pts2 = src_pts4; my_dst_pts0 = dst_pts2; my_dst_pts1 = dst_pts3; my_dst_pts2 = dst_pts4; if (!DoGaussianElimination(Vars3, my_src_pts, my_dst_pts) return FALSE; my_src_pts0 = src_pts0; my_src_pts1 = src_pts3; my_src_pts2 = src_pts4; my_dst_pts0 = dst_pts0; my_dst_pts1 = dst_pts3; my_dst_pts2 = dst_pts4; if (!DoGaussianElimination(Vars4, my_src_pts, my_dst_pts) return FALSE; #if 0printf(Vars:);int i;for (i=0; i0 & !(i%4)printf(n);printf(%dt, Varsi);printf(n);#endif return TRUE;/* 名称:DoMouseCalibrate* 功能:校准* 入口参数:* 出口参数:*/ int32 DoMouseCalibrate(uint16 * x0, uint16 * y0)#ifdef _CALIBRATE_/ 使用校准参数,否则使用固定的校准值 int x = *x0;int y = *y0; int x1, y1, x2, y2, x3, y3, x4, y4;printk(src: x:%4d y:%4dn, x, y); x1 = Vars10 * x + Vars11 * y + Vars12; y1 = Vars13 * x + Vars14 * y + Vars15; x2 = Vars20 * x + Vars21 * y + Vars22; y2 = Vars23 * x + Vars24 * y + Vars25; x3 = Vars30 * x + Vars31 * y + Vars32; y3 = Vars33 * x + Vars34 * y + Vars35; x4 = Vars40 * x + Vars41 * y + Vars42; y4 = Vars43 * x + Vars44 * y + Vars45;x = RSHIFT(x1 + x2 + x3 + x4);y = RSHIFT(y1 + y2 + y3 + y4);if (x SCREEN_WIDTH)x = SCREEN_WIDTH;if (y SCREEN_HEIGHT)y = SCREEN_HEIGHT; *x0 = x;*y0 = y;printk(des: x:%4d y:%4dn, x, y);#else#define TOUCH_LEFT(709)/100#define TOUCH_TOP(1093)/400#define TOUCH_RIGHT(3369)/100#define TOUCH_BOTTOM(3215)/700int32 ScaleX = (TOUCH_RIGHT - TOUCH_LEFT) * 10 / 600;/10倍int32 ScaleY = (TOUCH_BOTTOM - TOUCH_TOP) * 10 / 300;/10倍int32 x, y;x = *x0;y = *y0; x = (x-TOUCH_LEFT)*10 / ScaleX + 100;y = (y-TOUCH_TOP)*10 / ScaleY + 100;if (xSCREEN_WIDTH)x = SCREEN_WIDTH;if (ySCREEN_HEIGHT)y = SCREEN_HEIGHT;*x0 = x;*y0 = y;printk(*x:%dt y%dn, x, y);#endifreturn TRUE;/* 名 称:get_lcd_xy* 功 能:读取触摸屏上触摸点的坐标。* 程序会一直等待,直到有触摸输入。* 入口参数:x 用于保存触摸点x坐标(LCD)的变量指针* y 用于保存触摸点y坐标(LCD)的变量指针* 出口参数:无* 说 明:先通测量y轴的触摸输入,判断是否有触摸动作。如果有,则进行数据采集,*并进行去极值平均滤波处理。最后还要判断触摸输入是否合法,只有* 当触摸输入合法时才返回。*/int32 get_lcd_xy(uint16 *vx, uint16 *vy) static uint8i, temp;static uint16 vx_dat = 0; static uint16vy_dat = 0;static uint16x_max_data = 0;static uint16x_min_data = 0;static uint16y_max_data = 0;static uint16y_min_data = 0;staticuint32x_sum = 0;staticuint32y_sum = 0;/ 屏校准后不读取拖动状态的数据,只有按下和抬起有发送给GUIif (TsDev.penStatus = PEN_FLEETING) & (CalibrateOk = TRUE)return -1;while(1) / 进行数据采集 ADS7843_WriteRead(AIN_X, &vx_dat);x_max_data = vx_dat;x_min_data = vx_dat;x_sum = vx_dat; ADS7843_WriteRead(AIN_Y, &vy_dat);y_max_data = vy_dat;y_min_data = vy_dat;y_sum = vy_dat;for (i = 1; i x_max_data)x_max_data = vx_dat;if (vx_dat y_max_data)y_max_data = vy_dat;if (vy_dat 200)return -1;if (y_max_data - y_min_data) 200)return -1;*/if (i x = BUF_TAIL.x;ts_ret-y = BUF_TAIL.y;ts_ret-pressure = BUF_TAIL.pressure;TsDev.tail = INCBUF(TsDev.tail, MAX_TS_BUF);/printk(touchscreenko ts_get_value_2n);return sizeof(TS_RET);else Ready = 0;return -1;/* Function:gpio_init Description: GPIO初始化 Input: 无 Output:无 Return:无 Others:*/void gpio_init(void)int32 tmp;/ 设置GPIO1方向gpio_dirgetbyte(GPIO_1_PORT, &tmp);printk(gpio_init-:0x%xn,GPIO_1_PORT);tmp |= 0x98;/ 设置gpio1的3,4,7为输出tmp &= 0xDB;/ 设置gpio1的2,5为输入gpio_dirsetbyte(GPIO_1_PORT, tmp);/ 设置GPIO1中的5为中断口gpio_interruptset_byte(GPIO_1_PORT,0x20,0,0,1/ SENSE_BOTH,/ SENSE_LEVEL,/ EVENT_FALLING_EDGE);/ 屏蔽GPIO1.5中断tmp = 0x20;gpio_interruptdisable_byte(GPIO_1_PORT, tmp);/ 清除GPIO1.5中断标志gpio_interruptclear_byte(GPIO_1_PORT,tmp);/ 使能GPIO1.5中断gpio_interruptenable_byte(GPIO_1_PORT,tmp);/* Function:ts_interrupt Description: 触摸屏中断处理 Input: 无 Output:无 Return:无 Others:*/static irqreturn_t ts_interrupt(int32 irq, void *dev_id, struct pt_regs *reg) int32 handled = 0;uint8 current_irq;int32 tmp;printk(KERN_NOTICE ENTER INTE);tmp = 0x20; gpio_interruptdisable_byte(GPIO_1_PORT, tmp);/ 查询该管脚中断是否匹配上 current_irq = readw(GPIO_1_PORT_ADDR + GPIO_RIS); current_irq = current_irq & tmp;/ 读取中断管脚上的电平tmp = ADS7843_IRQR();if (current_irq = 0 | tmp != 0)/ 中断没匹配上或中断管脚上的电平不为低则不处理tmp = 0x20;gpio_interruptclear_byte(GPIO_1_PORT, tmp);gpio_interruptenable_byte(GPIO_1_PORT, tmp);else/printk(pen_downn);TsDev.penStatus = PEN_DOWN;/ 笔状态置为按下ts_timer.expires = jiffies + TS_TIMER_DELAY;add_timer(&ts_timer);/ 启动定时器/printk(ts_interruptn);handled = 1; return IRQ_RETVAL(handled);/* Function:ts_timer_handler Description: 定时器处理 Input: 无 Output:无 Return:无 Others:*/static void ts_timer_handler(unsigned long data)int32 temp;static uint16 x = 0;static uint16 y = 0;/ 读取中断管脚上的电平temp = ADS7843_IRQR();if (temp = 0)/ 去抖处理/printk(PEN_FLEETINGn);temp = get_lcd_xy(&x, &y);/ 读取触摸屏的值if (temp = 0)ts_put_value(x, y);/ 把笔状态与触摸屏的值加入到队列中TsDev.penStatus = PEN_FLEETING;/ 下一个状态改为拖拽ts_timer.expires = jiffies + TS_TIMER_DELAY1;add_timer(&ts_timer);else if (TsDev.penStatus != PEN_UP)del_timer(&ts_timer);if (TsDev.penStatus = PEN_FLEETING)TsDev.penStatus = PEN_UP;ts_put_value(x, y);/ 把抬笔状态加入到队列中TsDev.penStatus = PEN_UP;temp = 0x20;gpio_interruptclear_byte(GPIO_1_PORT, temp);gpio_interruptenable_byte(GPIO_1_PORT, temp);/* Function:ts_open Description: 打开设备 Input: 无 Output:无 Return:无 Others:*/static int32 ts_open(struct inode *inode ,struct file *file)TsDev.head = 0;TsDev.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论