#include <Mega32.
h>
#include <stdio.h> // sprintf
#include <delay.h>
/*D - Input/Output to Computer
*
D.1 - Output Clock
*
D.3 - Input Clock
*
D.6 - Output Data
*
D.4 - Input Data
*/
//define some useful maps to bits
#define CLK_OUT PORTC.1 //
#define DATA_OUT PORTC.6
#define CLK_IN PINC.3
#define DATA_IN PINC.4
//#define VCC_IN PINA.4
//define PS/2 data line states
#define IDLE 0
#define INHIBIT 1
#define BUSY 2
#define WAIT_FOR_REQUEST 3
#define REQUEST 4
#define POWEROFF 5
// boolean defines
#define TRUE 1
#define FALSE 0
unsigned char Ytilt, Xtilt, Button0, Button1, ScrollState;
//ScrollState 1 => scrolling.
//ScrollState 0 => button pushing.
signed char Xmove, Ymove, timetemp, OldXmove, OldYmove;
unsigned int time, Button0pushed, Button1pushed, ButtonTimeDiff;
// byte declarations
unsigned char byte_index;
unsigned char transmit_byte;
unsigned char transmit_parity;
unsigned char receive_byte;
unsigned char receive_bit;
unsigned char previous_byte;
unsigned char resend_byte;
// clock
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
state machine declarations
char clock_state;
char next_clock_state;
char mouse_state;
char transmit;
char receive;
char outInhibit, Xneg, Yneg;
// mouse packet declarations
unsigned char gen_mouse_packet;
unsigned int count;
#define RISE 0
#define HIGH 1
#define FALL 2
#define LOW 3
// queue declarations
#define QUEUELEN 200
unsigned char queue[QUEUELEN]; //queue of data sent by keyboard. (first in, firs
t out)
unsigned char queueFull;
//indicates if queue is full
unsigned char queueEmpty;//indicates if queue is empty
unsigned char queueIn;
//indicates where to put data into queue
unsigned char queueOut;
//indicates where to take data out of queue
// PS/2
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
Host Command set.
ERROR
RESET
RESEND
SET_DEFAULT
0xF6
DIS_DATA_REPORT 0xF5
EN_DATA_REPORT 0xF4
SET_SAMPLE_RATE 0xF3
GET_DEVICE_ID 0xF2
SET_REMOTE_MODE 0xF0
SET_WRAP_MODE 0xEE
RESET_WRAP_MODE 0xEC
READ_DATA
SET_STREAM_MODE 0xEA
STATUS_REQ
SET_RES
SET_SCALING21 0xE7
SET_SCALING11 0xE6
#define
#define
#define
#define
ACK
SELF_TEST_PASS 0xAA
INIT
SCALING21
// mouse
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
0xFC
0xFF
0xFE
OxEB
0xE9
0xE8
0xFA
0x00
0x02
declarations
char deviceID;
char data_reporting;
char sample_rate;
char scaling; // 0 = 1:1, 1 = 2:1
char resolution;
char waiting_for_sample_rate;
char waiting_for_resolution;
// data reporting declarations
unsigned char mouse_posX;
unsigned char mouse_posY;
signed char prev_byte1, prev_byte2, prev_byte3;
unsigned char left_button_click;
unsigned char middle_button_click;
unsigned char right_button_click;
unsigned char mouse_byte1;
char scroll_byte;
//RXC ISR variables
unsigned char r_index; //current string index
unsigned char r_buffer[32]; //input string
unsigned char r_ready; //flag for receive done
unsigned char r_char; //current character
//TX empty ISR variables
unsigned char t_index; //current string index
unsigned char t_ready; //flag for transmit done
unsigned char t_char; //current character
unsigned char t_buffer[32]; // output string
int temp;
unsigned char portb_cycle;
// Function prototypes
void gets_string(void); //starts getting a string from serial line
void puts_string(void); //starts a send to serial line
void initialize(void); //all the usual mcu stuff
// function prototypes
unsigned char queuePut(unsigned char);
unsigned char queueGet(void);
unsigned char getParity(unsigned char);
void process_command(unsigned char);
//UART character-ready ISR
interrupt [USART_RXC] void uart_rec(void) {
r_char=UDR; //get a char
UDR=r_char; //then print it
//build the input string
if (r_char != '\r') r_buffer[r_index++]=r_char;
else {
putchar('\n'); //use putchar to avoid overwrite
r_buffer[r_index]=0x00; //zero terminate
r_ready=1; //signal cmd processor
UCSRB.7=0; //stop rec ISR
}
}
//UART xmit-empty ISR
interrupt [USART_DRE] void uart_send(void) {
t_char = t_buffer[++t_index];
if (t_char == 0){
UCSRB.5=0; //kill isr
t_ready=1; //transmit done
}
else UDR = t_char ; //send the char
}
// -- non-blocking keyboard check initializes ISR-driven
// receive. This routine merely sets up the ISR, which then
//does all the work of getting a command.
void gets_string(void) {
r_ready=0;
r_index=0;
UCSRB.7=1;
}
// -- nonblocking print: initializes ISR-driven
// transmit. This routine merely sets up the ISR, then
//send one character, The ISR does all the work.
void puts_string(void) {
t_ready=0;
t_index=0;
if (t_buffer[0]>0) {
putchar(t_buffer[0]);
UCSRB.5=1;
}
}
// this interrupt should run every 20us or 1/4 period of the clock
interrupt [TIM0_COMP] void timer0_overflow(void)
{
if (timetemp >= 50){
timetemp = 0;
time++;
}
else timetemp++;
if (time >= 1000) time = 0;
if (queueEmpty == TRUE)
count++;
if (count >= 500)
// 100 samples a second
{
gen_mouse_packet = TRUE;
count = 0;
}
// state machine for transmitting a byte to Host
if(transmit){
// update the next clock state
clock_state = next_clock_state;
// do the appropriate command based on the state of the clock
switch (clock_state) {
case RISE:
// start or end a byte transmission
switch (byte_index) {
case 0:
// get a new byte to be xmitted
if (queueEmpty == FALSE) {
// get data off the queue to be xmitted
transmit_byte = queueGet
();
transmit_parity = getPar
ity(transmit_byte);
// print out transmit by
te to hyperterminal
//if (gen_mouse_packet =
= TRUE) {
//
printf("TRANSMIT
\n\r");
//}
//printf("%x\n\r", trans
mit_byte);
delay_us(150);
// used to wait until host is ready
}
break;
case 11:
// finished transmission
transmit = 0; // transmit fini
shed
byte_index = 0; // reset byte in
dex
break;
default:
break;
}
// set the new clock state
CLK_OUT = 1;
next_clock_state = HIGH;
break; // end of RISE
case HIGH:
// can begin writing data to host
// state machine ensure we transmit the correct
bit from the PS/2 byte
switch (byte_index) {
case 0:
DATA_OUT = 0;
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
DATA_OUT = transmit_byte & 0x01;
transmit_byte = transmit_byte >>
1;
break;
case 9:
DATA_OUT = transmit_parity;
break;
case 10:
DATA_OUT = 1;
break;
default:
break;
}
// update the byte index
byte_index++;
// update the clock state
next_clock_state = FALL;
break; // end of HIGH
case FALL: // clock transitions to low
CLK_OUT=0;
// pull
the clock to 0
next_clock_state = LOW; // set the next clock st
ate to low
break; // end of FALL
case LOW: // clock is low - nothing happens here
next_clock_state = RISE;
// next clock st
ate is rising
break; // end of RISE
}
}
if(receive) {
// get the next clock state
clock_state = next_clock_state;
switch (clock_state) {
case RISE:
// all receiving done on the rising edge
of the clock
CLK_OUT = 1;
// get the bit off the data line
// and place into the receive_byte
if (byte_index >=0 && byte_index < 8) {
receive_bit = DATA_IN;
receive_byte = ((receive_bit & 0x01) <<
byte_index) | receive_byte;
}
// update variables for the next state
if (byte_index < 11) {
next_clock_state = HIGH;
byte_index++;
}
break;
case HIGH:
switch (byte_index) {
case 10:
DATA_OUT = 0;
break;
case 11:
DATA_OUT = 1;
// send ACK
// terminate receive operation and reset
receive = 0;
byte_index = 0;
// process the received command
//PORTB.4 = 0x00;
process_command(receive_byte);
receive_byte = 0;
receive_bit = 0;
break;
default:
//if (byte_index == 1)
//
PORTB.4 = 0x0;
break;
}
next_clock_state = FALL;
break;
case FALL:
// hosts transmits on the falling edge
CLK_OUT = 0;
next_clock_state = LOW;
break;
case LOW:
next_clock_state = RISE;
//printf("BYTE: %c\n\r", byte_index);
break;
}
}
switch (mouse_state) {
case IDLE:
IN == 0)
// enter inhibt state if clock is trying to be pulled
// low by host when device is trying to make high
if ((clock_state == HIGH || clock_state == RISE) && CLK_
// host trying to pull CLK low!
{
mouse_state = INHIBIT; // go to the INHIBIT sta
te
next_clock_state = LOW;
// turn off the
transmit = 0;
// mouse can no
receive = 0;
// mouse can no
clock
longer transmit
longer receive
}
else { // check if mouse needs to be in BUSY state -- a
nything on queue?
if(queueEmpty == FALSE)
{
mouse_state = BUSY;
// transition to busy state
transmit = 1;
// allow mouse to transmit
receive = 0;
// make sure we don't receive!
next_clock_state = RISE;
// turn
on the clock
byte_index = 0;
// reset the byte index for transmit
}
else // otherwise we should just stay in IDLE
{
mouse_state = IDLE;
}
}
break;
case BUSY:
//PORTB.0 = 0x0;
// again check if host is trying to inhibt
// by pulling the clock low when it should be high
if ((clock_state == HIGH || clock_state == RISE) && CLK_
IN == 0)
{
mouse_state = INHIBIT; // go to the INHIBIT sta
te
next_clock_state = LOW;
// turn off the
transmit = 0;
// mouse can no
receive = 0;
// mouse can no
clock
longer transmit
longer receive
}
else { // go back to IDLE if mouse has nothing to send
or receive
if ( !(transmit|| receive) )
mouse_state = IDLE;
else
mouse_state = BUSY;
// other
wise stay BUSY
}
break;
case INHIBIT:
// if we enter the INHIBIT state before we finish sendin
g
// a byte, we should save the byte & resend!
if(byte_index > 0 && byte_index < 10)
{
resend_byte = TRUE;
}
// reset the byte index
byte_index = 0;
// check for REQUEST state
// first, the host must release the CLK
if (CLK_IN == 1) {
mouse_state = WAIT_FOR_REQUEST; // next, we chec
k for DATA line to go low
}
else { // stay in INHIBIT state
mouse_state = INHIBIT;
transmit = 0;
receive = 0;
next_clock_state = LOW;
}
break;
case WAIT_FOR_REQUEST:
// check if the data line has gone low
if(DATA_IN == 0)
{
mouse_state = REQUEST; // go to REQUEST state
next_clock_state = RISE;
// turn on the c
lock
}
else
{
// we must be in the IDLE state because both
// CLK & DATA are high
mouse_state = IDLE;
next_clock_state = RISE;
}
break;
case REQUEST:
// get ready to receive data from the host
transmit = 0;
receive = 1;
byte_index = 0;
next_clock_state = FALL;
// host sends data on fa
lling edge
// In case we get another INHIBIT state
if ((clock_state == HIGH || clock_state == RISE) && CLK_
IN == 0)
{
mouse_state = INHIBIT;
next_clock_state = LOW;
transmit = 0;
receive = 0;
}
else if (transmit || receive)
// go to BUSY state to p
rocess data
mouse_state = BUSY;
else
mouse_state = REQUEST;
wise stay in REQUEST until data comes
break;
// other
}//end switch
}
//insert data into queue. Return 1 if queue full, or 0 if inserted data sucessf
ully
unsigned char queuePut(unsigned char d)
{
if (queueFull==TRUE) {
//check if queue is full
return(TRUE);
}
queue[queueIn]=d;
queueIn++;
ck in the next d value
queueEmpty=FALSE;
//insert d into queue
//increment where to sti
//indicate queue isnt' empty any
more
if (queueIn==QUEUELEN)
queueIn=0;
//if reached the end of the queue
//wrap around to the beg
if (queueIn==queueOut)
queueFull=TRUE;
//if queueIn caught up to queueOut
//indicate queue is full
inning
return(0);
}
//get data out of queue. Return 0 if queue empty or the actual data if not empt
y
unsigned char queueGet(void)
{
char d;
if(resend_byte == TRUE) // in case we need to resend data due to an INHI
BIT
{
resend_byte = FALSE;
return previous_byte;
}
if (queueEmpty==TRUE)
return(0);
//check if queue is empty
d=queue[queueOut];
queueOut++;
t next d value
queueFull=FALSE;
//get data out of queue
//increment location where to ge
//indicate queue isn't full anymore
if (queueOut==QUEUELEN) //if reached the end of the queue
queueOut=0;
//wrap around to the beginning
if (queueOut==queueIn) //if queueOut caught up to queueIn
queueEmpty=TRUE;
//indicate queue is empty
//if(d==0xAA)
// <FIX>
delay_ms(375);
previous_byte = d;
send it.
return(d);
}
//calculate the parity of a character
unsigned char getParity(unsigned char x)
{
unsigned char temp, i;
temp=1;
for(i=0;i<8;i++)
{
temp=temp^(x&1);
x>>=1;
}
return temp;
// save the byte we just popped
// in case we need to re
//return the data from queue
}
void process_command(unsigned char host_command) {
//PORTB.3 = 0x0;
delay_us(50); // do this stuff at rising edge of CLK
//PORTB = 0xFF;
//delay_ms(1000);
//PORTB = host_command;
//delay_ms(1000);
if (host_command == RESET)
{
queueIn = 0;
queueOut=0;
queueEmpty = TRUE;
queueFull = FALSE;
delay_us(500);
}
// Acknowledge the incoming request
queuePut(ACK);
// we received a byte w/ the new resolution
if(waiting_for_resolution) {
// check for valid resolution
if(host_command >= 0 && host_command <= 3)
resolution = host_command;
else {
queuePut(ERROR);
}
waiting_for_resolution = 0;
return;
}
// we received a byte w/ the new sample rate
if(waiting_for_sample_rate) {
// check for valid sample rate
if(host_command >= 10 && host_command <= 200) {
sample_rate = host_command;
}
else { // bad sample rate
queuePut(ERROR);
}
waiting_for_sample_rate = 0;
return;
}
switch (host_command) {
case RESET:
// RESET
PORTB.2 = 0x0;
deviceID = 0x03;
// create a devi
ce ID
queuePut(SELF_TEST_PASS);
// respond w/ self-test
passed (0xAA)
queuePut(deviceID);
ice ID
// <FIX > queuePut(INIT_SUCC_1);
// send host dev
data_reporting = 0;
// disable data
sample_rate = 100;
// set the sampl
scaling = 0;
resolution = 0x02;
// set scaling to 1:1
// set resolutio
reporting
ing rate to 100
n to 4
break;
case RESEND:
// Host requests for resending of data
resend_byte = TRUE;
//PORTB.7 = 0x0;
break;
case EN_DATA_REPORT:
// Enabling of data reporting
PORTB.7 = 0x0; // indicates mouse was detected
data_reporting = TRUE;
break;
case SET_SCALING11:
scaling = 0;
break;
// set scaling 1:1
case SET_SCALING21:
scaling = 1;
break;
// set scaling 2:1
case GET_DEVICE_ID:
// host requests device ID
PORTB.5 = 0x00;
queuePut(deviceID);
break;
case SET_RES: // host requests to set resolution
// host sends next byte with valid resolution
// set a flag to get this byte
waiting_for_resolution = 1;
break;
case STATUS_REQ: //status request respond 0xFA, 0x00, 0x02, 0x64
queuePut(0x00);
// <FIX> have to create the righ
t byte here ...
queuePut(resolution);
queuePut(sample_rate);
break;
case SET_SAMPLE_RATE: // host requests setting of sample rate
// host sends next byte with valid sample rate
// set a flag to get this byte
waiting_for_sample_rate = 1;
break;
case DIS_DATA_REPORT: // disable data reporting
data_reporting = 0;
break;
case SET_DEFAULT:
data_reporting = 0;
sample_rate = 100;
resolution = 4;
// set default values
break;
default:
break;
}
}
void init_serial(void) {
//serial setup for debugging using printf, etc.
UCSRB = 0x18;
UBRRL = 103;
putsf("\r\nStarting...\r\n");
//set up timer 0
//OCR2=249; //1 mSec
//TIMSK=0b10000010; //turn on timer 0 cmp-match ISR
//TCCR2=0b00001011; //prescalar to 64 and Clr-on-match
r_ready=0;
t_ready=1;
puts_string();
}
void initialize(void)
{
Button0pushed = 1050;
Button1pushed = 1050;
ADMUX = 0b01000000; //ADLAR is not set
ADCSRA = 0b11000111; //Enable & Start ADC w/ division factor of 128
OCR0=5;
//20 uSec
TIMSK=2;
//turn on timer 0 cmp-match ISR
TCCR0=0b00001011;
//prescalar to 64 and Clr-on-match
// Set up the A/D
//ADMUX = 0b00100001; //ADLAR is set
//ADCSR = 0b11000111; //Enable & Start ADC w/ division factor of 128
// setup Port D for PS/2 communication
DDRC = 0b01000010;
PORTC = 0b01000010;
// setup LEDs for debugging
DDRB = 0xFF;
PORTB = 0xFF;
//DDRD = 0xFF;
//PORTD = 0xFF;
// use Port C for buttons
//DDRC=0x00;
// set as input
// counter to be used in ISR
count = 0;
// initialize our outputs
CLK_OUT = 1;
DATA_OUT = 1;
// initialize the queue
queueEmpty = TRUE;
queueFull = FALSE;
queueIn = 0;
queueOut =0;
// initialize the states
byte_index = 0;
mouse_state = IDLE;
clock_state = HIGH;
next_clock_state = HIGH;
transmit = receive = 0;
outInhibit = FALSE;
// where we are in byte
// state of the mouse
// state of the clock
// what clock will be changing to
// init byte vars
transmit_byte = 0xFA;
receive_byte = 0x00;
previous_byte = 0x00;
resend_byte = FALSE;
gen_mouse_packet = FALSE;
// init mouse vars
deviceID = 0x03;
data_reporting = FALSE;
sample_rate = 0;
scaling = 0;
resolution = 0;
waiting_for_sample_rate = FALSE;
waiting_for_resolution = FALSE;
// init data reporting vars
mouse_posX = 0x00;
mouse_posY = 0x00;
left_button_click = middle_button_click = right_button_click = 0;
mouse_byte1 = 0x0;
scroll_byte = 0x0;
// Set up the A/D
//ADMUX = 0b00000000; //ADLAR is not set
//ADCSRA = 0b11000111; //Enable & Start ADC w/ division factor of 128
portb_cycle = 0;
//crank up the ISRs
#asm
sei
#endasm
}
void main(void)
{
// tell the computer that the mouse is ready and alive.
initialize();
//init_serial();
// printf("Hello\r\n");
// let the host know the mouse is connected
queuePut(SELF_TEST_PASS);
queuePut(INIT);
//printf("<Button0, Xmove: %d, %d> <Button1, Ymove: %d, %d> \r\n", Butto
n0, Xmove, Button1, Ymove);
// begin real work
while (1) {
// can we generate a new packet?
if(gen_mouse_packet == TRUE && data_reporting == TRUE) {
//if(1){
gen_mouse_packet = FALSE;
// if (1){
// check buttons
mouse_byte1 = 0x08;
mouse_posX = 0x00;
mouse_posY = 0x00;
Xmove = 0;
Ymove = 0;
scroll_byte = 0;
/*if (PINC.2 == 0x0){
//PORTB.0 == 0x0;
left_button_click = 1;
}
else {
left_button_click = 0;
//PORTB.0 == 0x1;
}
if (PINC.1 == 0x0){
//PORTB.1 = 0x0;
middle_button_click = 1;
}
else {
middle_button_click = 0;
//PORTB.0 == 0x1;
}
if (PINC.0 == 0x0){
//PORTB.2 = 0x0;
right_button_click = 1;
}
else {
right_button_click = 0;
//PORTB.0 == 0x1;
}
if (PINC.3 == 0x0) {
mouse_posX = 10;
}
if (PINC.4 == 0x0) {
mouse_posX = -10;
}
if (PINC.5 == 0x0) {
mouse_posY = 10;
}
if (PINC.6 == 0x0) {
mouse_posY = -10;
}*/
Button0 = 0;
Button1 = 0;
OldXmove = Xmove;
OldYmove = Ymove;
ADMUX = 0b01100000; //tilt around Y axis (accel on the
side is being read) => X axis motion on computer
ADCSRA.6 = 1;
while(ADCSRA.6 == 1){
//wait for an ADC conversion to finish
}
Ytilt = (ADCH);
Xmove = (signed char)(Ytilt);
ADMUX = 0b01100001; //tilt around X axis (accel on top
is being read) => Y axis motion on computer
ADCSRA.6 = 1;
while(ADCSRA.6 == 1){
//wait for an ADC conversion to finish
}
Xtilt = (ADCH);
Ymove = (signed char)(Xtilt);
if (Xmove < -121 || Xmove > 121) {//tolerance condition
Xmove = 0;
}
if (Xmove > 0){ //Need to correct descending system to a
scending system
//Xmove = (-127)-Xmove;
Xmove = (-132)-Xmove; //Smoother with 133 rath
er than 127
}
else if (Xmove < 0){
//Xmove = 127-Xmove;
Xmove = 132-Xmove;
}
if (Ymove < -123 || Ymove > 123) {//tolerance condition
Ymove = 0;
}
if (Ymove < 0){ //Need to correct descending system to a
scending system
Ymove = (-127)-Ymove;
//Smoothness does not ma
tter as much for Y axis
//since theres less Y to traverse than there is X space.
}
else if (Ymove > 0){
Ymove = 127-Ymove;
}
Xmove = (Xmove*(-1));
if (Button0pushed == 1050 || Button0pushed <= time){
ADMUX = 0b01100010; //tilt around Y axis (accel on the
side is being read) => X axis motion on computer
ADCSRA.6 = 1;
while(ADCSRA.6 == 1){
//wait for an ADC conversion to finish
}
Button0 = (ADCH);
//if (Button0 >= 140 && (Xmove>-25)){ //Can't press button while
tilted
if (((Xmove>-10)&&(Button0 >140))||((Xmove<-10)&&(Button0 >= (1
40-Xmove)))) {//This will allow buttons to be pushed even while mouse is tilted.
Button0pushed = time+150;
if (Button0pushed >= 1000) Button0pushed = (Button0pushe
d-999); //Overflow check
Button0 = 1;
}
else {
Button0 = 0;
Button0pushed = 1050;
}
}
if (Button1pushed = 1050 || Button1pushed <= time){
ADMUX = 0b01100011; //tilt around X axis (accel on top is being
read) => Y axis motion on computer
ADCSRA.6 = 1;
while(ADCSRA.6 == 1){
//wait for an ADC conversion to finish
}
Button1 = (ADCH);
//if (Button1 >= 140 && (Xmove>-25)){
if (((Xmove>-10)&&(Button1 >140))||((Xmove<-10)&&(Button1 >= (1
40-Xmove)))) {//This will allow buttons to be pushed even while mouse is tilted.
Button1 = 1;
Button1pushed = time+150;
if (Button1pushed >= 1000) Button1pushed = (Button1pushe
d-999); //Overflow check
}
else{
Button1 = 0;
Button1pushed = 1050;
}
}
//Check for both buttons pushed together (within 20ms) to toggle
scroll mode off & on
//first check the time difference between the button pushes.
if (Button1pushed > Button0pushed) ButtonTimeDiff = Button1pushed - Butt
on0pushed;
//else ButtonTimeDiff = Button0pushed - Button1pushed;
if (ButtonTimeDiff <= 80 && (Button0pushed!= 1050) && Button1pushed!=105
0){//Less than 20ms
ScrollState = ~ScrollState; //Toggle the scroll state
//Note that a 255 => scr
olling and a 0 => normal button functionality
}
//Safety conditions:
if ((Button0pushed > time + 151) || (Button0pushed > 1050)) Button0pushe
d = 1050;
if ((Button1pushed > time + 151) || (Button1pushed > 1050)) Button1pushe
d = 1050;
//Button1 = 0;
//Button0 = 0;
//Xmove = 0;
mouse_posX = (unsigned char) Xmove;
mouse_posY = (unsigned char) Ymove;
/*if (Xmove < 0){
mouse_posX = 255-mouse_posX;
}
*/
//printf("<Button0, Xmove: %d, %d> <Button1, Ymove: %d, %d> \r\n", Ymove,
mouse_posY, Xmove, mouse_posX);
//printf("<Button0, Button1: %d, %d> <ScrollState, move_y: %d, %d>\r\n",
Button0, Button1, ScrollState,Xmove);
//delay_ms(8);
//mouse_byte1 = mouse_byte1 | (((Yneg)&0x1)<<5) | (((Xneg)&0x1)<
<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (Button0 & 0x1);
if (ScrollState ==0) {//Not in scrolling mode
mouse_byte1 = mouse_byte1 | (((Ymove >> 7)&0x1)<<5) | (((Xmo
ve >> 7)&0x1)<<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (Butt
on0 & 0x1);
}
else {//In scrolling mode
mouse_byte1 = mouse_byte1 | (((Ymove >> 7)&0x1)<<5) | ((
(Xmove >> 7)&0x1)<<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (
Button0 & 0x1);
mouse_byte1 = ((mouse_byte1 >> 2)<<2); //shift out the l
ast 2 bits corresponding to button pushes.
//You can't push buttons while you are scrolling => the
button pushes mean you are scrolling up and down
}
//if (!(prev_byte1 == mouse_byte1 && prev_byte2 == Xmove
&& prev_byte3 == Ymove)) {
//if ((mouse_posX-prev_byte2)>50 || (mouse_posX-prev_byt
e2)<-50 || (mouse_posY-prev_byte3) > 50 || (mouse_posY-prev_byte3) < -50 || mous
e_byte1 != prev_byte1) {
//if ((Xmove-prev_byte2)>3 || (Xmove-prev_byte2)<-3 || (
Ymove-prev_byte3) > 3 || (Ymove-prev_byte3) < -3 || mouse_byte1 != prev_byte1) {
//if (((Xmove-OldXmove)>100) ||((Xmove-OldXmove) <-100)|
| ((OldYmove-Ymove)>100) || ((OldYmove-Ymove)<-100) || mouse_byte1 != prev_byte1
) {
if(1){
//if (prev_byte1 != mouse_byte1) {
if (portb_cycle == 0) {
PORTB.0 = 1;
portb_cycle = 1;
}
else {
PORTB.0 = 0;
portb_cycle = 0;
}
queuePut(mouse_byte1);
queuePut(Xmove);
queuePut(Ymove);
/* new code */
if (ScrollState != 0 && Button0 == 1) {
scroll_byte = 4;
}
if (ScrollState != 0 && Button1 == 1) {
scroll_byte = -4;
}
queuePut(scroll_byte);
/*prev_byte1 = mouse_byte1;
prev_byte2 = Xmove;
prev_byte3 = Ymove;*/
}
prev_byte1 = mouse_byte1;
prev_byte2 = Xmove;
prev_byte3 = Ymove;
// reset state variables for this loop
}
}
}