// Drivers #include // SPI USB #include #define SPI_SCLK 32 #define SPI_MISO 35 #define SPI_MOSI 33 #define SPI_SS 5 #define PIN_MOUSE_V 19 // LAN_TX0 #define PIN_MOUSE_VQ 26 // LAN_RX1 #define PIN_MOUSE_H 27 // LAN_CRS #define PIN_MOUSE_HQ 23 // LAN_MDC #define PIN_MOUSE_LBTN 21 // LAN_TXEN #define PIN_MOUSE_MBTN 25 // LAN_RX0 #define PIN_MOUSE_RBTN 17 // LAN_CLK #define MOUSE_SCALE_MAX 63 #define MOUSE_PULSE_DELAY 70 const byte mouseStates[4][2] = { {0, 0}, {0, 1}, {1, 1}, {1, 0} }; class MouseRptParser : public MouseReportParser { protected: void OnMouseMove (MOUSEINFO *mi); void OnRightButtonUp (MOUSEINFO *mi); void OnRightButtonDown (MOUSEINFO *mi); void OnLeftButtonDown (MOUSEINFO *mi); void OnLeftButtonUp (MOUSEINFO *mi); void OnMiddleButtonDown (MOUSEINFO *mi); void OnMiddleButtonUp (MOUSEINFO *mi); }; void MouseRptParser::OnRightButtonUp (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_RBTN, HIGH); }; void MouseRptParser::OnRightButtonDown (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_RBTN, LOW); }; void MouseRptParser::OnLeftButtonDown (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_LBTN, LOW); }; void MouseRptParser::OnLeftButtonUp (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_LBTN, HIGH); }; void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_MBTN, LOW); }; void MouseRptParser::OnMiddleButtonUp (MOUSEINFO *mi) { digitalWrite(PIN_MOUSE_MBTN, HIGH); }; bool mouseYworking = false; int mouseYTableIndex = 0; void amigaYpulse(int8_t count) { if (count == 0) return; if (mouseYworking) return; mouseYworking = true; byte mapped = map(abs(count), 0, 127, 1, MOUSE_SCALE_MAX); for (byte i = 0; i < mapped; i++) { if (count < 0) { mouseYTableIndex++; if (mouseYTableIndex > 3) { mouseYTableIndex = 0; } } else { mouseYTableIndex--; if (mouseYTableIndex < 0) { mouseYTableIndex = 3; } } digitalWrite(13, mouseStates[mouseYTableIndex][0]); digitalWrite(14, mouseStates[mouseYTableIndex][1]); delayMicroseconds(MOUSE_PULSE_DELAY); } mouseYworking = false; } int mouseXTableIndex = 0; void amigaXpulse(int8_t count) { if (count == 0) return; for (byte i = 0; i < map(abs(count), 0, 127, 1, MOUSE_SCALE_MAX); i++) { if (count < 0) { mouseXTableIndex++; if (mouseXTableIndex > 3) { mouseXTableIndex = 0; } } else { mouseXTableIndex--; if (mouseXTableIndex < 0) { mouseXTableIndex = 3; } } digitalWrite(15, mouseStates[mouseXTableIndex][0]); digitalWrite(12, mouseStates[mouseXTableIndex][1]); delayMicroseconds(MOUSE_PULSE_DELAY); } } void MouseRptParser::OnMouseMove(MOUSEINFO *mi) { amigaYpulse(mi->dY); amigaXpulse(mi->dX); }; // This is only for single USB device (without HUB) // In this example we support keyboard or mouse USB Usb; HIDBoot HidMouse(&Usb); MouseRptParser PrsMouse; void setupAnalogMouse() { pinMode(PIN_MOUSE_V, OUTPUT); pinMode(PIN_MOUSE_VQ, OUTPUT); pinMode(PIN_MOUSE_H, OUTPUT); pinMode(PIN_MOUSE_HQ, OUTPUT); pinMode(PIN_MOUSE_LBTN, OUTPUT); pinMode(PIN_MOUSE_MBTN, OUTPUT); pinMode(PIN_MOUSE_RBTN, OUTPUT); // Default button state is not pressed digitalWrite(PIN_MOUSE_LBTN, HIGH); digitalWrite(PIN_MOUSE_MBTN, HIGH); digitalWrite(PIN_MOUSE_RBTN, HIGH); } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("INIT"); Serial.print("USB init..."); SPI.begin(SPI_SCLK, SPI_MISO, SPI_MOSI, SPI_SS); if (Usb.Init() == -1) { Serial.println("WARN: Usb init failed."); } else { Serial.println(" DONE"); } setupAnalogMouse(); HidMouse.SetReportParser(0, &PrsMouse); Serial.println("Ready to rock and roll..."); } void loop() { Usb.Task(); }