/*********************************************
Project :PowerGlove LinkBox
Version : 
Date    : 11/25/2001
Author  : Unknown
Company : 
Comments: ATmega163L is too slow.  Need a 8Mhz system for this project. 



Chip type           : ATmega163   
Clock frequency     : 8.000000 MHz
Memory model        : Small
Internal SRAM size  : 1024
External SRAM size  : 0
Data Stack size     : 256
*********************************************/

#include <mega163.h>
#include <delay.h>


/*MB1-MouseByte Register Bit def. */
#define  M1X 7
#define  M1Y 6
#define  LB  5
#define  RB  4
#define  Y7  3
#define  Y6  2
#define  X7  1
#define  X6  0
/*MB2*/
#define  M2X 7
#define  M2Y 6
#define  X5  5
#define  X4  4
#define  X3  3
#define  X2  2
#define  X1  1
#define  X0  0
/*MB3*/
#define  M3X 7
#define  M3Y 6
#define  Y5  5
#define  Y4  4
#define  Y3  3
#define  Y2  2
#define  Y1  1
#define  Y0  0



/*PortC Registers*/
/*Data Direction Register DDRC*/
#define   DDC7  7
#define   DDC6  6
#define   DDC5  5
#define   DDC4  4 
#define   DDC3  3
#define   DDC2  2
#define   DDC1  1
#define   DDC0  0   
/*Data Register*/ 
#define   PORTC7  7
#define   PORTC6  6
#define   PORTC5  5
#define   PORTC4  4
#define   PORTC3  3
#define   PORTC2  2
#define   PORTC1  1
#define   PORTC0  0
 

/* Input Pins */
//Port C
#define   PINC7  7
#define   PINC6  6
#define   PINC5  5
#define   PINC4  4
#define   PINC3  3
#define   PINC2  2
#define   PINC1  1
#define   PINC0  0 

//gdata register
#define   sevenbit 7
#define   sixbit   6
#define   fivebit  5
#define   fourbit  4
#define   threebit 3
#define   twobit   2
#define   onebit   1
#define   zerobit  0


/*UART Control Register Bit Definitions */
#define		RXCIE		7
#define		TXCIE		6
#define		UDRIE		5	
#define		RXEN		4
#define		TXEN		3
#define		CHR9		2
#define		RXB8		1
#define		TXB8		0    

/*  UART Status Register Bit Definitions */
#define 	RXC		7
#define		TXC		6
#define		UDRE		5
#define		FE		4
#define		OR		3  

//IBM glove code
#define   D2BYTES 145     //145 is 0g
#define   D2BITS  5       //5 is og
#define   D2SLOW  13500   // 13400 is lower limit. Anylower and it glitches
                          // 13500 works good except for center button
                          // 13700 is upper limit. Glitches above this. 

// Declare your global variables here
//Mouse code 
unsigned char MB1=0xC0;  //defines and sets up MouseBytes with constant header bits.
unsigned char MB2=0x80;
unsigned char MB3=0x80;
//unsigned char x1=0;
//unsigned char y1=0;
//unsigned char Mback1=0xC0;  //Buttons plus x,y upper bits
//unsigned char Mback2=0x80;  //main x mouse byte
//unsigned char Mback3=0x80;  //main y mouse byte
//Powerglovecode
register unsigned char y=0;




/*Prtototypes*/
//UART
void InitUART( unsigned char baudrate );
void TransmitByte( unsigned char data );
//Mouse
void Mouse_send(unsigned char x,unsigned char y, unsigned char z);
void Convert_pos(void);
void Convert_fin(void); //convert fingers
//PGlove
void Hi_Res(void);
unsigned char getbyte(void);
unsigned char getglove(void);
float gdata[12];




 
//Powerglove Functions
void Hi_Res(void)
{
 int hi_res_codes[] = {0x06, 0xC1, 0x08, 0x00, 0x02, 0xFF, 0x01}; //code to set PG to HI_RES mode
 int t,x,j;
  //Reset pulse
 PORTC=0x01;
 PORTC=0x03;
 delay_us (D2BITS);
 PORTC=0x02;
 //read four bits and discard
 delay_us (D2BITS);
 PORTC=0x00;
 PORTC=0x01;
 delay_us (D2BITS);
 PORTC=0x00;
 PORTC=0x01;
 delay_us (D2BITS);
 PORTC=0x00;
 PORTC=0x01;
 delay_us (D2BITS);
 PORTC=0x00;
 PORTC=0x01;
 //Establish communication
 PORTC=0x01;
 delay_us (7212);
 PORTC=0x03;
 delay_us (2260);
 //Send 7 Bytes
for (t=0;t<7;t++)
 { x = hi_res_codes[t];
   for (j=0;j<8;j++)
   {
   if (x & 0x80)
   {
    PORTC=0x03;
    PORTC=0x02;
    PORTC=0x03;
    }
   else
   {
    PORTC=0x01;
    PORTC=0x00;
    PORTC=0x01;
    }
    x =x<<1;
    delay_us(D2BITS);
    }
    delay_us (D2BYTES);
  }
  delay_us (892);
  PORTC=0x01;
  delay_us (40000);
  }
 

unsigned char getglove(void)
{
 unsigned char v=0;
 for (v=0;v<8;v++)               
        {                               
        gdata[v]=getbyte();  //stores data into a array which can be accessed later.
        
        delay_us (D2BYTES);
         }
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
         getbyte();
         delay_us(D2SLOW);
}


unsigned char getbyte(void)
{
register int k;
register unsigned char gread=0;
PORTC=0x01;
PORTC=0x03;
delay_us (D2BITS);
PORTC=0x01;

for(k = 0; k < 8; k++)  //Leave at 8 without it at this value, A0 header byte is read incorrectly.
 {
 gread= ((gread << 1) + PINC.2);
 PORTC=0x00;
 delay_us(D2BITS);   //These delays match perfect with builder.exe program
 PORTC=0x01;
 delay_us(D2BITS); 
 }      
 return gread;
} 


/*UART Functions*/
void InitUART( unsigned char baudrate)
 {
 UBRR= baudrate;
 UCSRB=(1<<TXEN);
 }
 
 void TransmitByte(unsigned char data)
 {
  while ( !(UCSRA & (1<<UDRE)))
    ;
    UDR=data;
  }


//Mouse functions 
void Mouse_send(unsigned char x, unsigned char y, unsigned char z)
{
  if (PIND.3)  /*only sends "M" when requested.*/
      {
      delay_ms(16);
      TransmitByte(77);  /* Send "M" char to tell computer this is a mouse */ 
      } 
      if (!PIND.3)//If system is not searching for mouse then transmit data
      {
      
         TransmitByte(x);
         TransmitByte(y);
         TransmitByte(z);
       	
      } 
}

void Convert_pos(void)
{
/* int d1=0; //x
 int d2=0; //y
 
 d1=x1-gdata[1];
 d2=y1-gdata[2];
 
 if (d1>0)
 {
  MB1=((1<<M1X)|(1<<M1Y)|(1<<X7)|(1<<X6));
  MB2=0x8E;  //moves mouse left 2 at a time
 }
 if (d1<0)
 {
  MB1=((1<<M1X)|(1<<M1Y)|(0<<X7)|(0<<X6));
  MB2=0x82;  //moves mouse right 2 at a time
 }
 if (d1=0)
 {
   MB1=Mback1;
   MB2=Mback2;   //Dont move mouse
 }
 
 if (d2>0)
 {
  MB1=((1<<M1X)|(1<<M1Y)|(0<<Y7)|(0<<Y6));
  MB3=0x82;    //moves mouse down 2 at a time
 }
 if (d2<0)
 {
  MB1=((1<<M1X)|(1<<M1Y)|(1<<Y7)|(1<<Y6));
  MB3=0x8E;   //moves mouse up 2 at a time
 }
 if (d2=0)
 {
  MB1=Mback1;
  MB3=Mback3;   //dont move mouse
 }
 x1=gdata[1];       //Store backups for next loop
 y1=gdata[2];
 Mback1=MB1;
 Mback2=MB2;
 Mback3=MB3;
     */
} 

void Convert_fin(void)
{
// if (gdata[5]>0x40 && gdata[5],0xC1)
//   {
//    MB1=(1<<RB);
//   }
// if (gdata[5]<0x40 && gdata[5]>16)
//   {
//    MB1=(1<<LB);
//   }
// if (gdata[5]<16)
//   {
//    MB1=((0<<LB)|(0<<RB));
//   }
}   

void main(void)
{
DDRC.0=1; //Sets DDC0(Data_Clk) and DDC1(Latch) as output pins
DDRC.1=1;
DDRC.2=0; //Sets DDC2(Data) as input pin 


InitUART(103);   /*Sets BuadRate at 9600.  103=4800  51=9600 207=2400 414=1200(may not be valid)*/
//delay_ms(500);//delay for hi_res
Hi_Res();
//delay_ms(500);  //Put the glove in HI_RES mode

while (1)
      {
      // MB1=((1<<M1X)|(1<<M1Y)|(0<<LB)|(0<<RB)|(0<<Y7)|(0<<Y6)|(0<<X7)|(0<<X6));   
      // MB2=((1<<M2X)|(0<<M2Y)|(0<<X5)|(0<<X4)|(0<<X3)|(0<<X2)|(0<<X1)|(0<<X0));   
      // MB3=((1<<M3X)|(0<<M3Y)|(0<<Y5)|(0<<Y4)|(0<<Y3)|(0<<Y2)|(0<<Y1)|(0<<Y0));   
      //Glove code
        
      getglove();  //retreives 8 bytes of data and stores in array. 
      
     // if (PIND.4)
     // {//This transmits mouse mode
     //  Convert_pos();
     //  Convert_fin();
     //  Mouse_send(MB1,MB2,MB3);
     // }
     // else
     // {//This transmits raw data  
         for (y=0;y<8;y++)
         {
         TransmitByte(gdata[y]);
         }
     // }
      
      };
}