📄 touchpanel.c
字号:
/************************************************************文档类型: 原代码 项目编号: 文档编号: 修订版本: v1.0生成日期: 2001.11.9文档作者: 张继周,何雄伦审 核: ************************************************************相关文档: uClinux的触摸屏驱动程序 文档编号 说明 ************************************************************修订版本: v1.1修订说明: 增加了对触摸屏坐标的校验功能生成日期: 2002.3.28文档作者: 何雄伦审 核: ************************************************************修订版本: v1.1修订说明: 增加了将DX,DY,SCX,SCY值写到FLASH生成日期: 2002.5.23文档作者: 周泽明审 核: ************************************************************/#include <linux/kernel.h>#include <asm/MC68VZ328.h>#include <asm/segment.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/tqueue.h>#include <linux/interrupt.h>/* 触摸屏的两种状态:PEN_DOWN为笔按下状态;PEN_UP为笔没有按下状态 */#define PEN_DOWN 1#define PEN_UP 2/* 时钟中断的间隔,每隔固定的时间片就检查笔的状态(按下或没按下) */#define DELAY 20/*The size of keyboard input buffer.*/#define MAX_BUF_COUNT 5000/* 触摸屏设备号 */unsigned int touch_major = 98;/* 笔状态变量,默认没按下 */static unsigned char flag = PEN_UP;/* 触摸屏的数据缓冲区(循环队列) */static unsigned char pen_buf[MAX_BUF_COUNT];static int pstart,pend,count;/* The touch pannel wait queque */static struct wait_queque *touch_wait;/* 触摸屏当前笔的位置和上次按下的位置 */static struct pos { unsigned short x; unsigned short y;}pre_pos,cur_pos;// [Added++] by Aavan, 2002/09/05int gOldX = 0;int gOldY = 0;int gX = 0;int gY = 0;// [Added--]// 由于触摸屏的抖动问题,使用一个滤波器对坐标值滤波struct { unsigned int x[5]; unsigned int y[5]; unsigned short count;}filter;// 存放手写字的轨迹struct trackbuf{ unsigned char track[20000]; unsigned int endpos; unsigned int pointcount; // flag == 0:一个字的轨迹还未结束;flag == 1:一个字的轨迹结束了; unsigned char flag;}pointbuf;// 手写输入键盘在屏幕上的位置;当笔落在这个范围内的时候,// 作为鼠标;在这个范围以外,作为手写轨迹struct keyboard{ unsigned int x; unsigned int y; unsigned int x1; unsigned int y1;}boardrect;// 0:送轨迹;1:不送轨迹static unsigned char sendtrack;// 0:没进入了输入键盘;1:进入了键盘static unsigned char keyflag = 0;// 0:触笔模拟鼠标;1:触笔正进行坐标校验;2:触笔正进行手写输入static unsigned char collateflag = 0;// 判断当前要定位的位置,0:左上角;1:右下角static unsigned char collatepos = 0;unsigned int DX = 151;//179; // LCD左上角位置在触摸屏上的X坐标unsigned int DY = 119;//183; // LCD左上角位置在触摸屏上的Y坐标unsigned int DX1; // LCD右下角位置在触摸屏上的X坐标unsigned int DY1; // LCD右下角位置在触摸屏上的Y坐标float SCX = 0.185f;//0.189f; // SCX = 320/(DX1-DX)float SCY = 0.135f;//0.149f; // SCY = 240/(DY1-DY)// 设备文件正在使用标志static unsigned char useflag = 0;// LCD显示缓存指针static unsigned char *videobuf;// 定义显示缓存尺寸#define VIDEOLEN 38400// 定义一行象素的尺寸#define LINELEN 160// 备份显示缓存static unsigned char videobackup[VIDEOLEN];static unsigned int writedelay = 0;// 定义手写输入字轨迹的灰度值static unsigned char greyvalue = 0xff;static unsigned char notmask[2] = { 0x0f, 0xf0};static char shift[2] = {4,0};// 在FLASH中保存SCX,SCY,DX,DY的值,打开设备时读入这些值,// 在每次校正时重新把这几个值写到FLASH中保存,并在前五个字节里// 写入"FLASH"作为标志.从FLASH中读这几个值,如果前五个字节不是// "FLASH",表示SCX,SCY,DX,DY的值还没有烧到FLASH中,就使用缺省的值.// format: "FLASH",DX,DY,SCX,SCY.#define FLASHBLKID 0#define OFFSET 0#define INTLEN sizeof(unsigned int)#define FLOATLEN sizeof(float)#define LENGTH (5+2*INTLEN+2*FLOATLEN)// this value used to save port d datastatic unsigned char pddata;extern int freadflash(const int fd,const int off,unsigned char *buf,const unsigned int len);extern int fwriteflash(const int fd,const int off,unsigned char *buf,const unsigned int len);/************************************************************函数原型: static void drawpixel(unsigned int x, unsigned int y)功 能: Draw a pixel to LCD.输入参数: x,y:location the pixel.返 回 值: NULL.************************************************************/unsigned char *addr;#define drawpixel(x,y) { \ addr = videobuf; \ addr += (x>>1) + (y << 7) + (y << 5); \ *addr = greyvalue; \ addr += LINELEN; \ *addr = greyvalue; \}static int xdelta; /* width of rectangle around line */static int ydelta; /* height of rectangle around line */static int xinc; /* increment for moving x coordinate */static int yinc; /* increment for moving y coordinate */static int rem; /* current remainder */ static void drawline(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2){ xdelta = x2 - x1; ydelta = y2 - y1; if (xdelta < 0) xdelta = -xdelta; if (ydelta < 0) ydelta = -ydelta; xinc = (x2 > x1) ? 1 : -1; yinc = (y2 > y1) ? 1 : -1; drawpixel(x1,y1); if (xdelta >= ydelta) { rem = xdelta >> 1; for(;;) { x1 += xinc; rem += ydelta; if (rem >= xdelta) { rem -= xdelta; y1 += yinc; } drawpixel(x1,y1); if(x1 == x2) break; } } else { rem = ydelta >> 1; for(;;) { y1 += yinc; rem += xdelta; if (rem >= ydelta) { rem -= ydelta; x1 += xinc; } drawpixel(x1,y1); if(y1 == y2) break; } }}/************************************************************函数原型: static int touch_read(struct inode *node, struct file *fp, unsigned char *ubuf, int ucount);功 能: Read the data of touch panel.输入参数: unsigned char *ubuf:the input data buffer point,the buffer save data of x and y value and pen status(down or up) of touch panel. int ucount:it must be 5.返 回 值: if readed successful then return 5,if the user buffer error then return -1,and no data to read then return 0.************************************************************/static int touch_read(struct inode *node, struct file *fp, unsigned char *ubuf, int ucount){ if (verify_area(VERIFY_WRITE, ubuf, 5) == -EFAULT) return -1; if (count == 0) return 0; put_user(pen_buf[pend],ubuf); put_user(pen_buf[pend+1],ubuf+1); put_user(pen_buf[pend+2],ubuf+2); put_user(pen_buf[pend+3],ubuf+3); put_user(pen_buf[pend+4],ubuf+4); count --; pend +=5 ; if (pend >= MAX_BUF_COUNT) pend = 0; return 5;}/************************************************************函数原型: static int touch_open(struct inode *node, struct file *fp);功 能: this function open the touch panel.输入参数: struct inode *node:not used. struct file *fp:not used.返 回 值: it always open successful,so it return 0.************************************************************/static int touch_open(struct inode *node, struct file *fp){ unsigned char *save,*p,*q; int i;/* save = kmalloc(LENGTH,GFP_KERNEL); if (NULL == save) printk("kmalloc failure.\n"); else { p = save; if (freadflash(FLASHBLKID ,OFFSET,save,LENGTH)) printk("read flash error!\n"); else if ( (0x46 == *p++) && (0x4c == *p++) && (0x41 == *p++) && (0x53 == *p++) && (0x48 == *p++) ) { q = (unsigned char*)&DX; for (i=0;i<INTLEN;i++) *q++ = *p++; q = (unsigned char*)&DY; for (i=0;i<INTLEN;i++) *q++ = *p++; q = (unsigned char*)&SCX; for (i=0;i<FLOATLEN;i++) *q++ = *p++; q = (unsigned char*)&SCY; for (i=0;i<FLOATLEN;i++) *q++ = *p++; printk("read flast -- DX = %d\n",DX); printk("read flast -- DY = %d\n",DY); printk("read flast -- SCX = %d\n",(unsigned int)(SCX*1000)); printk("read flast -- SCY = %d\n",(unsigned int)(SCY*1000)); } kfree(save); }*/ if (useflag == 0) { // 如果驱动是第一次打开,则作为鼠标打开 pstart = 0; pend = 0; count = 0; useflag = 1; } // 不是第一次打开,作为手写输入 return 0;}/************************************************************函数原型: touch_close(struct inode *node, struct file *fp);功 能: this function close the touch panel.输入参数: all arguments don't used.返 回 值: it has no any return value.************************************************************/static void touch_close(struct inode *node, struct file *fp){ useflag = 0;}static int touch_select(struct inode *inode,struct file *file,int mode,select_table *table){ if (mode == SEL_IN) { if (count) { return 1; } select_wait(&touch_wait,table); } return 0;}static unsigned char resourchflag = 0;// This function added by xionglun.he 2002.3.28static int touch_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){ struct trackbuf *pbuf; struct keyboard *prect; unsigned char *save,*p,*q; int i; switch (cmd) { case 1: // 开始校验 collateflag = 1; pre_pos.x = 0; pre_pos.y = 0; cur_pos.x = 0; cur_pos.y = 0; if (arg == 0) collatepos = 0; else collatepos = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -