OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mw/] [src/] [drivers/] [mou_yopy.c] - Rev 1772

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * Microwindows touch screen driver for G.Mate YOPY
 *
 * Copyright (c) 2000 Century Software Embedded Technologies
 *
 * Requires /dev/yopy-ts kernel mouse driver.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <sys/ioctl.h>
#include "device.h"
 
/* file descriptor for touch panel */
static int pd_fd = -1;
 
/* Hack extern to used when hiding the mouse cursor
 * There needs to be a better way to do this
*/
extern SCREENDEVICE scrdev;
 
static int cal[7];
 
typedef struct {
        int x, y;
} XYPOINT;
 
#define TRANSFORMATION_UNITS_PER_PIXEL 4
static int GetPointerCalibrationData(void)
{
  /*
   * Read the calibration data from the calibration file.
   * Calibration file format is seven coefficients separated by spaces.
   */
 
  /* Get pointer calibration data from this file */
  const char cal_filename[] = "/etc/ts.conf";
 
  int items;
 
  FILE* f = fopen(cal_filename, "r");
  if ( f == NULL )
    {
      EPRINTF("Error %d opening pointer calibration file %s.\n",
	      errno, cal_filename);
      return -1;
    }
 
  items = fscanf(f, "%d %d %d %d %d %d %d",
		 &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5], &cal[6]);
  if ( items != 7 )
    {
      EPRINTF("Improperly formatted pointer calibration file %s.\n",
	      cal_filename);
      return -1;
    }
 
#ifdef TEST
  EPRINTF("a=%d b=%d c=%d d=%d e=%d f=%d s=%d\n",
	  cal[0], cal[1], cal[2], cal[3], cal[4], cal[5], cal[6]);
#endif
 
  return 0;
}
 
static XYPOINT DeviceToScreen(XYPOINT p)
{
  /*
   * Transform device coordinates to screen coordinates.
   * Take a point p in device coordinates and return the corresponding
   * point in screen coodinates.
   * This can scale, translate, rotate and/or skew, based on the coefficients
   * calculated above based on the list of screen vs. device coordinates.
   */
 
  static XYPOINT prev;
  /* set slop at 3/4 pixel */
  const short slop = TRANSFORMATION_UNITS_PER_PIXEL * 3 / 4;
  XYPOINT new, out;
 
  /* transform */
  new.x = (cal[0] * p.x + cal[1] * p.y + cal[2]) / cal[6];
  new.y = (cal[3] * p.x + cal[4] * p.y + cal[5]) / cal[6];
 
  /* hysteresis (thanks to John Siau) */
  if ( abs(new.x - prev.x) >= slop )
    out.x = (new.x | 0x3) ^ 0x3;
  else
    out.x = prev.x;
 
  if ( abs(new.y - prev.y) >= slop )
    out.y = (new.y | 0x3) ^ 0x3;
  else
    out.y = prev.y;
 
  prev = out;
 
  return out;
}
 
static int PD_Open(MOUSEDEVICE *pmd)
{
  /*
   * open up the touch-panel device.
   * Return the fd if successful, or negative if unsuccessful.
   */
 
  pd_fd = open("/dev/yopy-ts", O_NONBLOCK);
  if (pd_fd < 0) {
    EPRINTF("Error %d opening touch panel\n", errno);
    return -1;
  }
 
  GetPointerCalibrationData();
  GdHideCursor(&scrdev);
 
  return pd_fd;
}
 
static void PD_Close(void)
{
  /* Close the touch panel device. */
  if (pd_fd >= 0)
    close(pd_fd);
  pd_fd = -1;
}
 
static int PD_GetButtonInfo(void)
{
  /* get "mouse" buttons supported */
  return MWBUTTON_L;
}
 
static void PD_GetDefaultAccel(int *pscale,int *pthresh)
{
  /*
   * Get default mouse acceleration settings
   * This doesn't make sense for a touch panel.
   * Just return something inconspicuous for now.
   */
  *pscale = 3;
  *pthresh = 5;
}
 
 
static int PD_Read(MWCOORD *px, MWCOORD *py, MWCOORD *pz, int *pb)
{
  /* read a data point */
 
  unsigned long data;
  int bytes_read;
 
  XYPOINT transformed;
 
  bytes_read = read(pd_fd, &data, sizeof(data));
 
  if (bytes_read != sizeof(data)) {
    if (errno == EINTR || errno == EAGAIN) {
      return 0;
    }
    return 0;
  }
 
  transformed.x = (data & 0x3ff);
  transformed.y = (data >> 10) & 0x3ff;
 
  transformed = DeviceToScreen(transformed);
 
  transformed.x >>= 2;
  transformed.y >>= 2;
 
  *px = transformed.x;
  *py = transformed.y;
 
  *pb = (((data >> 31) & 0x1) ? MWBUTTON_L : 0);
 
  *pz = 0;
 
  if(! *pb )
    return 3;			/* only have button data */
  else 
    return 2;			/* have full set of data */
}
 
MOUSEDEVICE mousedev = {
  PD_Open,
  PD_Close,
  PD_GetButtonInfo,
  PD_GetDefaultAccel,
  PD_Read,
  NULL
};
 
#ifdef TEST
int main(int argc, char ** v)
{
  MWCOORD x, y, z;
  int	b;
  int result;
  int mouse = -1;
  DPRINTF("Opening touch panel...\n");
 
  if((result=PD_Open(0)) < 0)
    DPRINTF("Error %d, result %d opening touch-panel\n", errno, result);
 
  while(1) {
    result = PD_Read(&x, &y, &z, &b);
    if( result > 0) {
      if(mouse != b) {
	mouse = b;
	if(mouse) 
	  DPRINTF("Pen Down\n");
	else
	  DPRINTF("Pen Up\n");
      }
      DPRINTF("%d,%d,%d,%d,%d\n", result, x, y, z, b);
    }
  }
}
#endif
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.