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

📄 touchpanel.c

📁 最常用的嵌入式LINUX字符设备驱动:触摸屏和小键盘驱动。触摸屏使用SPI接口
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************文档类型: 原代码 项目编号: 文档编号: 修订版本: 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 + -