0% found this document useful (0 votes)
352 views19 pages

Air Mouse Code

code

Uploaded by

Bakhtiar Tiar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
352 views19 pages

Air Mouse Code

code

Uploaded by

Bakhtiar Tiar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 19

#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
}
}
}

You might also like