?? touchpanel.c
字號:
/************************************************************文檔類型: 原代碼 項目編號: 文檔編號: 修訂版本: v1.0生成日期: 2001.11.9文檔作者: 張繼周,何雄倫審 核: ************************************************************相關(guān)文檔: uClinux的觸摸屏驅(qū)動程序 文檔編號 說明 ************************************************************修訂版本: v1.1修訂說明: 增加了對觸摸屏坐標(biāo)的校驗功能生成日期: 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>/* 觸摸屏的兩種狀態(tài):PEN_DOWN為筆按下狀態(tài);PEN_UP為筆沒有按下狀態(tài) */#define PEN_DOWN 1#define PEN_UP 2/* 時鐘中斷的間隔,每隔固定的時間片就檢查筆的狀態(tài)(按下或沒按下) */#define DELAY 20/*The size of keyboard input buffer.*/#define MAX_BUF_COUNT 5000/* 觸摸屏設(shè)備號 */unsigned int touch_major = 98;/* 筆狀態(tài)變量,默認(rèn)沒按下 */static unsigned char flag = PEN_UP;/* 觸摸屏的數(shù)據(jù)緩沖區(qū)(循環(huán)隊列) */static unsigned char pen_buf[MAX_BUF_COUNT];static int pstart,pend,count;/* The touch pannel wait queque */static struct wait_queque *touch_wait;/* 觸摸屏當(dāng)前筆的位置和上次按下的位置 */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--]// 由于觸摸屏的抖動問題,使用一個濾波器對坐標(biāo)值濾波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:一個字的軌跡還未結(jié)束;flag == 1:一個字的軌跡結(jié)束了; unsigned char flag;}pointbuf;// 手寫輸入鍵盤在屏幕上的位置;當(dāng)筆落在這個范圍內(nèi)的時候,// 作為鼠標(biāo);在這個范圍以外,作為手寫軌跡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:觸筆模擬鼠標(biāo);1:觸筆正進行坐標(biāo)校驗;2:觸筆正進行手寫輸入static unsigned char collateflag = 0;// 判斷當(dāng)前要定位的位置,0:左上角;1:右下角static unsigned char collatepos = 0;unsigned int DX = 151;//179; // LCD左上角位置在觸摸屏上的X坐標(biāo)unsigned int DY = 119;//183; // LCD左上角位置在觸摸屏上的Y坐標(biāo)unsigned int DX1; // LCD右下角位置在觸摸屏上的X坐標(biāo)unsigned int DY1; // LCD右下角位置在觸摸屏上的Y坐標(biāo)float SCX = 0.185f;//0.189f; // SCX = 320/(DX1-DX)float SCY = 0.135f;//0.149f; // SCY = 240/(DY1-DY)// 設(shè)備文件正在使用標(biāo)志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的值,打開設(shè)備時讀入這些值,// 在每次校正時重新把這幾個值寫到FLASH中保存,并在前五個字節(jié)里// 寫入"FLASH"作為標(biāo)志.從FLASH中讀這幾個值,如果前五個字節(jié)不是// "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);/************************************************************函數(shù)原型: static void drawpixel(unsigned int x, unsigned int y)功 能: Draw a pixel to LCD.輸入?yún)?shù): 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; } }}/************************************************************函數(shù)原型: static int touch_read(struct inode *node, struct file *fp, unsigned char *ubuf, int ucount);功 能: Read the data of touch panel.輸入?yún)?shù): 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;}/************************************************************函數(shù)原型: static int touch_open(struct inode *node, struct file *fp);功 能: this function open the touch panel.輸入?yún)?shù): 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) { // 如果驅(qū)動是第一次打開,則作為鼠標(biāo)打開 pstart = 0; pend = 0; count = 0; useflag = 1; } // 不是第一次打開,作為手寫輸入 return 0;}/************************************************************函數(shù)原型: touch_close(struct inode *node, struct file *fp);功 能: this function close the touch panel.輸入?yún)?shù): 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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -