PS/2 auf RS232 Mausprotokoll - Wandler


Mein Chef hat einiges an älterem, hochwertigem Laborequipment, das auf IBM-PCs basiert, die aber Sonderanfertigungen sind und nicht ersetzt werden können. Da die Versorgungssituation mit seriellen Mäusen langsam kritisch wird, habe ich mir einen Protokollwandler ausgedacht, der es erlaubt, PS/2 Mäuse an seine antiken PCs anzuschließen, &üuml;ber Adapter theoretisch auch USB-Mäuse (stellte sich raus, dass die Adapter nur elektrisch sind - die Maus muss PS/2 können, und das tun die allerwenigsten. Hier meine Lösung Download - enthält Code und vorkompilierte hex Datei für Attiny2313 :
Spezifikationen:
Attiny2313 (der Attiny13 hat keinen Hardware-UART und mein Code ist mit 1,2k etwas zu groß)
Max232-Pegelwandler
Emuliert Standard Microsoft Maus, nicht mehr und nicht weniger. Höhere Abtastraten oder Baudraten werden nicht unterstützt
Mit der mittleren Maustaste kann man die Abtastrate auf der PS/2 Seite einstellen (äußert sich in unterschiedlichen Bewegungsgeschwindigkeiten)
Erfolgreich getestet unter DOS, Windows 3.1 und Windows 95 (das sind alle Tests, die ich gemacht habe - und ach ja bei meinem Chef funktioniert es auch, der lässt sogar ein Board dafür entwickeln)
Hot-Plug fähig!


Die LEDs sind:
Oben (rot): Fehler. Leuchtet im Fehlerfalle ständig. Im Normalbetrieb scheint sie dunkel zu leuchten (schnelles Flackern), wird dunkler, wenn man die Maus bewegt (auch ohne angeschlossenen PC, kann also für Debug-Zwecke verwendet werden).
Mitte: PS/2 Maus erkannt.
Unten: PC Kommunikation. Leuchtet, wenn der PC die Maus abfragt oder mit ihr redet (ist also die meiste Zeit aus)

Hier die von meinem Chef in Auftrag gegebene Version, da erkennt man die Verdrahtung ein wenig besser:


Pinbelegung der Kabel am RS232-Stecker sind:
Blau: Pin 7.
Rot: Pin 3.
Lila: Pin 2.
Gelb: Pin 5.

Fangen wir mit der Konstruktion an: Ich dachte, es wäre einfach, einen Protokollwandler zu bauen, weil erstens beide Protokolle gut analysiert sind und zweitens Bibliotheken für AVR existieren. Pustekuchen. Ich habe 3 PS2 Bibliotheken für Atmega (mein Entwicklungschip ist ein Atmega8, das fertige Produkt ein Attiny2313, bis auf das Fehlen der LCD-Debugroutinen und dieses eine fiese Bit, was man beim Atmega8 setzen muss, damit der die Baudrate einstellt, ist der Code identisch) heruntergeladen, KEINE DAVON FUNKTIONIERTE!
Also selber schreiben. Im Wesentlichen einfach irgendwo die Referenz greifen, und gucken, ob sich das Ergebnis mit meinem Oszilloskop deckt.
Oben: Data Unten:Clk
(Oben Data, unten Clock)
Das Ergebnis in Bits hab ich dann direkt zum LCD geschickt, dann zum Bildschirmterminal. Während bereits beim LCD ein paar Bits verloren gingen, sah das Ergebnis auf dem Terminal richtig mies aus: Der braucht zu lange! Anschließend hab ich alles gepuffert und die Ausgabe DANN erst aufs Terminal ausgegeben, schon stimmte alles. Zunächst habe ich nur die Answer-To-Reset-Nachricht zu decodieren versucht, nach langem Herumprogrammieren konnte ich der Maus den Befehl zum Update der Positionsdaten schicken (Polling-Modus):
Ja, ich benutze ein ECHTES Bildschirmterminal
Im Code hatte ich das Problem, dass, wenn ich die Bits beim Empfang durch Shift-and-OR in die Datenstruktur schiebe, ich nur Nullen bekam, es sei denn, ich nehme statt einem Bitstring einen normalen String und schreibe 'H' für High und 'L' für Low hinein und parse die Daten nach dem Empfang in die Datenstruktur. Sehr viel später habe ich gemerkt, dass meine if(HIGH)-Abfrage nicht funktioniert, nur die if(LOW)-Abfrage tut, was sie soll. Aber ich bin zu faul, den Code zu ändern, schließlich funktioniert es ja (und ist als Bytestring leichter zu debuggen, siehe Terminal).
Die serielle Seite machte weit weniger Probleme: 1200 Baud, 7 Bits ohne Parity (nur Debuggen ging danach nicht mehr, weil mein Terminal 7 Bits nur MIT Parity kann), wenn RTS low dann sende 'M', anschließend automatisch bei Bewegung.
Senden der Bewegungsdaten funktionierte auf Anhieb, nur leider nicht in irgendwelchen Applikationen. Nur im Maustreiberprogramm selbst!
Prüfungen ergaben, dass jedes Mal, wenn eine Applikation getartet wird, RTS low gelegt und auf ein 'M' gewartet wird. Bei der Treiberinstallation alleine reichte das nicht, also habe ich die RTS Erkennungsroutine in die Hauptschleife gelegt. Danach funktionierte es soweit ganz gut. Später (als ich schon den Schritt zum Attiny gemacht habe) stellte ich fest, dass manche Computer RTS low HALTEN! Das Ergebnis war, dass der Chip permanent 'M' gesendet hat und dazwischen die Mauskoordinaten. Dass das überhaupt funktionierte, war ein Wunder. Die Lösung war, dass der Chip nur noch auf Flanken bei RTS reagiert. Das Ergebnis war, dass sich die Maus auch gleich viel ruhiger und glatter bewegt hat (vorher war sie etwas träge und niedrig aufgelöst).
Das Sahnehäubchen war, die mittlere Taste für Geschwindigkeitssteuerung zu verwenden. Leider funktioniert das nicht so klasse, bei manchen Mäusen tut es problemlos, bei anderen sehr unzuverlässig (es zählt hoch, während man gedrückt hält (nicht bei allen!) oder die Maus bewegt (bei allen)). Am besten, man berührt sie nicht.
Eine eventuelle Zukunfts-Overkill-Version wäre, wieder ein LCD anzubringen und die mittlere Maustaste sowie das Scrollrad für ein Menü zu benutzen (da könnte man z.B. Maustyp (Logitech, Microsoft, Mouse Systems) und/oder Funktion der mittleren Taste (Doppelklick)) einstellen.


Mein Plan für die nächste Zukunft ist ein Mausprotokollwandler PS2->SNES um Mario Paint zu zocken.