发信人: yexunkai(叶云)
整理人: wenbobo(2003-09-19 09:19:22), 站内信件
|
一个ELO E281-2310触摸屏的驱动程序
/*
*******************************************************************************
* Updated by Cloud Yip for embedding on qt-embedded 3.1.2
*******************************************************************************
*/
/*
* Filename: EloTouch.cpp
* Author: Phil Brooks
* Date: 06/25/2002
* Purpose: - RS-232 driver for Elo touch screen
*
* Copyright (c) 2002 - Olympic Medical Corp.
*/
/*
* $Log: EloTouch.cpp,v $
* Revision 1.2 2002/07/03 15:49:16 philb
* Cleaned up code.
*
* Revision 1.1.1.1 2002/06/25 22:08:12 philb
* Elo Touch driver for Embedded QT. Also includes stand alone test driver.
* From xf86 driver.
*
*/
/*
*******************************************************************************
*******************************************************************************
*
* This driver is able to deal with Elographics SmartSet serial controllers.
* It uses only a subset of the functions provided through the protocol.
*
* SUPPORT FOR E281-2310 and compatible controllers added with help of:
* 1996/01/17 Juergen P. Meier ([email protected]) and
* 1998/03/25 [email protected]
*
* The E281-2310 is a somewhat lobotomized 2210.
* It does not support the c,g,h,k,l,p,q,s and t commands.
* Especially the P command, which is used to check the baud rate.
* The E281-2310 however semms to use always 9600bps, 8bit, 1stop
* no parity, Hardwarehandshake (RTS-CTS) (which are the drivers
* default values)
*
*******************************************************************************
*******************************************************************************
*/
#include <unistd.h>
#include <errno.h>
#define TRUE 1
#define FALSE 0
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#define NEED_EVENTS
#include <errno.h>
#include <termio.h>
#include <fcntl.h>
#include <ctype.h>
#include "EloTouch.h"
/*
***************************************************************************
*
* Usefull macros.
*
***************************************************************************
*/
#define ErrorF printf
#define WORD_ASSEMBLY( byte1, byte2 ) ( ( ( byte2 ) << 8 ) | ( byte1 ) )
#define SYSCALL( call ) while ( ( ( call ) == -1 ) && ( errno == EINTR ) )
#ifdef DBG
#undef DBG
#endif
#ifdef DEBUG
#undef DEBUG
#endif
#define DEBUG 1
#if DEBUG
#define DBG( lvl, f ) { if ( ( lvl ) <= debug_level ) f; }
#else
#define DBG( lvl, f )
#endif
#define TEST 1
static int debug_level = 0;
/*
***************************************************************************
*
* Main
*
***************************************************************************
*/
#ifdef TEST
main()
{
static int fd;
int x, y, state;
EloPrivateRec pElo;
fd = -1;
EloInit( &pElo );
EloControl( &pElo, &fd, ELO_DEVICE_INIT );
EloControl( &pElo, &fd, ELO_DEVICE_ON );
while( TRUE )
{
EloReadInput( &pElo, fd, &x, &y, &state );
usleep( 100 );
if ( x < 800 )
break;
}
EloControl( &pElo, &fd, ELO_DEVICE_OFF );
EloControl( &pElo, &fd, ELO_DEVICE_CLOSE );
}
#endif // TEST
/*
***************************************************************************
*
* EloGetPacket --
* Read a packet from the port. Try to synchronize with start of
* packet and compute checksum.
* The packet structure read by this function is as follow:
* Byte 0 : ELO_SYNC_BYTE
* Byte 1
* ...
* Byte 8 : packet data
* Byte 9 : checksum of bytes 0 to 8
*
* This function returns if a valid packet has been assembled in
* buffer or if no more data is available.
*
* Returns Success if a packet is successfully assembled including
* testing checksum. If a packet checksum is incorrect, it is discarded.
* Bytes preceding the ELO_SYNC_BYTE are also discarded.
* Returns !Success if out of data while reading. The start of the
* partially assembled packet is left in buffer, buffer_p and
* checksum reflect the current state of assembly.
*
***************************************************************************
*/
int EloGetPacket(unsigned char *buffer,int *buffer_p,int *checksum,int fd)
{
int num_bytes;
int ok;
DBG(4, printf("Entering EloGetPacket with checksum == %d and
buffer_p == %d, and fd = %d\n",*checksum, *buffer_p,fd));
/*
* Try to read enough bytes to fill up the packet buffer.
*/
DBG(4, printf("buffer_p is %d, Trying to read %d bytes from link\n",
*buffer_p, ELO_PACKET_SIZE - *buffer_p));
num_bytes = read(fd,(char *) (buffer + *buffer_p),
(ELO_PACKET_SIZE - *buffer_p));
/*
* Okay, give up.
*/
if (num_bytes < 0)
{
DBG(3,ErrorF("System error while reading from Elographics touchscreen."));
return FALSE;
}
DBG(3, printf("Read %d bytes\n", num_bytes));
while (num_bytes)
{
/*
* Sync with the start of a packet.
*/
if ((*buffer_p == 0) && (buffer[0] != ELO_SYNC_BYTE))
{
/*
* No match, shift data one byte toward the start of the buffer.
*/
memcpy(&buffer[0], &buffer[1], num_bytes-1);
}
else
{
/*
* Compute checksum in assembly buffer.
*/
if (*buffer_p < ELO_PACKET_SIZE-1)
{
*checksum = *checksum + buffer[*buffer_p];
*checksum = *checksum % 256;
DBG(4, printf(" 0x%X-->0x%X ", buffer[*buffer_p], *checksum));
}
(*buffer_p)++;
}
num_bytes--;
}
if (*buffer_p == ELO_PACKET_SIZE)
{
/*
* Got a packet, validate checksum and reset state.
*/
ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
DBG(4, printf("Expecting checksum %d, got %d\n", *checksum,
buffer[ELO_PACKET_SIZE-1]));
*checksum = ELO_INIT_CHECKSUM;
*buffer_p = 0;
if (!ok)
{
DBG(3,printf("Checksum error on Elographics touchscreen link\n"));
return FALSE;
}
/*
* Valid packet received report it.
*/
return TRUE;
}
else
{
return FALSE;
}
}
/*
***************************************************************************
*
* EloReadInput --
* Read all pending report packets from the touchscreen and enqueue
* them.
* If a packet is not fully received it is deferred until the next
* call to the function.
* Packets recognized by this function comply with the format:
*
* Byte 1 : ELO_TOUCH
* Byte 2 : Packet type
* Bit 2 : Pen Up (Release)
* Bit 1 : Position (Stream)
* Bit 0 : Pen Down (Press)
* Byte 3 : X coordinate (lower bits)
* Byte 4 : X coordinate (upper bits)
* Byte 5 : Y coordinate (lower bits)
* Byte 6 : Y coordinate (upper bits)
* Byte 7 : Z coordinate (lower bits)
* Byte 8 : Z coordinates (upper bits)
*
* Phil Brooks - 06/25/02 - Modified to return screen coord.
*
***************************************************************************
*/
void EloReadInput(EloPrivateRec *priv, int fd, int *nX, int *nY, int *nState)
{
int cur_x, cur_y;
int state;
int nDiv;
int width, height;
DBG(2, printf("Entering ReadInput\n"));
/*
* Try to get a packet.
*/
if (EloGetPacket(priv->packet_buf,&priv->packet_buf_p,&priv->checksum,fd) != TRUE)
{
return;
}
/*
* Process only ELO_TOUCHs here.
*/
if (priv->packet_buf[1] == ELO_TOUCH) {
/*
* First stick together the various pieces.
*/
*nX = WORD_ASSEMBLY(priv->packet_buf[3], priv->packet_buf[4]);
*nY = WORD_ASSEMBLY(priv->packet_buf[5], priv->packet_buf[6]);
*nState = priv->packet_buf[2] & 0x07;
cur_x = *nX;
cur_y = *nY;
state = *nState;
/*
* Send events.
*
* We *must* generate a motion before a button change if pointer
* location has changed as DIX assumes this. This is why we always
* emit a motion, regardless of the kind of packet processed.
*/
/*
* Emit a button press or release.
* ELO_PRESS | ELO_STREAM |ELO_RELEASE
if ( state == ELO_PRESS || state == ELO_RELEASE )
{
*nState = ELO_PRESS;
}
*/
// Transform to screen coord. for Trolltech Embedded QT
width = priv->max_x - priv->min_x;
height = priv->max_y - priv->min_y;
*nX = (priv->screen_width * (*nX - priv->min_x)) / width;
// *nY = (priv->screen_height -
*nY = (priv->screen_height * (*nY - priv->min_y)) / height;
*nX = (priv->screen_width - *nX);
DBG(2, printf("TouchScreen: x(%d), y(%d), %s\n",
cur_x, cur_y,
(state == ELO_PRESS) ? "Press" : ((state == ELO_RELEASE) ? "Release" : "Stream")));
}
}
/*
---- 有兴趣请直接寄信,
在下上线时间不定,
回应帖子也比较慢。
|
|