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

📄 tpdrv.c

📁 linux console 界面下的触摸屏的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
 //=============================================================================
//
//  TeamPOS 2000 Touchpanel driver 
//  
//  
//
//-----------------------------------------------------------------------------
//================================================
//  include
//================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/resource.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <syslog.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#define D_TPDRV_DEBUG 0
//================================================
//  define 
//================================================
#define MAXFD	64

#define D_LOCK_FILE_NAME	"/usr/tmp/TPDrv.lock"
#define D_TP_PROFILE_NAME   "/usr/etc/TPDrv.conf"#define D_RAWSTAT_MAX	5

#define D_STATUS    0
#define D_XL		1
#define D_XH		2
#define D_YL		3
#define D_YH		4

#define D_MAKE		0x00
#define D_BODY		0x01
#define D_BREAK		0x02

#define D_STREAMMODE 1
#define D_POINTMODE  2

//================================================
//  struct
//================================================
typedef struct T_MouseStat
{
	int			  rawstat;
	unsigned char CurrentRaw[5];	//僞僢僠僷僱儖偐傜偺嵗昗僨乕僞僷働僢僩
	int LastX;
	int LastY;
	int BtnStat;
}t_MouseStat;

typedef struct T_TPProf
{
	int  mode;
	int  SamplingRate;
	char Port[16];
	int  Scalling;
	int  Threashold;
	int  X_Resolution;
	int  Y_Resolution;
	int  MAX_X_VAL;
	int  MAX_Y_VAL;
	char DevName[256];
}t_TPProf;

typedef struct T_ps2Packet
{
	unsigned char Botton;
	unsigned char X;
	unsigned char Y;	unsigned char rsv;
}t_ps2Packet;

//================================================
//  global
//================================================
static int  g_FIFOSH = -1;
t_MouseStat g_MouseStat;
t_ps2Packet g_ps2Packet[32];
t_TPProf    g_TPProf;	//default : STREAMMODE - SamplingRate 40ms
static int  g_SERISH;
char  g_OutData[256];
int   g_MAXMOVE;//===============================================
//  prototype
//================================================
static int  k_HandlerTP(unsigned char val);
static int  k_ConvertPS2XYData(int X, int Y);
static void k_MainLoop(void);
static int  k_SendDmy(void);
static int  k_SetRate(void);
static int  k_Report(void);
static int  k_RS_Open(void);
static int  k_RS_Write(char*	Buf, int Size);
static int  k_RS_Read(char* Buf, int Size);
static void k_RS_Close(void);
static int  k_Write_PS2Packet(int Num);
static int  k_AccelCalc(int X, int Y, char XSign, char YSign);
static void k_DPrint(const char *fmt, ...);
static void k_Dump(const char *Tag, void *msg, int len);
static int  k_GetProfileInt(const char *Section, const char *key, int Default);
static int  k_GetProfileString(const char *Section, const char *key, char *string, int stringsize,const char* Default);
static void k_ValueInit(void);static void k_Sig_Chld(int SigID);
static int  k_mkfifo(char *FIFOName);
//================================================
//  main
//================================================
int main(void)
{
	int		PipeFd[2];
	struct  flock Lock;
	char	Buf[16];
	int		Fd;
	int		ii;
	int		FncRet;
	pid_t		Pid;

	// start log 
	openlog("TPDrv ", 0, LOG_DAEMON);	syslog(LOG_CRIT, "start\n");
	syslog(LOG_CRIT, "priority = %d\n", getpriority(PRIO_PROCESS, 0));
	FncRet = pipe(PipeFd);

#if D_TPDRV_DEBUG
#else
	// be daemon process
	Pid = fork();
	if(Pid < 0)
		goto l_ErrorFork;
	if(Pid != 0)
	{
		// wait... until child process be session leader
		read(PipeFd[0], Buf, 1);
		exit(0);
	}
	setsid();
	write(PipeFd[1], Buf, 1);
#endif
	
	chdir("/");
	umask(0);

#if D_TPDRV_DEBUG
	// set signal handler
	signal(SIGCHLD, k_Sig_Chld);
#else
	// close file
	for (ii=0;ii<MAXFD;ii++)
		close(ii);
#endif
	// lock file
	Fd = open(D_LOCK_FILE_NAME, O_RDWR | O_CREAT);
	if(Fd < 0)
		goto l_ELockFileOpen;
	Lock.l_type = F_WRLCK;
	Lock.l_whence = SEEK_SET;
	Lock.l_start = 0;
	Lock.l_len = 1;
	FncRet = fcntl(Fd, F_SETLK, &Lock);
	if(FncRet != 0)
		goto l_ErrorLock;

	k_ValueInit();

	FncRet = k_mkfifo(g_TPProf.DevName);	
	if(FncRet != 0)
		goto l_EMKFifo;

	g_FIFOSH = open(g_TPProf.DevName, O_WRONLY);
	if(g_FIFOSH < 0)
		goto l_EFIFOOpen;

	g_MouseStat.LastX = g_TPProf.X_Resolution/2;
	g_MouseStat.LastY = g_TPProf.Y_Resolution/2;
	k_MainLoop();

l_Exit:
	if(g_FIFOSH != -1)	close(g_FIFOSH);
	syslog(LOG_CRIT, "stop\n");
	return 0;
l_ELockFileOpen:
	k_DPrint("SystemError[ID=0001](open errno=%d)\n", errno);
	goto l_Exit;
l_ErrorFork:
	k_DPrint("SystemError[ID=0002](fork errno=%d)\n", errno);
	goto l_Exit;
l_ErrorLock:
	k_DPrint("SystemError[ID=0003](lock errno=%d\n)\n", errno);
	goto l_Exit;
l_EFIFOOpen:
	k_DPrint("SystemError[ID=0004](open errno=%d)\n", errno);
	goto l_Exit;
l_EMKFifo:
	k_DPrint("SystemError[ID=0013]\n");
	goto l_Exit;
} 

//================================================
//  MainLoop
//================================================
static void k_MainLoop(void)
{
	int 	FuncRet;
	int		RecvLen;
	fd_set	SReadFs;
	char 	TempBuf[256];
	int 	ii;
	int 	Status;

	FuncRet = k_RS_Open();
	if(FuncRet < 0)
		goto l_EOpen;
	FuncRet = k_SendDmy();
	if(FuncRet != 0)
		goto l_SendDmy;
	FuncRet = k_SetRate();
	if(FuncRet != 0)
		goto l_SetRate;
	FuncRet = k_Report();	if(FuncRet != 0)
		goto l_Report;
		while(1)
	{
		FD_ZERO(&SReadFs);
		FD_SET(g_SERISH, &SReadFs);
		select(g_SERISH + 1, &SReadFs, NULL, NULL, NULL);
		if(FD_ISSET(g_SERISH, &SReadFs))
		{
			while(1)
			{
				RecvLen = k_RS_Read(TempBuf, sizeof(TempBuf));
				if(RecvLen <= 0)
				{
					Status = 0;
					break;
				}
				for(ii = 0; ii < RecvLen; ii++)
				{
					if(Status == 0)
					{
						if(!(TempBuf[ii] & 0x80))
							continue;
						else
						{
							k_HandlerTP(TempBuf[ii]);	/* 僷働僢僩僨乕僞偑婣傞偙偲偼偁傝偊側偄 */
							Status++;
						}
					}
					else
					{
						FuncRet = k_HandlerTP(TempBuf[ii]);
						if(0 < FuncRet)
						{
							k_Write_PS2Packet(FuncRet);
							Status = 0;
						}
					}
				}
			}
		}
	}

l_Exit:
	k_RS_Close();
	close(g_FIFOSH);
	return;
l_EOpen:
l_SendDmy:
l_SetRate:
l_Report:	goto l_Exit;
}

//================================================
//  k_SendDmy
//================================================
static int k_SendDmy(void)
{
	char Val = 0xFF;
	int FuncRet;

	FuncRet = k_RS_Write(&Val, sizeof(Val));
	if(FuncRet < 0)
		goto l_WErr;
	
	usleep(1000*10);		//sleep 10ms
	
l_Exit:
	return 0;
l_WErr:
	FuncRet = -1;
	goto l_Exit;
}
//================================================
//  k_SetRate
//================================================
static int k_SetRate(void)
{
	unsigned char Val[2];
	int FuncRet;
	int RecvLen = 0; 

	Val[0] = 0x8B;
	Val[1] = g_TPProf.SamplingRate;

	FuncRet = k_RS_Write(Val, sizeof(Val));
	if(FuncRet < 0)
		goto l_WErr;
	
	while(RecvLen != 2)
	{
		FuncRet = k_RS_Read(Val + RecvLen, sizeof(Val) - RecvLen);
		if(0 <= FuncRet)
			RecvLen += FuncRet;
		else 
			goto l_ESetRate;
		
		if(RecvLen == 2)
		{
			if(((Val[0] == 0x90) ||( Val[0] == 0xD0)) && (Val[1] == 0x00))
			  	 FuncRet = 0;
			else
				goto l_ESetRate;
		}
	}
		
l_Exit:
	return FuncRet;
l_WErr:
	FuncRet = -1;
	goto l_Exit;
l_ESetRate:
	k_DPrint("SystemError[ID=0005]\n");	
	k_Dump("Recv", Val, FuncRet);
	FuncRet = -1;
	goto l_Exit;
	
}
//================================================
//  k_Report
//================================================
static int k_Report(void)
{
	unsigned char Val[16];
	int FuncRet;
	int RecvLen = 0;

	Val[0] = 0x88;

	FuncRet = k_RS_Write(Val, 1);
	if(FuncRet < 0)
		goto l_WErr;
	
	while(RecvLen != 9)
	{
		FuncRet = k_RS_Read(Val + RecvLen, 9 - RecvLen);
		if(0 <= FuncRet)
			RecvLen += FuncRet;
		else 
			goto l_EReport;
		
		if(RecvLen == 9)
		{
			if(((Val[0] == 0x90) ||( Val[0] == 0xD0)) && (Val[1] == 0x00))
			{
				g_TPProf.MAX_X_VAL = Val[5] + ((Val[6]&0x3F) << 7);
				g_TPProf.MAX_Y_VAL = Val[7] + ((Val[8]&0x3F) << 7);
				FuncRet = 0;
			}
			else
				goto l_EReport;	
		}
	}		
l_Exit:
	return FuncRet;
l_WErr:
	FuncRet = -1;
	goto l_Exit;
l_EReport:
	k_DPrint("SystemError[ID=0006]\n");
	k_Dump("Recv", Val, FuncRet);
	FuncRet = -1;
	goto l_Exit;	
}

/*============================================================================
*		PS/2 Mouse Movement Packet
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*	    BYTE1 |YOver|XOver|YSign|XSign|  1  |M Btn|R Btn|L Btn|
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*	    BYTE2 |				      X Movement    			  |
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*	    BYTE3 |				      Y Movement			   	  |
*             +-----+-----+-----+-----+-----+-----+-----+-----+
*-----------------------------------------------------------------------------*/

/*===================================================================
*	k_HandlerTP
*
*	堷悢
*		val	僞僢僠僷僱儖偐傜偺嵗昗僨乕僞
*	栠傝抣
*		PS2僷働僢僩姰惉悢	
*--------------------------------------------------------------------*/
static int k_HandlerTP(unsigned char val)
{
	int RetValue = 0;
	int TempX;
	int TempY;
	int FuncRet;
	int  ii;
	int  LastRecFlg = 0;

	if(val & 0x80)		//recv data header
	{
		g_MouseStat.rawstat = D_STATUS;	//reset rawstat
		g_MouseStat.CurrentRaw[g_MouseStat.rawstat]   = val;
		g_MouseStat.rawstat++;			//goto next rawstat
	}
	else	//coordinate data
	{
		g_MouseStat.CurrentRaw[g_MouseStat.rawstat] = val;
		g_MouseStat.rawstat++;
		if(g_MouseStat.rawstat == D_RAWSTAT_MAX)
		{
			memset(g_ps2Packet, 0x00, sizeof(t_ps2Packet)*32);

			TempX  = g_MouseStat.CurrentRaw[D_XL];
			TempX += g_MouseStat.CurrentRaw[D_XH] << 7;

			TempY  = g_MouseStat.CurrentRaw[D_YL];
			TempY += g_MouseStat.CurrentRaw[D_YH] << 7;

			TempX = (TempX*g_TPProf.X_Resolution)/g_TPProf.MAX_X_VAL;
			TempY = (TempY*g_TPProf.Y_Resolution)/g_TPProf.MAX_Y_VAL;

			FuncRet = k_ConvertPS2XYData(TempX, TempY);

			switch(g_MouseStat.BtnStat)
			{
			case 0:	//墴壓懸偪
				switch(g_MouseStat.CurrentRaw[D_STATUS] & 0x03)
				{
				case D_MAKE:
					if(0 < FuncRet)
					{
						g_ps2Packet[FuncRet-1].Botton |= 0x01;	//嵍儃僞儞ON
						RetValue = FuncRet;
					}
					else
					{
						g_ps2Packet[0].Botton |= 0x01;	//嵍儃僞儞ON
						RetValue = 1;					
					}	
					
					if(g_TPProf.mode == D_STREAMMODE)
					{	//僗僩儕乕儉儌乕僪夝曻懸偪傊
						g_MouseStat.BtnStat = 1;
					}
					else
					{	//億僀儞僩儌乕僪夝曻懸偪傊
						g_MouseStat.BtnStat = 2;
					}
					LastRecFlg = 1;
					break;
				default:
					k_DPrint("BtnStat %d \n", g_MouseStat.BtnStat);
					k_Dump("Recv", g_MouseStat.CurrentRaw, 5);
					break;
				
				}
				break;
			case 1:	//僗僩儕乕儉儌乕僪夝曻懸偪
				switch(g_MouseStat.CurrentRaw[D_STATUS] & 0x03)
				{
				case D_MAKE:
				case D_BODY:
					for(ii = 0; ii < FuncRet; ii++)
						g_ps2Packet[ii].Botton |= 0x01;	//嵍儃僞儞ON
					RetValue = FuncRet;
					LastRecFlg = 1;
					break;
				case D_BREAK:
					if(0 < FuncRet)
					{
						for(ii = 0; ii < FuncRet; ii++)
							g_ps2Packet[ii].Botton |= 0x01;	//嵍儃僞儞ON
						g_ps2Packet[FuncRet-1].Botton &= 0xFE;	//嵟屻偺僷働僢僩偱儃僞儞夝曻
						// 墴壓懸偪傊
						g_MouseStat.BtnStat = 0;
						RetValue = FuncRet;
					}
					else
					{
						g_ps2Packet[0].Botton &= 0xFE;	//嵟屻偺僷働僢僩偱儃僞儞夝曻					
						g_MouseStat.BtnStat = 0;
						RetValue = 1;		//儃僞儞夝曻捠抦偺1僷働僢僩傪憲傞
					}
					LastRecFlg = 1;
					break;
				default:
					k_DPrint("BtnStat %d \n", g_MouseStat.BtnStat);
					k_Dump("Recv", g_MouseStat.CurrentRaw, 5);
					break;
				}

				break;
			case 2:	//億僀儞僩儌乕僪夝曻懸偪
				switch(g_MouseStat.CurrentRaw[D_STATUS] & 0x03)
				{
				case D_MAKE:
				case D_BODY:
					//墴壓帪偺嵗昗偱捠抦偡傞(堏摦搙侽)
					g_ps2Packet[0].X = 0;
					g_ps2Packet[0].Y = 0;
					g_ps2Packet[0].Botton = 0x04;
					//埲屻柍帇偡傞偨傔偵夝曻傑偪傊
					g_MouseStat.BtnStat = 3;
					RetValue = 1;
					break;
				case D_BREAK:
					//墴壓帪偺嵗昗偱捠抦偡傞(堏摦搙侽)
					g_ps2Packet[0].X = 0;
					g_ps2Packet[0].Y = 0;
					g_ps2Packet[0].Botton = 0x04;
					//墴壓傑偪傊
					g_MouseStat.BtnStat = 0;
					RetValue = 1;
					break;
				default:
					k_DPrint("BtnStat %d \n", g_MouseStat.BtnStat);
					k_Dump("Recv", g_MouseStat.CurrentRaw, 5);
					break;
				}
				break;
			case 3: //億僀儞僩儌乕僪夝曻捠抦屻BREAK懸偪
				RetValue = 0;//偡偱偵夝曻捠抦偟偨偺偱杮摉偺夝曻偑棃傞傑偱柍帇偡傞
				switch(g_MouseStat.CurrentRaw[D_STATUS] & 0x03)
				{
				case D_BREAK:
					g_MouseStat.BtnStat = 0;
					break;
				case D_MAKE:
				case D_BODY:
					break;
				default:
					k_DPrint("BtnStat %d \n", g_MouseStat.BtnStat);
					k_Dump("Recv", g_MouseStat.CurrentRaw, 5);
					break;
				}
				break;
			default:
					k_DPrint("BtnStat %d \n", g_MouseStat.BtnStat);
					k_Dump("Recv", g_MouseStat.CurrentRaw, 5);
				break;
			}

			g_MouseStat.rawstat = D_STATUS;
			if(LastRecFlg == 1)
			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -