157 lines
3.3 KiB
C++
157 lines
3.3 KiB
C++
|
#include "Arduino.h"
|
||
|
#include "HardwareSerial.h"
|
||
|
#include "PS2Mouse.h"
|
||
|
|
||
|
PS2Mouse::PS2Mouse(int data_pin, int clock_pin)
|
||
|
{
|
||
|
_data_pin = data_pin;
|
||
|
_clock_pin = clock_pin;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* according to some code I saw, these functions will
|
||
|
* correctly set the mouse clock and data pins for
|
||
|
* various conditions.
|
||
|
*/
|
||
|
void PS2Mouse::gohi(int pin)
|
||
|
{
|
||
|
pinMode(pin, INPUT);
|
||
|
digitalWrite(pin, HIGH);
|
||
|
}
|
||
|
|
||
|
void PS2Mouse::golo(int pin)
|
||
|
{
|
||
|
pinMode(pin, OUTPUT);
|
||
|
digitalWrite(pin, LOW);
|
||
|
}
|
||
|
|
||
|
void PS2Mouse::write(char data)
|
||
|
{
|
||
|
char i;
|
||
|
char parity = 1;
|
||
|
|
||
|
// Serial.print("Sending ");
|
||
|
// Serial.print(data, HEX);
|
||
|
// Serial.print(" to mouse\n");
|
||
|
// Serial.print("RTS");
|
||
|
/* put pins in output mode */
|
||
|
gohi(_data_pin);
|
||
|
gohi(_clock_pin);
|
||
|
delayMicroseconds(300);
|
||
|
golo(_clock_pin);
|
||
|
delayMicroseconds(300);
|
||
|
golo(_data_pin);
|
||
|
delayMicroseconds(10);
|
||
|
/* start bit */
|
||
|
gohi(_clock_pin);
|
||
|
/* wait for mouse to take control of clock); */
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
/* clock is low, and we are clear to send data */
|
||
|
for (i=0; i < 8; i++) {
|
||
|
if (data & 0x01) {
|
||
|
gohi(_data_pin);
|
||
|
}
|
||
|
else {
|
||
|
golo(_data_pin);
|
||
|
}
|
||
|
/* wait for clock cycle */
|
||
|
while (digitalRead(_clock_pin) == LOW)
|
||
|
;
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
parity = parity ^ (data & 0x01);
|
||
|
data = data >> 1;
|
||
|
}
|
||
|
/* parity */
|
||
|
if (parity) {
|
||
|
gohi(_data_pin);
|
||
|
}
|
||
|
else {
|
||
|
golo(_data_pin);
|
||
|
}
|
||
|
while (digitalRead(_clock_pin) == LOW)
|
||
|
;
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
/* stop bit */
|
||
|
gohi(_data_pin);
|
||
|
delayMicroseconds(50);
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
/* wait for mouse to switch modes */
|
||
|
while ((digitalRead(_clock_pin) == LOW) || (digitalRead(_data_pin) == LOW))
|
||
|
;
|
||
|
/* put a hold on the incoming data. */
|
||
|
golo(_clock_pin);
|
||
|
// Serial.print("done.\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Get a byte of data from the mouse
|
||
|
*/
|
||
|
char PS2Mouse::read(void)
|
||
|
{
|
||
|
char data = 0x00;
|
||
|
int i;
|
||
|
char bit = 0x01;
|
||
|
|
||
|
// Serial.print("reading byte from mouse\n");
|
||
|
/* start the clock */
|
||
|
gohi(_clock_pin);
|
||
|
gohi(_data_pin);
|
||
|
delayMicroseconds(50);
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
delayMicroseconds(5); /* not sure why */
|
||
|
while (digitalRead(_clock_pin) == LOW) /* eat start bit */
|
||
|
;
|
||
|
for (i=0; i < 8; i++) {
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
if (digitalRead(_data_pin) == HIGH) {
|
||
|
data = data | bit;
|
||
|
}
|
||
|
while (digitalRead(_clock_pin) == LOW)
|
||
|
;
|
||
|
bit = bit << 1;
|
||
|
}
|
||
|
/* eat parity bit, which we ignore */
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
while (digitalRead(_clock_pin) == LOW)
|
||
|
;
|
||
|
/* eat stop bit */
|
||
|
while (digitalRead(_clock_pin) == HIGH)
|
||
|
;
|
||
|
while (digitalRead(_clock_pin) == LOW)
|
||
|
;
|
||
|
|
||
|
/* put a hold on the incoming data. */
|
||
|
golo(_clock_pin);
|
||
|
// Serial.print("Recvd data ");
|
||
|
// Serial.print(data, HEX);
|
||
|
// Serial.print(" from mouse\n");
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
void PS2Mouse::init()
|
||
|
{
|
||
|
gohi(_clock_pin);
|
||
|
gohi(_data_pin);
|
||
|
// Serial.print("Sending reset to mouse\n");
|
||
|
write(0xff);
|
||
|
read(); /* ack byte */
|
||
|
// Serial.print("Read ack byte1\n");
|
||
|
read(); /* blank */
|
||
|
read(); /* blank */
|
||
|
// Serial.print("Sending remote mode code\n");
|
||
|
write(0xf0); /* remote mode */
|
||
|
read(); /* ack */
|
||
|
// Serial.print("Read ack byte2\n");
|
||
|
delayMicroseconds(100);
|
||
|
}
|
||
|
|
||
|
|
||
|
|