--- /dev/null
+
+#include "ps2dev.h"
+
+PS2dev mouse(3,2); // 2 data 3clock
+
+char buttons[3] = {0,0,0};
+
+int delta_x = 0;
+int delta_y = 0;
+//we start off not enabled
+int enabled =0;
+
+//ack a host command
+void ack() {
+ while(mouse.write(0xFA));
+}
+
+void write_packet() {
+ char overflowx =0;
+ char overflowy =0;
+ char data[3];
+ int x,y;
+
+ if (delta_x > 255) {
+ overflowx =1;
+ x=255;
+ }
+ if (delta_x < -255) {
+ overflowx = 1;
+ x=-255;
+ }
+ if (delta_y > 255) {
+ overflowy =1;
+ y=255;
+ }
+ if (delta_y < -255) {
+ overflowy = 1;
+ y=-255;
+ }
+
+ data[0] = ((overflowy & 1) << 7) |
+ ( (overflowx & 1) << 6) |
+ ( (((delta_y &0x100)>>8) & 1) << 5) |
+ ( ( ((delta_x &0x100)>>8)& 1) << 4) |
+ ( ( 1) << 3) |
+ ( ( buttons[1] & 1) << 2) |
+ ( ( buttons[2] & 1) << 1) |
+ ( ( buttons[0] & 1) << 0) ;
+
+ data[1] = delta_x & 0xff;
+ data[2] = delta_y & 0xff;
+
+ mouse.write(data[0]);
+ mouse.write(data[1]);
+
+ mouse.write(data[2]);
+
+ delta_x = 0;
+ delta_y = 0;
+}
+
+int mousecommand(int command) {
+ unsigned char val;
+
+ //This implements enough mouse commands to get by, most of them are
+ //just acked without really doing anything
+
+ switch (command) {
+ case 0xFF: //reset
+ ack();
+ //the while loop lets us wait for the host to be ready
+ while(mouse.write(0xAA)!=0);
+ while(mouse.write(0x00)!=0);
+
+ break;
+ case 0xFE: //resend
+ ack();
+ break;
+ case 0xF6: //set defaults
+ //enter stream mode
+ ack();
+ break;
+ case 0xF5: //disable data reporting
+ //FM
+ ack();
+ break;
+ case 0xF4: //enable data reporting
+ //FM
+ enabled = 1;
+ ack();
+ break;
+ case 0xF3: //set sample rate
+ ack();
+ mouse.read(&val); // for now drop the new rate on the floor
+ // Serial.println(val,HEX);
+ ack();
+ break;
+ case 0xF2: //get device id
+ ack();
+ mouse.write(00);
+ break;
+ case 0xF0: //set remote mode
+ ack();
+ break;
+ case 0xEE: //set wrap mode
+ ack();
+ break;
+ case 0xEC: //reset wrap mode
+ ack();
+ break;
+ case 0xEB: //read data
+ ack();
+ write_packet();
+ break;
+ case 0xEA: //set stream mode
+ ack();
+ break;
+ case 0xE9: //status request
+ ack();
+ // send_status();
+ break;
+ case 0xE8: //set resolution
+ ack();
+ mouse.read(&val);
+ // Serial.println(val,HEX);
+ ack();
+ break;
+ case 0xE7: //set scaling 2:1
+ ack();
+ break;
+ case 0xE6: //set scaling 1:1
+ ack();
+ break;
+
+ }
+
+}
+
+int xcenter ;
+int ycenter;
+
+int xsum = 0;
+int ysum = 0;
+
+void setup() {
+ unsigned char val;
+
+ // send the mouse start up
+ while(mouse.write(0xAA)!=0);
+ while(mouse.write(0x00)!=0);
+
+
+}
+
+
+
+
+void loop() {
+ unsigned char c;
+ if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
+ while(mouse.read(&c)) ;
+ mousecommand(c);
+ }
+
+ if (enabled) {
+ // move the mouse diagonally
+ delta_x = 1;
+ delta_y = 1;
+ write_packet() ;
+ }
+ delay(50);
+
+}
--- /dev/null
+/*
+ * ps2dev.cpp - an interface library for ps2 host.
+ * limitations:
+ * we do not handle parity errors.
+ * The timing constants are hard coded from the spec. Data rate is
+ * not impressive.
+ * probably lots of room for optimization.
+ */
+
+#include "WProgram.h"
+#include "ps2dev.h"
+
+
+//since for the device side we are going to be in charge of the clock,
+//the two defines below are how long each _phase_ of the clock cycle is
+#define CLKFULL 40
+// we make changes in the middle of a phase, this how long from the
+// start of phase to the when we drive the data line
+#define CLKHALF 20
+
+/*
+ * the clock and data pins can be wired directly to the clk and data pins
+ * of the PS2 connector. No external parts are needed.
+ */
+PS2dev::PS2dev(int clk, int data)
+{
+ _ps2clk = clk;
+ _ps2data = data;
+ gohi(_ps2clk);
+ gohi(_ps2data);
+}
+
+/*
+ * according to some code I saw, these functions will
+ * correctly set the clock and data pins for
+ * various conditions. It's done this way so you don't need
+ * pullup resistors.
+ */
+void
+PS2dev::gohi(int pin)
+{
+ pinMode(pin, INPUT);
+ digitalWrite(pin, HIGH);
+}
+
+void
+PS2dev::golo(int pin)
+{
+ pinMode(pin, OUTPUT);
+ digitalWrite(pin, LOW);
+}
+
+int PS2dev::write(unsigned char data)
+{
+ unsigned char i;
+ unsigned char parity = 1;
+
+ // Serial.print("sending ");
+ //Serial.println(data,HEX);
+
+
+ if (digitalRead(_ps2clk) == LOW) {
+ return -1;
+ }
+
+ if (digitalRead(_ps2data) == LOW) {
+ return -2;
+ }
+
+
+ golo(_ps2data);
+ delayMicroseconds(CLKHALF);
+ // device sends on falling clock
+ golo(_ps2clk); // start bit
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ for (i=0; i < 8; i++)
+ {
+ if (data & 0x01)
+ {
+ gohi(_ps2data);
+ } else {
+ golo(_ps2data);
+ }
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ parity = parity ^ (data & 0x01);
+ data = data >> 1;
+ }
+ // parity bit
+ if (parity)
+ {
+ gohi(_ps2data);
+ } else {
+ golo(_ps2data);
+ }
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ // stop bit
+ gohi(_ps2data);
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ delayMicroseconds(50);
+ return 0;
+}
+
+
+int PS2dev::read(unsigned char * value)
+{
+ unsigned char data = 0x00;
+ unsigned char i;
+ unsigned char bit = 0x01;
+
+ unsigned char parity = 1;
+
+ //wait for data line to go low
+ while (digitalRead(_ps2data) == HIGH) {
+
+ }
+ //wait for clock line to go high
+ while (digitalRead(_ps2clk) == LOW) {
+
+ }
+
+
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ for (i=0; i < 8; i++)
+ {
+ if (digitalRead(_ps2data) == HIGH)
+ {
+ data = data | bit;
+ } else {
+ }
+
+
+ bit = bit << 1;
+
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+ parity = parity ^ (data & 0x01);
+ }
+ // we do the delay at the end of the loop, so at this point we have
+ // already done the delay for the parity bit
+
+ // stop bit
+ delayMicroseconds(CLKHALF);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+
+
+ delayMicroseconds(CLKHALF);
+ golo(_ps2data);
+ golo(_ps2clk);
+ delayMicroseconds(CLKFULL);
+ gohi(_ps2clk);
+ delayMicroseconds(CLKHALF);
+ gohi(_ps2data);
+
+
+ *value = data;
+
+ return 0;
+}
+
+