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

下载本文档

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

文档简介

1、我的触摸屏驱动源代码 /*C头文件*/#include "au_types.h"#define  DEVICE_NAME         "tpanel"#define    IRQ_1              7#define    GPIO_1_PORT 

2、;       GPIO_1#define    GPIO_1_PORT_ADDR   GPIO_1_BASE/ 触摸屏返回值结构体typedef struct  uint32 pressure; uint32 x; uint32 y;TS_RET;/ 校准值结构体typedef struct int32 x; int32 y;TS_POINT;static   TS_POINT   T

3、sPoint10;#define  TS_IOC_MAGIC  0xd9#define  CALIBRATE   _IOW(TS_IOC_MAGIC, 1, sizeof(TsPoint)#define  CALIBRATE_START  _IOW(TS_IOC_MAGIC, 2, sizeof(uint8)/ 以下为触摸屏控制器管脚设置#define   ADS7843_CSS()  writew(0xff, (GPIO_1

4、_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()  wr

5、itew(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

6、_DOUTR()  readw(GPIO_1_PORT_ADDR + 0x10)    / dout p1.2/ ADS7843控制字  #define   AIN_X              0xD4#define   AIN_Y          

7、60;   0x94/ ADS7846控制字/#define   AIN_X              0xD0  /#define   AIN_Y              0x90 /#define   DELAY_200NS 

8、0; 200           / 操作时序控制宏(即延时控制值)#define   DELAY_200NS   400           / 操作时序控制宏(即延时控制值)#define  PEN_DOWN   1    &

9、#160;      / 笔按下#define  PEN_UP    2           / 笔抬起#define  PEN_FLEETING  4           / 笔拖拽#define  

10、;MAX_TS_BUF   16           / 最大缓冲区数#define  BUF_HEAD   (TsDev.bufTsDev.head)      / 取队列头值#define  BUF_TAIL   (TsDev.bufTsDev.tail)   &#

11、160;  / 取队列尾值#define  INCBUF(x, mod)  (+(x) & (mod)-1)      / 位移加一#define  TS_TIMER_DELAY  (HZ/28)          / 定时时长为36ms/#define  TS_TIMER_DELAY  (HZ/15

12、)#define  TS_TIMER_DELAY1  (HZ/10)          / 定时时长为100ms/*C源代码*/#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/kernel.h> &

13、#160;     / printk#include <linux/fs.h>        / file结构#include <linux/init.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/poll.h>#include <linux/interr

14、upt.h>#include <linux/devfs_fs_kernel.h>#include <linux/timer.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/ioctl.h>#include "hi_gpio.h"#include "touch_screen.h"#define _CA

15、LIBRATE_  1       / 使用校准参数,否则使用固定的校准值/ 以下为触摸屏较正用#define SCREEN_WIDTH 800#define SCREEN_HEIGHT 460#define NR_EQUATIONS 6#define LSHIFT(x)       (x)<<10)#define RSHIFT(x)      

16、 (x)>>12)static int VarsNR_EQUATIONS*4;static int CalibrateOk = FALSE;       / 是否校准过#define Vars1 Vars#define Vars2 (Vars + NR_EQUATIONS)#define Vars3 (Vars + NR_EQUATIONS * 2)#define Vars4 (Vars + NR_EQUATIONS * 3)/ 触摸屏设备结构体typedef struct 

17、0;uint32    penStatus; TS_RET    bufMAX_TS_BUF; uint32    head, tail; wait_queue_head_t wq; spinlock_t   lock;TS_DEV;static TS_DEV TsDev;static  struct  timer_list ts_timer; &

18、#160;  / 定义定时器变量static uint32 touch_screen_major = 0;    / 触摸屏设备号static  uint8   Ready = 1;/* 名称:DelayNo()* 功能:短软件延时。* 入口参数:i 延时参数,值越大,延时越久* 出口参数:无*/void  DelayNo(uint32 i)   for(; i>0; i-);/* 名称:TestDelayNo()* 功能:测试短软件延时,以便于产生

19、正确的时序。* 入口参数:无* 出口参数:无*/void  TestDelayNo(void)    while(1)            ADS7843_DCLKS();        DelayNo(DELAY_200NS);        ADS7843_DCLKC();    &

20、#160;   DelayNo(DELAY_200NS);    /* 名称:ADS7843_IOInit()* 功能:初始化ADS7843的控制I/O,CS=1,DCLK=0,DIN=0。* 入口参数:无* 出口参数:无*/void  ADS7843_IOInit(void)    ADS7843_CSS();          / CS = 1    ADS7843_DCLKC();

21、           / DCLK = 0    ADS7843_DINC();         / DIN = 0    DelayNo(DELAY_200NS);/* 名称:ADS7843_IRQR()* 功能:ADS7843的PENIRQ引脚测量,返回当前此引脚的电平值。* 入口参数:无* 出口参数:返回为0表示PENIRQ为低电平状态,否则

22、为高电平。*/uint8  ADS7843_IRQR(void) uint8   dat3; uint8 val; 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);  

23、;  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); 

24、0;    else  return(0); /* 名称:ADS7843_WriteRead()* 功能:对ADS7843进行读写操作。操作按照ADS7843的规定,*  24Clocks,先写8位控制数据,然后读取12位的转换结果。* 入口参数:data  控制数据* 出口参数:返回值为读出的数据*/ void  ADS7843_WriteRead(uint8 data, uint16 *ret)   uint8   i;   

25、60;uint16  ret_dat;  data = data | 0x80;     / 设置S位 ADS7843_IOInit(); ADS7843_CSC();      / CS = 0 for(i=0; i<8; i+)     if( (data&0x80) != 0 )      ADS7843_DINS()

26、;    / DIN = 1       else       ADS7843_DINC();    / DIN = 0    DelayNo(DELAY_200NS);  ADS7843_DCLKS();    / DCLK = 1  DelayNo(DELAY_200NS);

27、  ADS7843_DCLKC();    / DCLK = 0    data = data<<1;  ADS7843_DINC();      / DIN = 0 DelayNo(DELAY_200NS * 3); ADS7843_DCLKS();     / DCLK = 1 DelayNo(DELAY_200NS); 

28、ADS7843_DCLKC();        / DCLK = 0 ret_dat = 0; for(i=0; i<12; i+)     ret_dat = ret_dat<<1;          DelayNo(DELAY_200NS);    ADS7843_DCLKS();    / DC

29、LK = 1    if( ADS7843_DOUTR() != 0 )      ret_dat = ret_dat | 1;         DelayNo(DELAY_200NS);  ADS7843_DCLKC();       / DCLK = 0    if(i = 6)     

30、60;DelayNo(DELAY_200NS * 2);     for(i=0; i<3; i+)     DelayNo(DELAY_200NS);    ADS7843_DCLKS();    / DCLK = 1    DelayNo(DELAY_200NS);  ADS7843_DCLKC();    / DCLK = 0 

31、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) 

32、   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 = (

33、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;  

34、60; if (denominator1 = 0)            return FALSE;        denominator2 = y12*x23 - y23*x12;    if (denominator2 = 0)            return FALSE;  &#

35、160;     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 * s

36、rc_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

37、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_PO

38、INT 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 (!DoGauss

39、ianElimination(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 = ds

40、t_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_pt

41、s2;    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)  

42、;          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; &

43、#160;  my_dst_pts2 = dst_pts4;    if (!DoGaussianElimination(Vars4, my_src_pts, my_dst_pts)            return FALSE;     #if 0  printf("Vars:"); int i; for (i=0; i<4*NR_EQUATION

44、S; i+)   if (i>0 && !(i%4)   printf("n");  printf("%dt", Varsi);    printf("n");#endif    return TRUE;/* 名称: DoMouseCalibrate* 功能: 校准*  * 入口参数:* 出口参数:*/ int32 DoMou

45、seCalibrate(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

46、 * 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;&

47、#160;   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 < 0)   x = 0;  else if (x > SCREEN_WIDTH)   x = SCR

48、EEN_WIDTH;  if (y < 0)   y = 0;  else if (y > SCREEN_HEIGHT)   y = SCREEN_HEIGHT;     *x0 = x; *y0 = y; printk("des: x:%4d  y:%4dn", x, y);#else #define TOUCH_LEFT   (709) /1

49、00 #define TOUCH_TOP   (1093) /400 #define TOUCH_RIGHT   (3369) /100  #define TOUCH_BOTTOM  (3215) /700 int32 ScaleX = (TOUCH_RIGHT - TOUCH_LEFT) * 10 / 600; /10倍 int32 ScaleY = (TOUCH_BOTTOM - TOUCH_TOP) * 10

50、/ 300; /10倍 int32 x, y;  x = *x0; y = *y0;    x = (x-TOUCH_LEFT)*10 / ScaleX + 100; y = (y-TOUCH_TOP)*10 / ScaleY + 100; if (x<0)  x = 0;  if (x>SCREEN_WIDTH)  x = SCREEN_WIDTH;  if (y<0)  y

51、= 0;  if (y>SCREEN_HEIGHT)  y = SCREEN_HEIGHT;  *x0 = x; *y0 = y; printk("*x:%dt y%dn", x, y);#endif return TRUE;/* 名    称:get_lcd_xy* 功    能:读取触摸屏上触摸点的坐标。*         &#

52、160; 程序会一直等待,直到有触摸输入。* 入口参数:x       用于保存触摸点x坐标(LCD)的变量指针*           y       用于保存触摸点y坐标(LCD)的变量指针* 出口参数:无* 说    明:先通测量y轴的触摸输入,判断是否有触摸动作。如果有,则进行数据采集,*   并进行去极值平均滤

53、波处理。最后还要判断触摸输入是否合法,只有*           当触摸输入合法时才返回。*/int32  get_lcd_xy(uint16 *vx, uint16 *vy)    static  uint8 i, temp; static  uint16  vx_dat = 0;  static  uint16 vy_dat = 0; static  u

54、int16 x_max_data = 0; static  uint16 x_min_data = 0; static  uint16 y_max_data = 0; static  uint16 y_min_data = 0; static uint32 x_sum = 0; static uint32 y_sum = 0; / 屏校准后不读取拖动状态的数据,只有按下和抬起有发送给GUI  if (TsD

55、ev.penStatus = PEN_FLEETING) && (CalibrateOk = TRUE)   return -1;    while(1)               / 进行数据采集        ADS7843_WriteRead(AIN_X, &vx_dat);  x_ma

56、x_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 <

57、; 21; i+)     udelay(100);   temp = ADS7843_IRQR();   if (temp != 0)       break;      ADS7843_WriteRead(AIN_X, &vx_dat);   if (vx_dat > x_max_data) 

58、0;     x_max_data = vx_dat;      if (vx_dat < x_min_data)       x_min_data = vx_dat;      x_sum += vx_dat;      ADS7843_WriteRead(AIN_Y, &vy_da

59、t);   if (vy_dat > y_max_data)       y_max_data = vy_dat;      if (vy_dat < y_min_data)       y_min_data = vy_dat;      y_sum += vy_dat;  &

60、#160;#if 1  / 去极值求平均值  /*  if (x_max_data - x_min_data) > 200)     return -1;    if (y_max_data - y_min_data) > 200)     return -1;    */  if (i < 3)  

61、   return -1;    *vx = (x_sum - x_max_data - x_min_data) / (i-2);    *vy = 4096 - (y_sum - y_max_data - y_min_data) / (i-2);  /printk("1.x:%d  y:%d   i = %dn", *vx, *vy, i);  printk("1.x:%d  y:%d

62、n", *vx, *vy); #else  / 取极值求平均值  *vx = (x_max_data + x_min_data) / 2;  *vy = 4096 - (y_max_data + y_min_data) / 2;  printk("2.x:%d  y:%dn", *vx, *vy); #endif #ifdef _CALIBRATE_       / 使用校准参

63、数校准,否则使用固定参数校准  if (CalibrateOk = TRUE)           DoMouseCalibrate(vx, vy);   / 触摸屏校准      #else  DoMouseCalibrate(vx, vy); #endif         return 0;&#

64、160; /*  Function:  ts_put_value  Description:  将采样到的数据填充到队列中并唤醒进程来读取  Input:  1.   x 横坐标 2.   y 纵坐标  Output:  无  Return:  无  Others:*/static void ts_put_value(uint16 x, uint16 y) BUF_H

65、EAD.x = x; BUF_HEAD.y = y; BUF_HEAD.pressure = TsDev.penStatus; TsDev.head = INCBUF(TsDev.head, MAX_TS_BUF); Ready = 1; wake_up_interruptible(&(TsDev.wq);/*  Function:  ts_get_value  Description:  从队列中读取采样到的数据  Input:   无  Out

66、put: 1.   采样到的值  Return:  成功-采样到值的字节数,失败= -1  Others:*/static uint32 ts_get_value(TS_RET *ts_ret) /printk("touchscreenko ts_get_value_1n"); if (TsDev.head != TsDev.tail)   ts_ret->x = BUF_TAIL.x;  ts_ret->y =

67、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;  ret

68、urn -1; /*  Function:  gpio_init  Description:  GPIO初始化  Input:   无  Output:  无  Return:  无  Others:*/void gpio_init(void) int32 tmp;  / 设置GPIO1方向 gpio_dirgetbyte(GPIO_1_PORT, &tmp); printk(&

69、quot;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为中断口

70、60;gpio_interruptset_byte(        GPIO_1_PORT,        0x20,0,0,1        / SENSE_BOTH,        / SENSE_LEVEL,     

71、60;  / 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_P

72、ORT,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

73、 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 &a

74、mp; 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 

75、  /printk("pen_downn");  TsDev.penStatus = PEN_DOWN;     / 笔状态置为按下  ts_timer.expires = jiffies + TS_TIMER_DELAY;  add_timer(&ts_timer);      / 启动定时器  /printk("ts_interruptn&quo

76、t;); handled = 1;    return IRQ_RETVAL(handled);/*  Function:  ts_timer_handler  Description:  定时器处理  Input:   无  Output:  无  Return:  无  Others:*/static void ts_timer_handler(unsigned long data) int3

77、2 temp; static uint16 x = 0; static uint16 y = 0; / 读取中断管脚上的电平 temp = ADS7843_IRQR(); if (temp = 0)         / 去抖处理   /printk("PEN_FLEETINGn");  temp = get_lcd_xy(&x, &y);   

78、;  / 读取触摸屏的值  if (temp = 0)     ts_put_value(x, y);      / 把笔状态与触摸屏的值加入到队列中   TsDev.penStatus = PEN_FLEETING;   / 下一个状态改为拖拽      ts_timer.expires = jiffies + TS_TIME

79、R_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_

温馨提示

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

评论

0/150

提交评论