/********************************************************************************
*
* PROJECT:      Sieg Defense Platform (CSE 477, Spring 2000, Gene Ma, Gary Look,
*                              and Michael Dougherty)
*
* FILE:         touchvga.c
*
* DESCRIPTION:  Gets the touch coordinates from the touch screen using the serial
*               interrupts.  Scales the coordinates from 1900x1900 to 475x475
*               and sends the coordinates to the FPGA.
*
*********************************************************************************/

#pragma code

#include "reg51.h"
#include "NewXbus.h"
#include <stdlib.h>

#define BUF_SIZE 32    // size of input and output buffer

unsigned char ibuff[BUF_SIZE];
unsigned char obuff[BUF_SIZE];
unsigned char ihead,itail, ohead, otail;     // both head and tail point to valid data
unsigned char sending;
unsigned char recerror;
signed int currentX, currentY;               // current x and y coordinates
unsigned char fromTouch[5];                  // buffer to hold at most 5 bytes from touch screen

unsigned char getchar();
unsigned char putchar(unsigned char);
unsigned char userenqueue(unsigned char);
unsigned char userdequeue();
void getTouch(unsigned char);

void serialInterrupt ( void ) interrupt 4 using 1 {

 unsigned char interC;

    if (RI)
 {
  interC = SBUF;
  RI = 0;
 
  if(itail==-1) // enter first element into an empty queue
   {
   ibuff[0] = interC;
   ihead = 0;
   itail = 0;
   return;
   }

  if( ((itail+1)%BUF_SIZE) == ihead )
    {
            // input queue is full do nothing
   return;
   }
  else
   {
   itail = (itail+1)%BUF_SIZE;  // stuff the queue
   ibuff[itail] = interC;
   return;
   }
 }

 
 else //if(TI)
 {
  if(ohead == -1)  // queue is empty
  {
   sending = 0;
   TI = 0;
   return;
  }

  if(ohead == otail) // return LAST element in queue
  {
   SBUF = obuff[ohead];
   TI = 0;
   sending = 1;
   ohead = -1;
   otail = -1;
   return;
  }

  else    // return an element that's not the last in the queue
  {
   SBUF = obuff[ohead];
   TI = 0;
   sending = 1;
   ohead = (ohead + 1) % BUF_SIZE;
   return;
  }
    }

}
 

void init ( void ) {
  TMOD = 0x20;  // 0010_0000 disable timer0, use timer1 as a timer in auto-reload
  TCON = 0x40;  // 0100_0000 enable timer1
  TH1 = 243;    // timer 1 reload value
  SCON = 0x50;  // 0101_0010 mode 1, set TI initially to 0
  PCON |= 0x80; // set SMOD bit to not divide by 2

  // ****************************************************************************
  // Enable Interruppts
  // The IE register sets the state of the interrupt vectors.
  // Every bit in IE is for a different interrupt (see documentation for definition)
  //
  //(MSB)                               (LSB)
  // EAall  NA  ET2  ES  ET1  EX1  ET0  EX0
  //
  // ****************************************************************************

  IE = 0x90; // 1001_0000 enable serial port interrups
 
  sending = 0;
  ihead = -1;
  itail = -1;
  ohead = -1;
  otail = -1;
}
 

void main() {

  unsigned char c;
 

  init();
  while (1)
  {
      // wait till we get the next byte from the touch screen
      while ( (c = getchar()) == 0 );
      // for debug purposes - print out the byte
   while ( putchar(c) == 0 );
      // check if the byte from the touch screen is a header byte
      // and if so do processing
   getTouch(c);
  }
 

}
 

unsigned char getchar()
{
 unsigned char c;
 EA = 0;
 c = userdequeue();

 if(!c) // buffer is empty
 {
  EA = 1;
  return 0;
 }
 else  // there's something in the buffer just return it
 {
  EA = 1;
  return c;
 }
 
}
 

unsigned char putchar(unsigned char c)
{
 EA = 0;
 if( !(userenqueue(c)) ) // buffer is full, so can't put anything in it
 {
  EA = 1;
  return 0;
 }
 else     // else, there's space in the buffer to put a char
 {
  if(!sending)
   TI = 1;

  EA = 1;
  return 1;
 }
}

unsigned char userenqueue(unsigned char input)
{
 if(otail==-1) // enter first element into an empty queue
 {
  obuff[0] = input;
  ohead = 0;
  otail = 0;
  return 1;
 }

 if( ((otail+1)%BUF_SIZE) == ohead )
  return 0;  // queue is full

 else
 {
  otail = (otail+1)%BUF_SIZE;  // stuff the queue
  obuff[otail] = input;
  return 1;
 }
}
 

unsigned char userdequeue()
{
 unsigned char c;

 if(ihead == -1)  // queue is empty
  return 0;

 if(ihead == itail) // return LAST element in queue
 {
  c = ibuff[ihead];
  ihead = -1;
  itail = -1;
  return c;
 }

 else    // return an element that's not the last in the queue
 {
  c = ibuff[ihead];
  ihead = (ihead + 1) % BUF_SIZE;
  return c;
 }
}
 

void getTouch(unsigned char c)
{
    int i = 1; // counter
 unsigned char temp;
 unsigned char hexZero = 0x00;

 fromTouch[0] = c;  // place byte into temp buffer

    if (c == 0xC2) // 0xC2 - screen touch
 {
     // then place the bytes from touch into touch screen buffer
  for (i = 1; i < 5; i++)
  {
   while((temp = getchar()) == 0);  // get byte
      while(putchar(temp) == 0);
   fromTouch[i] = temp;
  }

     // Convert the info from touch screen into coordinates
  // For touches the header byte is 0xC2
  if (fromTouch[3] == 0xC2)  // 3 bytes from Touch Screen
  {
            // storing into 16-bit int value - since all low order bits no shifting needed
   // need to shift left 1-bit because we were dropping a bit for some reason
   currentX = fromTouch[1]<<1;
   currentY = fromTouch[2]<<1;
  }

  else if (fromTouch[4] == 0xC2) // 4 bytes from Touch Screen
  {
   if (fromTouch[1] < 20) // then the 1st two bytes are for X - changed to 20 from 7
   {
                /* 2 bytes for X and 1 for Y */
       // need to shift left 1, on the lower byte because we were dropping a bit for some reason
    currentX = (fromTouch[1] << 8) + (fromTouch[2]<<1);
    currentY = fromTouch[3]<<1;
   }
   else  // then last two bytes are for Y
   {
    // 1 byte for X and 2 for Y
                // need to shift left 1, on the lower byte because we were dropping a bit for some reason
    currentX = fromTouch[1]<<1;
    currentY = (fromTouch[2] << 8) + (fromTouch[3]<<1);
   }
  }
  else // 2 bytes for X and 2 bytes for Y
  {
      // need to shift left 1, on the lower byte because we were dropping a bit for some reason
   currentX = (fromTouch[1] << 8) + (fromTouch[2] << 1);
   currentY = (fromTouch[3] << 8) + (fromTouch[4] << 1);
  }

  // scaling - divide by 4
  currentX = currentX >> 2  ;
  currentY = currentY >> 2  ;
 
     // shift back into 4 bytes instead of 2 16-bit unsigned ints
  uConSend(currentX >> 8 & 0xff);  // high order bits for X coordinate
  uConSend(currentX & 0xff);       // low order bits for X coordinate
  uConSend(currentY >> 8 & 0xff);  // high order bits for Y coordinate
  uConSend(currentY & 0xff);       // low order bits for Y coordinate

 } // end if header byte encountered
}
 
 
 

Back to Report