keyman64
Programmierbarer Tastatur- und Hardware-Controller
Der Keyman64 ist ein programmierbarer Tastatur- und Hardware-Controller für Heimcomputer, die mit einer einfachen 64-Tasten Matrixtastatur ausgestattet sind.
Das Gerät wird zwischen Tastatur und Computer installiert und überwacht dort die physische Tastatur, deren Zustand zunächst immer unmittelbar an den Computer weitergeleitet wird. Der Computer liest die vom Keyman64 bereitgestellte virtuelle Tastatur genau wie eine normale Tastatur aus. Der Keyman64 kann dadurch sowohl alle vom Benutzer getätigten Tastatureingaben überwachen als auch den vom Computer gelesenen Zustand der Tastatur bestimmen.
Der Keyman64 kann nun so programmiert werden, dass bestimmte Tastenkombinationen nicht an den Computer weitergeleitet werden, sondern stattdessen eine oder mehrere der sechzehn auf der Platine ausgeführten digitalen Steuerleitungen auf bestimme, benutzerdefierte Weise geschaltet werden. Mit Hilfe dieser Steuerleitungen kann im Computer verbaute Zusatzhardware anstelle von Schaltern oder Tastern kontrolliert werden.
Mit dem Keyman64 ist somit der Einbau von Schaltern oder Tastern in das Gehäuse des Computers nicht mehr notwendig.
Unter anderem bietet das Gerät zusätzlich die Möglichkeit, benutzerdefinierte Tastatur-Macros zu senden oder auch das Layout der Tastatur zu verändern. Alle Steuerbefehle können auch vom PC aus über USB oder über die integrierte serielle Schnittstelle Keyman64 gesendet werden, so dass sowohl eine Fernsteuerung von einem externen Rechner, dem Computer selbst oder durch andere Mikrokontroller möglich ist.
Einige konkrete Beispiele finden sich im Abschnitt Anwendungsbeispiele.
Die Dokumentation ist auf deutsch und englisch verfügbar.
Übersicht
Arbeitsweise
Während des normalen Betriebs leitet das Gerät alle Tastaturereignisse direkt an den Computer weiter, es sei denn, es wird die als Meta-Taste definierte Taste heruntergehalten. Solange Meta heruntergehalten wird, lösen zusätzliche Tastatureingaben die Ausführung der vom Benutzer für die jeweilige Tastenkombination definierten Schaltsequenzen aus. Wird die Meta-Taste wieder losgelassen, werden Tastaturereignisse wieder an den Computer weitergeleitet.
Wurde allerdings keine weitere Taste betätigt, während die Meta-Taste gedrückt war, so wird das Betätigen der Meta-Taste selbst an den Computer weitergeleitet. Auf diese Weise ist die Meta-Taste nicht “verloren”, und kann weiterhin wie vorgesehen verwendet werden. Der einzige Unterschied besteht darin, dass der Computer das Herunterdrücken und Loslassen der Taste erst registriert, nachdem die pyhsische Taste wieder losgelassen wurde.
Diese Vorgehensweise funktioniert gut, so lange die Meta-Taste lediglich kurz betätigt werden soll, um z.B. den jeweiligen Buchstaben oder das jeweilige Symbol einzugeben. Soll die Taste jedoch eine längere Zeit gedrückt gehalten werden, muss dies über eine weitere Tastenkombination realisiert werden, z.B.:
m: down ARROWLEFT
Unter der Annahme, dass der Linkspfeil als Meta-Taste verwendet wird, kann der Befehl “down ARROWLEFT” durch gleichzeitiges Drücken von Linkspfeil und der Taste “M” ausgelöst werden. Die virtuelle Linkspfeil-Taste wird nun solange vom Computer als gedrückt gesehen, wie die Meta-Taste gehalten wird. Sobald Meta losgelassen wird, scannt und übermittelt das Gerät wieder die physische Tastatur an den Computer, wodurch das Herunterhalten von Meta aus Sicht des Computers wieder beendet wird.
Als Meta-Taste dient in der Standardeinstellung die Linkspfeil-Taste. Um eine andere Taste als Meta-Taste zu verwenden, kann der unten beschriebene Befehl meta verwendet werden.
Software
Ein einfachen Kommandozeilen-Tool dient zur Konfiguration und zur Kontrolle des Geräts. Dieses tool übersetzt die vom Benutzer geschriebene Konfigurationsdatei in ein binäres Format, das in den EEPROM-Speicher des Mikrocontrollers geschrieben wird. Dies ist im Abschnitt Konfiguration detailliert beschrieben.
Zusätzlich erlaubt das tool die Kontrolle des Keyman64 über USB. Es können beliebige Befehle über USB an das Gerät gesendet und dort direkt ausgeführt werden.
Hardware
Das Gerät basiert auf einem Atmega1284p Mikrokontroller, einem Crosspoint-Switch IC sowie einigen diskreten 74xx ICs. Unterstützt werden als Crosspoint-Switch sowohl der CD74HC22106 als auch der MT8808, wahlweise in DIP- oder PLCC-Bauweise. Ein USB-Anschluss ermöglicht die einfache Konfiguration und das Update der Firmware mit Hilfe des auf dem Mikrokontroller vorinstallierten USB-Bootloaders. Weitere Details zu Schaltung und Aufbau der Platine finden sich in der Quelldistribution sowie in den folgenden Abschnitten.
Kompatibilität
Theoretisch ist das Gerät für den Einsatz in jedem Heimcomputer geeignet, der eine passive 8x8 Tasturmatrix verwendet. Allerdings folgen das Layout der Anschlüsse und die Bennenung der Tasten denen des C64. Ebenso verwendet der Befehl type die für den C64 notwendigen Tastatureingaben, um den übergebenen ASCII-Text auszugeben. Falls ihr softwareseitige Unterstützung für andere Computer benötigt, zögert nicht, einen Feature-Request auf dem Github-Issue-Tracker zu stellen, vorzugsweise unter Angabe der dazu benötigten Informationen.
Dokumentation
- Downloads
- Errata
- Bestellung von Bausätzen
- Aufbau
- Installation der Firmware
- Einrichten der USB-Geräte auf dem PC
- Installation des Konfigurationstools keyman64 auf dem PC
- Konfiguration
- Konfigurationstool
- Porterweiterung
- Serielle Schnittstelle
- Anwendungsbeispiele
- Lizensierung
Downloads
Quellen
Die Quelldistribution umfasst den Quelltext für die Firmware und das Konfigurations-Tool sowie den Schaltplan und das Platinenlayout im KiCad-Format.
Die letzte stabile Version ist keyman64-1.6.tar.gz.
Alle veröffentlichten Versionen finden sich unter /download/keyman64
Neuste Entwicklungen können auf github verfolgt werden:
git clone https://github.com/hbekel/keyman64
Der Changelog führt alle Änderungen im Detail auf.
Binärdateien
-
keyman64-1.6.msi
Konfigurationstool, Windows 32bit Installationspaket -
keyman64-bootloader-updater-1.6.hex
Anwendung zum Aktualisieren des Bootloaders für Versionen 1.3 und früher über den bereits installierten Bootloader -
keyman64-application-and-bootloader-1.6.hex
keyman64-application-and-bootloader-1.6.bin
Vollständiges Abbild, das sowohl den Bootloader als auch die Anwendung enhält, geeignet für das Programmieren des Mikrokontrollers mit einem Programmiergerät außerhalb der Schaltung -
keyman64-application-1.6.hex
keyman64-application-1.6.bin
enthält lediglich den Anwendungsteil der Firmware -
keyman64-gerber-r4.zip
Gerber-Dateien für die Platinenrevision 4
Schaltplan
Errata
Revision 3
Die Schaltung für die USB-Pegelanpassung ist in allen Revisionen bis einschließlich Revision 3 fehlerhaft. Dies kann zu fehlender USB-Funktionalität führen. Diese ist abhängig von dem spezifischen Typ der verwendeten 3.6V Zenerdioden. Während die Dioden, die ich mit den Revisionen 1 und 2 ausgeliefert haben, zufälligerweise funktioniert haben, waren die mit den Bausätzen für Revision 3 verschickten Dioden nicht geeignet. Daher habe ich diesen Fehler leider erst nach Auslieferung der ersten Bausätze von Revision 3 entdeckt.
Beim Aufbau bzw. bei der Reparatur eines Geräts der Revision 3 müssen die Dioden daher wie im folgenden Bild gezeigt verbaut bzw. umgebaut werden:

Wie man sieht müssen die Kathoden der Dioden (d.h. die Seite mit dem Strich) vor den Widerständen an die USB-Datenleitungen D- und D+ angeschlossen werden. Diese können direkt an die Beinchen der 68Ω-Widgerstände gelötet werden, vorausgesetzt, dass die Widerstände so eingelötet wurden, wie es der Bestückungsdruck vorschlägt.
Dieser Fehler wurde in Revision 4 behoben.
Revision 2
Der Generator für negative Spannungen, ICL7660 wird nicht benötigt, obwohl es auch nicht schadet, wenn er eingebaut bleibt. Er wurde in Revision 3 zugunsten einen alternativen PLCC-Sockels für den Crosspoint-Switch entfernt.
Außerdem messen die Bohrlöcher in Revision 2 nur 3mm im Durchmesser und somit nicht geeignet für gebräuchliche selbstklebende Platinenhalter, die zumeist Löcher mit 4mm benötigen. Die Löcher wurden in Revision 3 auf 4mm Durchmesser erweitert.
Bestellung von Bausätzen
Ich biete Bausätze zum Preis von 30€ pro Stück an. Der Bausatz enthält eine Keyman64 Platine, eine vorprogrammierten Atmega, einen MT8808 in DIP-Bauweise und alle weiteren benötigten Bauteile und IC-Sockel (ausgenommen Verbindungskabel). Weltweiter Versand per Post ist kostenlos.
Bestellungen könnt Ihr per Mail an henning.liebenau@protonmail.com tätigen.
Bitte verwendet das Wort “keyman64” im Betreff. Gebt in der Mail euren vollen Namen, Eure Lieferadresse und die Anzahl der gewünschten Bausätze an. Bitte beachtet, dass die Anzahl der Bausätze pro Person auf zwei Stück beschränkt ist. Ihr bekommt dann von mir per Mail weitere Informationen zur Bezahlung per Überweisung. Bitte beachtet, dass im voraus gezahlt werden muss, um die Bestellung verbindlich zu bestätigen.
Hinweise zur Verfügbarkeit
Ich versuche stets eine ausreichende Menge an Bausätzen auf Lager zu halten. Bitte beachtet jedoch, dass dies mit geringem Budget und bei minimaler Gewinnmarge in meiner Freizeit passiert. Mein Ziel ist es primär, der Community meine Hardware zugänglich zu machen, und nicht etwa ein profitables Geschäft zu betreiben.
Sollte ich also momentan keine Bausätze auf Lager haben kann es durchaus einige Wochen dauern, bis ich eine neue Serie von Bausätzen produzieren und somit eurer Bestellung nachkommen kann. Unter Umständen muss ich auch warten, bis eine ausreichende Anzahl an Vorbestellungen eingeht, bevor ich selbst die nötigen Bauteile zu einem ausreichend günstigen Preis bestellen kann. In diesen Fällen werde ich Euch natürlich regelmäßig über den Status Eurer Bestellung informieren. Es bedarf also unter Umständen ein wenig Geduld und auch Vertrauen von Eurer Seite.
Aufbau
Der Aufbau sollte relativ problemlos von statten gehen können. Orientiert euch einfach and der Liste der Bauteile und am Bestückungsplan weiter unten.
Spannungsversorgung
Eine Versorgung mit +5V Gleichstrom muss an den mittleren Pin des Jumpers J1 geführt werden. Dazu können entweder +5V vom Computer direkt an diesen Pin geführt werden, oder es kann eine Brücke verwendet werden, um die Spannung von Pin 4 an des Tastaturanschlusses des Computers zu beziehen, oder die Spannung kann direkt von der USB-Buchse bezogen werden. Um Spannung aus dem Tastaturanschluss zu beziehen (die empfohlenen Methode für den C64), müssen der linke und mittlere Pin von J1 gebrückt werden. Um die Spannung über USB zu beziehen, müssen der mittlere und rechte Pin von J1 gebrückt werden.
Die Versorgung über den USB-Port ist nur dann zu empfehlen, wenn das Gerät ohne Anschluss an andere Geräte betrieben wird, das heißt wenn P1 nicht an die Ein/Ausgabeleitungen eines Computers angeschlossen ist und keines der anderen mit dem Gerät verbundenen Geräte von einer anderen Spannungsquelle versorgt wird. Generell müssen alle beteiligten Geräte (der Computer, der Keyman64 selbst und die von ihm kontrollierten Geräte) von derselben Spannungsquelle versorgt werden. Wäre der Keyman beispielsweise für die Versorgung über USB konfiguriert und an Leitungen des Computers angeschlossen und würde der Computer dann angeschaltet werden, ohne das gleichzeitig Spannung über den USB-Port bereitgestellt wird, würde der Keyman64 dennoch über die ESD-Schutzdioden der I/O-Ports des Atmels Strom zu ziehen versuchen, was erheblichen Schaden an den I/O-Ports aller beteiligten Geräte zur Folge haben kann.
Verbindungen
Die Pinbelegung von P1 und P2 folgen der Pinbelegung des C64-Tastaturanschlusses. Die Restore-Leitung wird lediglich durchgeschleift.
Liste der Bauteile
Referenz | Typ | Wert | Bauweise/Rastermaß |
---|---|---|---|
C1 | Keramikkondensator | 18pF | 2.5mm |
C2 | Keramikkondensator | 18pF | 2.5mm |
C6 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
C7 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
C8 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
C9 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
C10 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
C11 | Keramik- oder Filmkondensator | 100nF | 2.5mm |
D1 | Zenerdiode | 3.6V | DO-204 |
D2 | Zenerdiode | 3.6V | DO-204 |
R1 | Präzisionswiderstand | 1.5kΩ | 6.5mm, ∅ 2.5mm |
R2 | Präzisionswiderstand | 68Ω | 6.5mm, ∅ 2.5mm |
R3 | Präzisionswiderstand | 68Ω | 6.5mm, ∅ 2.5mm |
P3 | USB Mini-B-Buchse | - | Through-Hole |
SW1 | Taster | - | 6x6mm print |
SW2 | Taster | - | 6x6mm print |
X1 | Quartz | 16Mhz | HC49/U-S |
U1 | 74HC22106 oder MT8808 | - | DIP28 |
U2 | Atmega1284P | - | DIP40 |
U3 | 74HC00 | - | DIP14 |
U4 | 74HC4051 | - | DIP16 |
U5 | 74HC4520 | - | DIP16 |
U6 | 74HC4051 | - | DIP16 |
U7 | 74HC22106 oder MT8808 | - | PLCC28 |
Als Crosspoint-Switch kann entweder ein MT8808 oder ein 74HC22106 verwendet werden, dabei kann entweder eine DIP28-Variante auf U1 oder eine PLCC28-Variante auf U7 verwendet werden.
Wird ein 74HC22106 verwendet, muss dies über den Konfigurationsbefehl using entsprechend mittgeteilt werden.
IC-Sockel sind nicht gelistet.
Bestückungsplan
Installation der Firmware
Falls ihr einen Bausatz von mir erworben habt, ist der mitgelieferte Atmega bereits mit der aktuellsten Firmware programmiert und einsatzbereit.
Wenn dies nicht der Fall ist und ihr keine Möglichkeit habt, den Atmega zu programmieren, schickt ihn mir zu und ich programmiere ihn für euch. Mailt dazu an henning.liebenau@protonmail.com.
Installation des kombinierten Firmware-Images
Die einfachste Möglichkeit besteht darin, das kombinierte Firmware-Image aufzuspielen. Es enthält bereits den Bootloader und die Firmware und kann mit einem externen Programmiergerät (z.B. dem TL866) aufgespielt werden.
Dabei muss darauf geachtet werden, die korrekten Werte für die Fuses des Atmega zu verwenden:
Low: 0xd7 High: 0xd0 Extended: 0xfc
Diese Werte entsprechen den zu setzenden Fuses SUT1, CKSEL3, SPIEN, EESAVE, BOOTSZ0, BOOTSZ1, BOOTRST, BODLEVEL0 und BODLEVEL1. Alle anderen Fuses dürfen nicht gesetzt sein.
Manuelle Installation des Bootloaders
Der Atmega1284p benötigt den USBaspLoader, der vor Einbau auf der Platine über ISP programmiert werden muss.
In der Quelldistribution findet sich eine vorkonfigurierte Version des Bootloaders.
Im Verzeichnis bootloader
müssen die PROGRAMMER
-Optionen in der
Datei Makefile.inc
für das verwendete Programmiergerät angepasst
werden. Dann kann aus diesem Verzeichnis heraus der Bootloader
kompiliert und geflasht werden sowie die Fuses gesetzt werden:
$ make flash fuse
Der Atmega kann nun in das Modul eingesetzt werden. Bei aktiviertem Bootloader identifiziert sich das Gerät gegenüber dem PC mit
16c0:05dc Van Ooijen Technische Informatica shared ID for use with libusb
Es kann mit avrdude wie folgt angesprochen werden:
avrdude -p m1284p -c usbasp <commands...>
Zuvor müssen jedoch die USB-Geräte auf dem PC konfiguriert werden.
Aktivieren des Bootloaders
Um den Bootloader manuell zu aktivieren, drückt man die BOOT-Taste herunter, betätigt die RESET-Taste und lässt schließlich die Boot-Taste wieder los.
Sobald die Keyman64-Anwendung auf dem Gerät installiert ist, kann auch eine Tastenkombination für das Aktivieren des Bootloader konfiguriert werden:
b: boot
Dadurch kann der Bootloader durch Drücken von Meta-B aktiviert werden.
Alternativ kann der boot
-Befehl auch vom PC aus über USB ausgeführt werden:
$ keyman64 boot
Update des Bootloaders
Unter Umständen kann bei zukünftigen Firmware-Updates ein vorheriges Update des Bootloaders nötig werden.
Zu diesem Zweck wird eine Update-Anwendung bereitgestellt, aktuell keyman64-bootloader-updater-1.6.hex.
Um das Update des Bootloaders vorzunehmen, wird zunächst der bereits installierte Bootloader aktiviert. Dann wird das Update mit Hilfe von avrdude aufgespielt:
$ avrdude -p m1284p -c usbasp -U flash:w:keyman64-bootloader-updater-1.6.hex
Hierbei wird zunächst die vorhandene Keyman64-Anwendung mit der Update-Anwendung überschrieben. Diese wird dann unmittelbar ausgeführt und überschreibt den vorhandenen Bootloader mit der neuen Version.
Danach kann der neue Bootloader wieder aktiviert werden und die Anwendung wie im nächsten Abschnitt beschrieben neu installiert werden.
Installation und Update der Anwendung
Sobald der Bootloader installiert ist, kann der Anwendungsteil der Firmware mit dem folgenden Befehl installiert werden:
$ avrdude -p m1284p -c usbasp -U flash:w:keyman64-firmware-1.6.hex
Falls ihr die Firmware selbst kompiliert habt, kann alternativ
auch ein make program
aus dem Hauptverzeichnis der Quelldistribution
heraus ausgeführt werden.
Ab Version 1.4 kann die Anwendung auch über den update
-Befehl des
Kommandozeilen-Tools aktualisiert werden:
$ keyman64 update keyman64-firmware-<version>.bin
Dabei wird der Bootloader automatisch aktiviert und das Update vorgenommen.
Ab Version 1.5 akzeptiert der update
-Befehl auch Dateien im
Intel-HEX-Format. Es wird dabei aus der Dateiendung .bin
oder .hex
auf das zu verwendende Format geschlossen.
Ab version 1.6 akzeptiert der update
-Befehl auch eine
Konfigurationsdatei als zweites, optionales Argument. Wird eine
Konfigurationsdatei angegeben, so wird zunächst die im Gerät
gespeicherte Konfiguration gelöscht. Danach wird die Firmware
aktualisiert. Schließlich wird die Konfiguration aus der angegebenen
Datei neu generiert und wieder auf das Gerät geschrieben. Diese
Prozedur ist notwendig, wenn sich das binäre Format der Konfiguration
mit dem Update der Firmware ändert. Falls dies der Fall ist, wird in
den Release Notes und im Changelog explizit darauf hingewiesen.
Einrichten der USB-Geräte auf dem PC
Das Keyman64-Modul implementiert zwei verschiedene USB-Geräte, je nachdem, ob der Bootloader oder die Anwendung gerade aktiv ist.
Während des normalen Betriebs kann das Keyman64-Modul mit Hilfe des Konfigurationstools angesprochen werden. Dieses Gerät identifiziert sich gegenüber dem PC mit den folgenden Eigenschaften:
Vendor | OpenMoko, Inc. |
Manufacturer | Henning Bekel |
Device | Keyman64 |
Vendor ID | 1d50 |
Product ID | 60e9 |
Im Bootloader-Modus wird das USBasp-Programmiergerät emuliert. Dieses Gerät identifiziert sich gegenüber dem PC mit den folgenden Eigenschaften:
Vendor | Van Ooijen Technische Informatica shared ID for use with libusb |
Manufacturer | www.fischl.de |
Device | USBasp |
Vendor ID | 16c0 |
Product ID | 05dc |
Linux
Unter Linux werden die benötigten udev-Regeln zusammen mit dem Konfigurationstool installiert. Nach der Installation muss der folgende Befehl ausgeführt werden, um die Geräte sofort benutzen zu können:
# udevadm control --reload-rules
Im Bootloader-Modus erscheint das entsprechende Gerät als symlink
unter /dev/usbasp
. Im Normalbetrieb wird das entsprechende Gerät als
symlink unter /dev/keyman64
angelegt. Diese symlinks werden mit den
Dateiberechtigung 0666
angelegt und können so von jedem Benutzer
verwendet werden. Um den Zugriff zu beschränken können die jeweiligen
Regeln in /etc/udev/rules.d/10-keyman64.rules
angepasst werden.
Windows
Wird unter Windows eines der USB-Geräte zum ersten mal angeschlossen, versucht Windows, einen Treiber für dieses Gerät herunterzuladen und zu installieren. Da es sich bei beiden Geräten jedoch um treiberlose Geräte handelt, ist dieser Versuch sinnlos, da es schlicht keine speziellen Treiber für diese Geräte gibt. Die Windows-Treiberinstallation muss abgebrochen werden, da Windows ansonsten den Zugriff auf diese Geräte dauerhaft verhindert, da es aus seiner Sicht keine brauchbaren Treiber finden konnte.
Stattdessen muss das frei erhältliche Tool Zadig verwendet werden. Dieses generiert minimale Treiber, die die Geräte lediglich mit den für den generischen Zugriff benötigten Bibliotheken verknüpfen.
Wird Zadig nun ausgeführt, sollte es das Gerät “Keyman64”
erkennen. Es ist der “WinUSB” Treiber für dieses Gerät zu
installieren. Die benötigte libusb-1.0.dll
wird mit dem
Konfigurationstool installiert.
Nun muss noch einmal in den Bootloader-Modus gewechselt werden, um auch für dieses Gerät (USBasp) einen Treiber zu installieren. Hier wird ebenfalls der “WinUSB”-Treiber verwendet.
Für den Fall, dass das USBasp-Gerät über avrdude und nicht über das keyman64-tool verwendet werden soll, muss unter Umständen der Zadig-Treiber “libusb-win32” installiert werden, da die für Windows erhältlichen Versionen von avrdude meist noch gegen die veraltete libusb-0.1 gelinkt sind, deren Verwendung nur mit Zadigs libusb-win32-Treiber möglich ist.
Installation des Konfigurationstools keyman64 auf dem PC
Binäres Installationspaket (Windows)
Die Windows-Version kann mit Hilfe des
Win32-Installationspaketes installiert werden. Dieses
installiert auch die benötigte libusb-1.0.dll
und fügt das
Installationsverzeichnis zur Umgebungsvariable PATH
hinzu, so dass
die keyman64.exe
in der Eingabeaufforderung aus jedem beliebigen
Verzeichnis heraus aufgerufen werden kann.
Kompilieren und Installieren aus den Quelltexten
Linux & MacOSX
libusb-1.0
und das entsprechende “devel”-Paket (falls bei eurer
Distribution benötigt) müssen auf dem System vorhanden sein.
$ tar vxzf keyman64-1.6.tar.gz
$ cd keyman64-1.6
$ make
$ make install
Dies installiert nach erfolgreicher Kompilierung das
Konfigurationstool keyman64
nach /usr/local/bin
. Die
PREFIX
-Variable kann für die Installation mit einem anderen Präfix
benutzt werden, z.B. installiert make PREFIX=/usr install
nach
/usr/bin
. Die Variable DESTDIR
kann für die Installation in ein
lokales Verzeichnis mit dem gegebenen Präfix verwendet werden.
Unter Linux werden die benötigten udev-Regeln nach
/etc/udev/rules.d/
installiert. Nach der
Installation sollte als root-Benutzer zusätzlich der folgende Befehl
ausgeführt werden:
# udevadm control --reload-rules
Windows
Falls Cygwin verwendet wird kann eine Windows-Version auf die gleiche
Weise kompiliert und installiert werden wie unter Linux oder
MacOSX. Die benötigten Cygwin-Pakete sind libusb-1.0
und
libusb-1.0-devel
. Die resultierende Anwendung benötigt jedoch
weiterhin Cygwin-spezifische Bibliotheken (siehe ldd keyman64.exe
).
Eine native Win32-Anwendung kann mit Hilfe der Cross-Compiler-Suite
Mingw32 unter Linux oder Cygwin kompiliert werden. Falls nötig ist
dazu das Makefile
zu editieren und die MINGW32
-Variable
entsprechend des benötigten Präfixes für eure Mingw32-Installation
anzupassen. Dann kann mit Hilfe von make win32
die keyman64.exe
gebaut werden.
Konfiguration
Die Konfigurationsdatei ist eine einfache Textdatei, die die Befehle und Tastenkombinationen in lesbarem Format enthält. Mit Hilfe des Konfigurationstools wird diese Datei in ein binäres Format kovertiert und kann in den EEPROM-Speicher des Mikrokontrollers geschrieben werden. Siehe dazu den Abschnitt Übertragen der Konfiguration.
Syntax
Leerzeichen und Kommentare
Leere Zeilen und führende oder folgende Leerzeichen werden ignoriert. Leerzeichen sind nur relevant, wenn Schlüsselwörter oder Argumente voneinander getrennt werden
Kommentare beginnen mit einem Hash-Zeichen #
und erstrecken sich bis
zum Ende der aktuellen Zeile.
Schlüsselwörter
Alle Schlüsselwörter wie Befehle, Tastennamen sowie benutzerdefinierte
Symbole werden ohne Rücksicht auf Groß- oder Kleinschreibung
interpretiert. So ist z.B. die Schreibweise für den Befehl clear
äquivalent zu CLEAR
, Clear
oder auch clEAr
.
Befehle und Befehlstasten
Jede Zeile muss genau eine Befehlsangabe enthalten, auf die je nach Befehl weitere Argumente folgen können. Optional kann eine Tastenangabe vorangestellt werden.
[<Taste>:][<Regel>] <Befehl> [<Argumente>]
Wird keine Tastenangabe vorangestellt, wird der Befehl direkt beim Starten bzw. nach einem Reset ausgeführt, und kann so dazu verwendet werden, den Anfangszustand des Gerätes zu definieren.
Wird eine Tastenangabe vorangestellt, wird der Befehl an die angegebene Taste gebunden. Der Befehl kann dann durch Drücken der Meta-Taste und der angegebenen Taste ausgeführt werden.
Werden mehrere Befehle auf mehreren Zeilen an die gleiche Taste gebunden, so werden bei Betätigen der Tastenkombination alle Befehle nacheinander ausgeführt, und zwar in der Reihenfolge, in der sie in der Datei definiert wurden.
Befehle oder Befehlssequenzen können auch an “Slots” gebunden werden,
indem numerische Werte zwischen $40
und $F9
verwendet
werden. Diese Sequenzen können nicht direkt über Tastenkombinationen
aufgerufen werden, sondern nur indirekt mit Hilfe des Befehls
exec.
Tastenangaben können optional mit einem weiteren Argument versehen
werden, indem direkt nach dem Doppelpunkt 0
oder 1
angehängt
wird. Diese Werte bedeuten hier “ungerade” bzw. “gerade”. Wird
“ungerade” angegeben, wird der Befehl nur beim ersten, dritten,
fünften usw. Betätigen der Taste ausgeführt, bei “gerade”
entsprechend nur beim zweiten, vierten, sechsten mal usw.
Mit diesem feature lässt sich z.B. ein Umschalten zwischen Tristate-Zustand auf Masse bzw. von Masse auf Tristate mit einer einzigen Taste realisieren:
tristate a0
S:0 clear a0
S:1 tristate a0
In diesem Beispiel wird die Leitung a0 zunächst beim Einschalten auf
tristate gesetzt. Betätigt man nun <meta>-S
zum ersten mal, wird die
Leitung auf Masse gezogen. Beim erneuten Betätigen von <meta>-S
wird die
Leitung wieder in den Tristate-Zustand versetzt, und so weiter.
Tastennamen
Tasten können mit Hilfe von Tastennamen wie DEL
, A
, RUNSTOP
oder
ONE
angegeben werden. Eine Liste von gültigen Tastennamen gibt das
Konfigurationstool bei Angabe der Option --keys
aus.
Alternativ können Tasten auch numerisch über ihre Postion innerhalb der C64-Tastatur-Matrix angegeben werden. Die Tasten werden dabei von links nach rechts zeilenweise durchnummeriert, beginnend bei Reihe 0, Spalte 0 und endend bei Reihe 7, Spalte 7.
So entspricht $00
der Taste DEL
und $3f
entspricht der Taste
RUNSTOP
.
Numerische Tastenangaben können dezimal oder hexadecimal angegeben
werden. Hexadezimalen Werten muss entweder ein $
oder 0x
vorangestellt werden.
Ports
Die sechzehn Steuerleitungen sind in zwei acht Bit breiten Ports
organisiert. Für Befehle, die den Zustand der Steuerleitungen ändern,
kann der gewünschte Port mit Hilfe des Schlüsselwortes port
,
gefolgt von a
oder b
angegeben werden:
port [a|b]
Bits
Befehle, die die Steuerleitungen beinflussen, können auf einzelne
Kontrolleitungen oder auch nebeneinanderliegende Leitungen eines Ports
eingeschränkt werden. Die einzelnen Leitungen (Bits) werden durch
einen Dezimalwert im Bereich 0-7 angegeben. Dazu wird entweder das
Schlüsselwort bit
für einzelne Leitungen oder das Schlüsselwort
bits
für mehrere nebeneinanderliegende Leitungen verwendet:
bit <n>
bits <s>-<e>
Wobei n
eine einzelne Leitung angibt und s
und e
Anfang und Ende
eines Bereichs (inklusiv) angeben.
Kurznotation für Ports und Leitungen
Ab Version 1.6 können Port und Leitungen auch in Kurznotation angegeben werden:
<port>[[<s>][-<e>]]
So sind Ausdrücke wie port a bit 3
oder port b bits 0-2
gleichbedeutend mit
a3
bzw. b0-2
.
Zeitdauer
Eine Zeitdauer kann durch einen Dezimalwert, optional gefolgt von einer Zeiteinheit angegeben werden:
[<n><einheit>...][<n>]
Gültige Einheiten sind d
, h
, m
, s
und ms
für Tage, Stunden,
Minuten, Sekunden und Millisekunden. Wird keine Einheit angegeben, wird
die Dauer als Angabe in Millisekunden interpretiert.
Die maximal verwendbare Zeitdauer beträgt 232 Millisekunden, dies entspricht ungefähr 49 Tagen. Angaben, die diese Dauer überschreiten, werden auf die Maximaldauer gekürzt.
Beispiele:
1m30s
= Eine Minute und dreißig Sekunden
1s500
= Eine Sekunde und fünfhundert Millisekunden
10
= Zehn Millisekunden
Numerische Werte
Numerische Werte können in dezimaler, hexadezimaler oder binärer
Schreibweise angegeben werden. Hexadezimalen Werten wird ein $
vorangestellt, binäre Werte müssen mit %
eingeleitet werden.
Symbole
Benutzerdefinierte Symbole können verwendet werden, um die Lesbarkeit der Konfigurationsdatei zu verbessern. Symbole werden als einfache Schlüssel/Wert-Paare durch folgende Syntax definiert:
<name> = <value>
Symbolnamen dürfen nur aus alphanumerischen Zeichen oder Unterstrichen bestehen. Es wird eine Warnung ausgegeben, wenn ein Konflikt mit bereits definierten Schlüsselwörtern oder Symbolen entsteht.
Sobald ein Symbol definiert wurde, werden alle folgenden Verwendungen durch den angegebenen literalen Wert ersetzt. Wird ein Symbol verwendet, bevor es definiert wurde, wird eine entsprechende Fehlermeldung ausgegeben.
Zum Beispiel kann die folgende Definition einer Befehlssequenz
r: clear port a bit 0 r: sleep 10 r: tristate port a bit 0
durch die Verwendung von Symbolen sehr viel lesbarer gestaltet werden:
RESETLINE = port a bit 0 RESET = r RESET: clear RESETLINE RESET: sleep 10 RESET: tristate RESETLINE
Konfigurations- und Wartungsbefehle
using
using <8808|22106>
Gibt an, welche Crosspoint-Switch-Variante verwendet wird. Es kann
entweder ein CD74HC22106 oder ein MT8808 verwendet werden. Der
Standardwert ist 8808
.
speed
speed <fast|slow>
Gibt an, in welcher Geschwindigkeit die Matrix der physischen Tastatur
gescannt wird. Schnell (fast
) ist die Standardeinstellung und sollte
in den meisten Fällen problemlos funktionieren. Der langsame Modus
(slow
) wird nur benötigt, wenn die Länge der Kabel zur Tastatur
deutlich länger ist, als es bei einer üblichen C64-Tastatur der Fall ist,
zum Beispiel wenn das Gerät in einem Commodore SX64 installiert wird.
Der langsame Modus beeinträchtigt dabei in keinster Weise die Geschwindigkeit der Tastaturabfrage. Beide Modi scannen die Tastatur schnell genug, um eine unmittelbare Reaktion auf Tastatureingaben zu gewährleisten.
expand
expand ports=<n> clock=<line> data=<line> latch=<line> enable=<line>
Konfiguriert eine Porterweiterung durch <n> hintereinandergeschaltete 74595 serielle Schieberegister, wobei die Leitungen für CLOCK, DATA, LATCH und ENABLE des ersten Schieberegisters mit den angegebenen Steuerleitungen verbunden werden.
Hierbei müssen die Steuerleitungen in Kurznotation angegeben werden.
Siehe Porterweiterung für weitere Details.
meta
meta <Taste>
Der Befehl meta
definiert die zu verwendende
Meta-Taste. Standardeinstellung ist die Linkspfeil-Taste
(ARROWLEFT
).
boot
boot
Aktiviert den Bootloader. Der Bootloader erwartet Konfigurations- oder Firmware-Updates über USB. Das Gerät verbleibt im Bootloader-Modus bis eine neue Konfiguration oder Firmware übertragen wurde oder der RESET-Button am Gerät betätigt wird.
Wird dieser Befehl über die USB-Fernsteuerung durch ausführen des
Befehls keyman64 boot
auf dem PC ausgeführt, springt der
Mikrokontroller direkt in den Bootloader, ohne die USB-Kommunikation
ordnungsgemäß zu beenden. Dies führt zur Ausgabe der folgenden
unbedenklichen Fehlermeldung:
error: could send usb control message: Pipe error
Diese Fehlermeldung kann ignoriert werden sofern der Bootloader erfolgreich aktiviert wurde.
save
save
Speichert den aktuellen Zustand der Steuerleitungen dauerhaft im
EEPROM-Speicher. Dieser Zustand kann später mit Hilfe des Befehls
restore
wieder hergestellt werden.
restore
restore
Stellt den zuvor durch den Befehl save
im EEPROM-Speicher
gespeicherten Zustand der Steuerleitungen wieder her. Wurde zuvor
kein Zustand gespeichert, werden alle Steuerleitungen in den
Tristate-Zustand versetzt.
memorize
memorize
Speichert den aktuellen Zustand der Steuerleitungen temporär im RAM.
RAM. Dieser Zustand kann später über den Befehl recall
wieder
hergestellt werden.
recall
recall
Stellt den zuvor über den Befehl recall
im RAM abgelegten Zustand
der Steuerleitungen wieder her. Wurde zuvor kein Zustand im RAM
abgelegt, werden alle Steuerleitungen in den Tristate-Zustand
versetzt.
Befehle zur Kontrolle der Steuerleitungen
set
set <Port> [<Bits>] [to <Wert>]
Setzt die angegebenen Bits des angegebenen Ports auf den angegebenen Wert. Wird kein Wert angegeben, werden alle betroffenen Bits auf 1 (high) gesetzt. Werden keine explizit Bits angegeben, wird der gesamte Port auf den angegebenen Wert gesetzt.
Beispiele:
set port a bit 3 to 1
– Setzt Bit 3 des Ports A auf high
set port b bits 3-4 to 2
– Setzt für Port B Bit 3 auf low und Bit vier auf high (2 dezimal = 10 binär)
set port a
– Setzt die Bits 0-7 von Port A auf high
clear
clear <Port> [<Bits>]
Löscht die angegebenen Bits des angegebenen Ports, also setzt sie auf 0 (low). Werden keine Bits angegeben, werden alle Bits des angegebenen Ports gelöscht.
tristate
tristate <Port> [<Bits>]
Versetzt die angegebenen Bits des angegebenen Ports in den Tristate-Zustand. Werden keine Bits angegeben, werden alle Bits des angegebenen Ports in den Tristate-Zustand versetzt.
Eine Leitung in den Tristate-Zustand zu versetzen bedeutet, die Leitung in einen hochohmigen Zustand zu bringen, der von angeschlossenen digitalen Bausteinen weder als “High” noch als “Low” interpretiert wird. In digitalen Schaltungen ist entspricht dieser Zustand einer nicht verbundenen Leitung.
Dies ist vor allem für die Simulation von Tastern notwendig. Ein zweipoliger Taster stellt keinen Kontakt her, solange er nicht gedrückt wird. Die angeschlossene Steuerleitung ist somit meist im Tristate-Zustand. Wird der Schalter geschlossen, wird die angeschlossene Steuerleitung in der Regel entweder mit VCC (high) oder GND (high) verbunden.
So verbindet zum Beispiel ein im C64 verbauter Reset-Taster die RESET-Leitung des C64 kurzzeitig mit Masse, das RESET-Signal geht auf low und der C64 wird zurückgesetzt.
Um dies im Keyman zu realisieren, verbindet man die Reset-Leitung mit einer der Steuerleitungen des Keymans, zum Beispiel mit der Leitung 0 auf Port A. Nun kann ein Reset über eine Tastenkombination wie folgt konfiguriert werden:
tristate a0 # Beim Einschalten ist der Taster erstmal offen,
# die RESET-Leitung wird also vom Keyman nicht beeinflusst
r: clear a0 # Wird Meta-r gedrückt, wird der Taster "geschlossen",
# also die RESET-Leitung wird auf Low gezogen
r: sleep 20 # Wir halten die RESET-Leitung für 20 Millisekunden auf low...
r: tristate a0 # Und "lassen den Taster dann wieder los",
# so dass die RESET-Leitung nicht länger vom Keyman beeinflusst wird
invert
invert <Port> [<Bits>]
Invertiert den Zustand der angegebenen Bits auf dem angegebenen Port. Werden keine Bits angegeben, werden alle Bits des angegebenen Ports invertiert. Ist eine Leitung zuvor im Tristate-Zustand, wird sie auf High gesetzt.
increment
increment <Port> [<Bits>]
Erhöht die angegebenen Bits auf dem angegebenen Port um eins. Dabei werden die Zustände der angegebenen Bits als binärer Wert interpretiert. Werden keine Bits angegeben, wird der Wert aller Bits des angegebenen Ports erhöht.
Dies kann zur Realisierung eines Binärzählers auf einem Port oder einem bestimmten Bereich eines Ports verwendet werden. Sind alle Bits des angegebenen Bereichs bereits auf 1 gesetzt (also hat der Zähler sein Maximum ereicht), werden alle Bits wieder gelöscht.
Beispiel für einen vier Bit breiten Binärzähler im unteren Teil von Port A:
increment port a bits 0-3
decrement
decrement <port> [<bits>]
Erniedrigt die angegebenen Bits um eins. Gegenstück zum Befehl decrement
.
Befehle zur Steuerung der Tastaturmatrix
Die folgenden Befehle Steuern den Zustand der vom Computer gescannten, virtuellen Tastaturmatrix.
down
down <Taste>
Hält die angegebene Taste herunter. Die Taste bleibt solange gedrückt,
bis sie durch den Befehl up
wieder losgelassen wird oder die
Meta-Taste losgelassen wird.
up
up <Taste>
Lässt die angegebene Taste wieder los, sofern sie zuvor durch den
Befehl down
gedrückt gehalten wurde.
press
press <key>
Betätigt die angegebene Taste einmalig. Die Taste wird für 20 Millisekunden heruntergedrückt und dann wieder losgelassen.
Dies ist also die Kurzform für:
down <Taste>
sleep 20
up <Taste>
type
type <Zeichenkette>
Gibt die angegebene Zeichenkette auf der virtuellen Tastatur ein. Um
das Betätigen der Return-Taste hinzuzufügen kann die Escape-Sequenz
\r
angehängt werden.
ASCII-Kleinbuchstaben bewirken das Drücken der entsprechenden Taste ohne weitere Modifier wie SHIFT, CONTROL oder CBM. ASCII-Großbuchstaben bewirken das Drücken der entsprechenden Taste in Verbindung mit dem dazu nötigen Modifier.
Um PETSCII-Buchstaben einzugeben, die nicht im ASCII-Zeichensatz
vorhanden sind, kann einfach das ASCII-Zeichen an der entsprechenden
Postion verwendet werden. Zum Beispiel befindet sich im
PETSCII-Zeichensatz das Pfund-Symbol an Position 92, im
ASCII-Zeichensatz findet sich dort der Backslash \
. Verwendet man in
der angegebenen Zeichenkette also einen Backslash, führt dies zur
Ausgabe eines Pfund-Symbols am C64.
Alternativ kann jedes PETSCII-Zeichen durch eine numerische Escape-Sequenz angegeben werden, entweder in dezimaler oder hexadezimaler Schreibweise:
\xnn -- hexadezimale Schreibweise, z.B. \x0a
\{ddd} -- dezimale Schreibweise, z.B. \{147}
Zusätzlich werden die folgenden Escape-Squenzen interpretiert:
\\ -- literaler Backslash, (0x5c) (Pfund-Symbol auf dem C64)
\r -- return (0x0d), entspricht dem Drücken der Taste RETURN
\n -- newline (0xa), entspricht dem Drücken der Tasten SHIFT und RETURN
\f -- form feed (0x0c), entspricht dem Drücken der Tasten SHIFT und CLRHOME
Der Keyman kann allerdings nur solche Zeichen eingeben, die
tatsächlich auch auf einer physikalischen Tastatur erzeugt werden
können. Dies schließt die PETSCII-Steuerzeichen für das Umschalten des
Zeichensatzes (Codes 14 und 142) sowie die Steuerzeichen für das
Sperren und Freigeben des Zeichensatzwechsels (Codes 8 und 9) aus.
Diese können auch am C64 nur programmatisch (z.B. durch print
chr$(9)
erzeugt werden.
Beispiel (für den C64):
type load"*",8,1\r
– gibt LOAD"*",8,1
ein und betätigt RETURN
swap
swap <Taste> <Taste>
Tauscht die angegebenen Tasten gegeneinander aus, bevor sie an den Computer weitergeleitet werden. So kann die Tastaturbelegung des Computers verändert werden, z.B. um ein QUERTZ-Layout zu erhalten:
swap Z Y
Dies wirkt sich allerdings nur auf die Tasten aus, die zum Computer weitergeleitet werden. Eine an Meta-Z gebundene Befehlssequenz wird hier also nach wie vor durch Betätigen der physischen Z-Taste ausgelöst.
map
map <Port> <Bit> to <Taste>
Verknüpft die angegebene, einzelne Steuerleitung mit der angegebenen Taste. Die Leitung wird zu einer low-aktiven Eingangsleitung. Solange die Leitung auf Low gezogen wird, wird die angegebene Taste gedrückt.
Sobald ein Pin auf diese Weise mit einer Taste verknüpft wurde, darf sein Zustand nicht länger durch andere Befehle verändert werden.
password
password
Ermöglicht es dem Benutzer, ein Passwort einzugeben, mit dem die
Tastatur wieder entsperrt werden kann, nachdem sie über den Befehl
lock
gesperrt wurde. Dazu muss der C64 im Direktmodus sein, damit
die Tastaturausgaben des Keymans auf dem Bildschirm sichtbar werden.
Das Password muss zweimal eingegeben werden. Stimmen beide Eingaben überein, wird das Passwort dauerhaft im EEPROM-Speicher hinterlegt.
Um das Password zurückzusetzen genügt es, zweimal ein leeres Passwort einzugeben.
lock
lock
Sofern ein Passwort über den Befehl password
gesetzt wurde, wird die
Tastatur gesperrt. Es werden keine Eingaben mehr an den Computer
weitergeleitet, bis der Benutzer das Passwort auf der Tastatur eingibt
und mit RETURN bestätigt.
Bevor die Tastatur gesperrt wird, werden alle Befehle ausgeführt, die
an die virtuelle Taste LOCKED
gebunden sind. Wird die Tastatur
wieder freigegeben, werden alle Befehle ausgeführt, die an die
virtuelle Taste UNLOCKED
gebunden sind.
Dies kann dazu verwendet werden, beim Sperren oder Entsperren der Tastatur zusätzliche Befehle auszuführen. So kann zum Beispiel beim Sperren der Tastatur auf einen unleserlichen Zeichensatz geschaltet werden, um damit auch den Bildschirm (genauer gesagt den Text darauf) zu “sperren”. Bei UNLOCKED kann dann wieder auf einen lesbaren Zeichensatz geschaltet werden.
Kontrollfluss-Befehle
exec
exec <Taste>|<Slot>
Führt die an die angegebene Taste oder den angegebenen Slot gebundene Befehlssequenz aus. Die Ausführung der aktuellen Befehlssequenz wird fortgesetzt, nach dem die angegebene Sequenz ausgeführt wurde.
sleep
sleep <duration>
Pausiert die Ausführung von Befehlen für die angegebene Zeitdauer. Während dieser Zeit werden keine Tastatureingaben weitergeleitet oder als gebundene Tastenkombinationen interpretiert.
requires
<Taste>: requires <n>
Diese Anweisung bewirkt, dass die an die angegebene Taste gebundene Befehlssequenz nur ausgeführt wird, nachdem die Taste n-mal betätigt wurde, während die Meta-Taste durchgehend gehalten wurde.
Dies ist nützlich, wenn eine potentiell destruktive Aktion wie ein
Reset vor versehentlicher Ausführung geschützt werden soll. So
benötigt die folgende Reset-Sequenz eine dreimalige Betätigung der
Taste R
bei durchgängig gedrückter Meta-Taste:
r: requires 3
r: clear port a bit 0
r: sleep 20
r: tristate port a bit 0
Dies betrifft allerdings nur die interaktive Ausführung über die
Tastatur. Der Befehl exec r
würde die Sequenz auch in diesem Fall
unmittelbar ausführen.
Befehle zur Anzeige von Informationen
Damit die von diesen Befehlen ausgegebene Information auf dem Bildschirm erscheint, muss der Computer im Eingabemodus sein.
version
version
Gibt die aktuelle Version der Firmware aus.
status
status
Gibt den aktuellen Status der Steuerleitungen aus in der folgenden Form aus:
A XXXX0010
B 11111001
Dabei ist 0 = low, 1 = high und X = tristate
Konfigurationstool
$ keyman64 --help
Keyman64 v1.6 Copyright (C) 2016 Henning Bekel. License GPLv3: GNU GPL version 3 <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Usage: keyman64 [<options>] convert [<infile>|-] [<outfile>|-] keyman64 [<options>] configure [<infile>] keyman64 [<options>] update <firmware> [<config>] keyman64 [<options>] reset keyman64 [<options>] <command> keyman64 [<options>] <script>|- Options: -v, --version : print version information -h, --help : print this help text -d, --device : specify usb device (default: /dev/keyman64) -D, --delay : delay in ms between commands -k, --keys : list key names and synonyms -p, --preserve : deprecated as of version 1.5 -i, --identify : request firmware identification via USB Files: <infile> : input file, format is autodetected <outfile> : output file, format determined by extension <script> : script file containing keyman64 commands <firmware> : binary or ihex firmware image (.bin or .hex) *.conf : plain text config file format *.bin : binary file format (default) Optional arguments default to stdin or stdout Command: (any valid keyman64 command)
Übertragen der Konfiguration
Version 1.4 und folgende Versionen
Ab der Version 1.4 kann die Konfiguration über den Befehl configure
in einem Schritt konvertiert und über USB zum Gerät übertragen werden:
$ keyman64 configure keyman64.conf
Hier wird die Konfigurationsdatei keyman64.conf
eingelesen und in
das binäre Format konvertiert. Danach wird das Gerät über USB in den
Bootloader-Modus versetzt und die Konfiguration in den EEPROM-Speicher
des Atmega übertragen. Schließlich wird das Gerät zurückgesetzt und
die Anwendung startet mit der neuen Konfiguration.
Die im nächsten Abschnitt beschriebene Methode kann weiterhin verwendet werden.
Version 1.3 und frühere Versionen
Über den convert
-Befehl wird die Konfigurationsdatei in das
Binärformat konvertiert:
$ keyman64 convert keyman64.conf keyman64.bin
Falls die Konfigurationsdatei keine Fehler enthält wird die Datei
keyman64.bin
erzeugt.
Nun muss der Bootloader aktiviert werden.
Die binäre Konfiguration wird nun mittels avrdude
übertragen:
$ avrdude -p m1284p -c usbasp -U eeprom:w:keyman64.bin:r
Nach der Übertragung wird das Gerät automatisch zurückgesetzt und startet mit der neuen Konfiguration.
Der Bootloader setzt den Mikrokontroller unmittelbar nach dem Update zurück. Dies geschieht noch bevor die aktuelle USB-Kommunikation zwischen dem Bootloader und avrdude ordnungsgemäß beendet wird. Daher erscheint die folgende unbedenkliche Fehlermeldung:
error: usbasp_transmit: usb_control_msg: sending control message failed
Diese Fehlermeldung kann ignoriert werden sofern avrdude zuvor die erfolgreiche Übetragung der Daten gemeldet hat.
Erhalten des gespeicherten Zustands der Steuerleitungen
Die in diesem Abschnitt beschriebene Option –preserve ist ab Version 1.5 nicht mehr notwendig. Ab Version 1.6 wird der gespeicherte Zustand nicht mehr beim Übertragen der Konfiguration überschrieben.
Um den gespeicherten Zustand zu erhalten kann die Option --preserve
zusammen mit dem Befehl convert
verwendet werden. In diesem Fall
wird zunächst der aktuell gespeicherte Zustand per USB vom Gerät
gelesen und später wieder zu der neu erzeugten Binärdatei
hinzugefügt. Dazu muss das Gerät allerdings über USB angeschlossen
sein.
Bei Verwendung des oben beschriebenen configure
-Befehls wird der
Zustand automatisch erhalten.
Fernsteuerung über USB
Mit Hilfe des Konfigurationstools können auch beliebige Befehle vom PC über USB zum Gerät übermittelt und dort direkt ausgeführt werden.
Ein einzelner Befehl kann direkt über die Kommandozeile abgesetzt werden, zum Beispiel
$ keyman64 press F5
Werden keine Argumente auf der Kommandozeile angegeben, so liest das Konfigurationstool Befehle von der Standardeingabe ein. Dabei muss jede Zeile nur einen Befehl enthalten. Allerdings werden die Befehle erst gelesen und ausgeführt, nachdem die Standardeingabe geschlossen wurde, also alle Befehle eingegeben oder aus einer Pipe gelesen wurden:
$ keyman64
reading commands from stdin...
> type load"$",8\r
> sleep 5s
> type list\r
> ^D
$
Handelt es sich beim ersten Argument um eine Datei, werden Befehler aus dieser Datei gelesen und an das Gerät übermittelt.
So kann man ein Skript wie das folgende in einer Datei speichern:
exec rightshift
press f5
press cursordown
press cursordown
press cursordown
press return
und mit folgendem Befehl ausführen:
$ keyman64 --delay 250 script.txt
Die Option --delay
fügt hier eine Verzögerung von 250ms nach jedem
Befehl hinzu. Dies verhindert, nach jedem Befehl einen expliziten
sleep
-Befehl hinzufügen zu müssen.
Unter Linux und MacOSX kann der #!
-Mechanismus verwendet
werden um solche Skripte direkt ausführbar zu machen. Dazu macht man
das Skript ausführbar und fügt eine entsprechende #!
-Zeile am
Anfang der Datei hinzu, zum Beispiel:
#!/usr/bin/keyman64 --delay 250
press f5
press cursordown
press return
Dann kann das Skript wie jeder andere Befehl ausgeführt werden.
Porterweiterung
Ab Version 1.6 kann die Anzahl der verfügbaren Steuerleitungen auf einfache Weise erweitert werden. Es können ein oder mehrere serielle Schieberegister des Typs 74595 in Serie angeschlossen werden. Lediglich vier der auf dem Gerät ausgeführten Steuerleitungen müssen dazu mit dem ersten Schieberegister verbunden werden. Das erste Schieberegister kann somit effektiv vier weitere Leitungen bereitstellen. Jedes weitere angeschlossene Schieberegister erweitert das Gerät dann um einen weiteren 8-Bit breiten Port.
Schieberegister des Typs 74595 sind auch auf kleinen Breakout-Boards erhältlich. Diese können auf einfache Weise hintereinander gehängt werden. Zum Beispiel bietet Artekit ein günstiges Breakout-Board an, das für diesen Zweck gut geeignet ist.
Der Befehl expand wird dabei verwendet, um dem Gerät mitzuteilen, wie viele zusätzliche Ports angeschlossen sind und welche der nativen Steuerleitungen mit den vier Eingängen des ersten Schieberegisters verbunden sind. Die zusätzlichen Ports werden dann beginnend mit dem Buchstaben “c” in alphabetischer Reihenfolge benannt. So können die zusätzlichen Ports genau wie die nativen Ports a und b in anderen Direktiven und Befehlen angegeben werden.
Der Befehl expand
erwartet die Angabe der für das Schieberegister
nötigen Steuerleitungen unter den Bezeichnungen CLOCK, DATA, LATCH und
ENABLE. Abhängig vom Datenblatt des ICs oder des verwendeten
Breakout-Boards können diese Leitungen unterschiedlich benannt sein:
Keyman64 | 74595 Pinnummer | Beschreibung | Andere geräuchliche Bezeichnungen |
CLOCK | 11 | shift register clock input | CLK, SCK, SHCP, SRCLK |
DATA | 14 | serial data input | DS, SER, SER-IN |
LATCH | 12 | storage register clock input | STCP, RCLK |
ENABLE | 13 | output enable input (active low) | OE, EN |
RESET | 10 | serial clear input (active low) | MR, CLR, SRCLR |
Die ENABLE- und die RESET-Leitung des Schieberegisters sollten jeweils über einen 4.7k Widerstand auf High-Pegel gezogen werden. Beim oben verlinkten Artekit-Board ist dies bereits der Fall.
Beim Einschalten oder nach einem Reset werden alle erweiterten Leitungen zunächst in den Tristate-Zustand versetzt. Sobald eine dieser Leitungen durch einen Befehl gesetzt wird, werden alle Register aktiviert. Leitungen, deren Zustand noch nicht definiert ist, werden dann auf Low gezogen. Es empfielt sich daher, den Zustand der zusätzlichen immer explizt zu initialisieren.
Die erweiterten Leitungen können weder in den Tristate-Zustand versetzt werden noch als Eingangsleitungen verwendet werden. Daher ist sind die Befehle tristate und map für erweiterte Leitungen nicht zulässig. Das Konfigurationstool wird in diesem Fall eine entsprechende Fehlermeldung ausgeben.
Beispiel
Dieses Bild zeigt, wie ein oder mehrere 74595-Breakout-Boards angeschlossen werden können. Hier werden die unteren vier Steuerleitungen von Port B mit dem ersten Schieberegister verbunden.
Der entsprechende expand
-Befehl lautet:
expand PORTS=2 DATA=b0 CLOCK=b1 LATCH=b2 ENABLE=b3
Alle auf diesen Befehl folgenden Befehle in der Konfigurationsdatei können die zusätzlichen Ports nun als Port C bzw. Port D ansprechen, zum Beispiel:
X: set port d bit 5
Y: inc port c bits 0-1
Serielle Schnittstelle
Der Anschluss P4 stellt eine einfache serielle Schnittstelle zur Verfügung, über die der Keyman64 von externer Hardware kontrolliert werden kann. Der linke Pin ist dabei der Eingang für ein low-aktives Clock-Signal (auf der Platine mit /CLK gekennzeichnet). Der rechte Pin stellt das Eingangssignal DATA bereit. Bei fallender Flanke des Clock-Signals wird der an DATA anliegende Wert vom Gerät übernommen.
Jeder Befehl besteht aus einem Befehlsbyte, gefolgt von einem oder
mehreren Parameterbytes. Bytes werden jeweils in little-endian
Reihenfolge übermittelt, das heißt das niederwertigste Bit wird zuerst
übermittelt. Um zum Beispiel die Taste RUNSTOP
zu betätigen, sieht
der eigentliche Befehl wie folgt aus:
00000100 00111111
=> 0x4 (Befehl) 0x3f (Parameter)
muss jedoch wie folgt übermittelt werden:
00100000 11111100
=> Befehl, dann Parameter, je LSB zuerst.
Die folgenden Befehle stehen zur Verfügung:
00000001 <key>
: An Taste oder Slot gebundene Befehlssequenz ausführen00000010 <Taste>
: Taste gedrückt halten00000011 <Taste>
: Taste loslassen00000100 <Taste>
: Taste betätigen (für 20ms drücken)00000101 <Pin> <Taste>
: Pin mit Taste verknüpfen (entspricht map)00000111 <Code>
: PETSCII code auf der Tastatur eingeben
Beim Verknüpfen eines Pins mit einer Taste wird der Pin über die Bits 0-2 angegeben, die höherwertigen Bits bezeichnen den Port (0 = a, 1 = b, 10 = c usw).
Wird eine Taste über die serielle Schnittstelle gedrückt gehalten, so bleibt sie gedrückt, bis sie auch über die serielle Schnittstelle wieder losgelassen wird. Der Zustand der physischen Taste wird währenddessen ignoriert.
Verbindung der seriellen Schnittstelle mit dem C64
Eine Möglichkeit der Verwendung der seriellen Schnittstelle ist der Anschluss an die Bits 3 und 4 des 6510 IO-Ports. Diese sind als “Cassette Sense” and “Casette Write” am Tapeport verfügbar (natürlich nur, wenn der Tapeport ansonsten nicht verwendet wird). “Cassette Sense” wird dann an /CLK angeschlossen, “Cassette Write” wird als DATA-Signal verwendet.
Die Quelldistribution enthält die Dateien serial.h
und serial.asm
im KickAssembler3-Format. Diese können benutzt werden um serielle
Befehle vom C64 über den Kassettenport zum Keyman64 zu senden.
Zum Beispiel führt der folgende Code die Keyman64-Befehlsequenz aus, die an die Tastenkombination Meta-RUNSTOP gebunden ist:
.import source "serial.h"
jsr serial.open // Kassettenport-Leitungen auf Ausgang schalten
lda #Command.exec // Befehlsbyte für den exec-Befehl in den Akku
jsr serial.write // Die Bits werden nach rechts rausgeschoben (lsb first)
lda #$3f // Dies ist der Code für die "RUNSTOP" Taste
jsr serial.write // Wieder nach rechts rauschieben
jsr serial.close // Kassettenport-Leitungen zurück auf Eingang schalten
rts
.import source "serial.asm"
Anwendungsbeispiele
Kernal umschalten und Reset auslösen
Nehmen wir an, im C64 ist ein zweifacher Kernelumschalter verbaut. Diese Umschalter haben meistens eine Leitung, der die höchste Adressleitung des Eproms kontrolliert und so den Kernal auswählt, der vom C64 gelesen wird. In der Regel wird erwartet, diese Leitung mit Hilfe eines Schalters umzuschalten, der im Gehäuse verbaut wird.
Anstelle des Schalters kann man nun den Keyman64 verwenden.
Man entfernt einfach den Schalter und verbindet die Steuerleitung mit
einer der sechzehn Steuerleitungen des Keymans. Für dieses Beispiel
verwenden wir die höchste Leitung des ersten Ports (port a bit 7
).
Wir erzeugen nun eine Konfigurationsdatei folgenden Inhalts:
clear port a
clear port b
k: invert port a bit 7
Und übertragen diese Konfiguration auf den Keyman:
$ keyman64 configure example.conf
Nachdem die Konfiguration übertragen wurde startet der Keyman
neu. Zunächst werden alle Befehle ausgeführt, die nicht an eine
Tastenkombination gebunden sind. Dies erlaubt es uns, den
Anfangszustand der Leitungen zu bestimmen. Hier verwenden wir den
Befehl clear
, um alle Leitungen zunächst auf low zu setzen. Die
Leitung zum Kernal-Umschalter ist also auch low, der erste Kernal ist
ausgewählt.
Die Tastenkombination Meta-k invertiert nun die Eprom-Adressleitung des Kernelumschalters und schaltet so effektiv zwischen den beiden Kernaln hin und her.
Das reicht zwar auf Hardwareebene, allerdings kann dies den C64 immer noch abstürzen lassen, falls der Kernal gerade dann umgeschaltet wird, wenn Code aus dem Kernal ausgeführt wird. Besser wäre es, den C64 nach dem Wechsel des Kernals gleich zurückzusetzen.
Wir verbinden also die Reset-Leitung des C64 mit der ersten Steuerleitung des Ports A und verändern die Konfiguration wie folgt:
tristate port a bit 0
clear port a bits 1-7
clear port b
r: clear port a bit 0
r: sleep 10
r: tristate port a bit 0
k: invert port a bit 7
k: exec r
Wenn wir nun Meta-R drücken, wird die Reset-Leitung, die zuvor im Tristate-Zustand war, für 10 Millisekunden auf low gezogen and danach wieder in den Tristate-Zustand versetzt, was zu einem Reset des C64 führt.
Wenn wir nun Meta-K drücken, wird der Kernel wie zuvor umgeschaltet. Dannach führen wir aber mit Hilfe des Befehls exec noch die Reset-Sequenz aus, die bereits an Meta-R gebunden ist.
So können wir den Kernal wechseln und einen Reset durchführen, indem wir einfach Meta-K drücken, anstatt jedesmal den C64 auszuschalten, einen Schalter umzulegen und den C64 wieder einzuschalten, wenn wir den Kernal wechseln wollen.
Während des Resets eine Taste gedrückt halten
Einige Expansionsport-Module führen spezielle Funktionen aus, wenn
eine Taste während des Resets gedrückt wird. Auch das kann der Keyman
für uns erledigen. Die folgende Tastenkombination führt einen Reset
aus und hält dabei die Taste RUNSTOP
gedrückt:
u: down runstop
u: clear port a bit 0
u: sleep 10
u: tristate port a bit 0
u: sleep 1s
u: up runstop
Tastaturmacros definieren
Der Befehl type kann ebenfalls an eine Taste gebunden werden:
d: type load"$",8\r
Wenn wir nun Meta-D drücken, tippt der Keyman load"$",8<return>
für
uns. Die Escape-Sequenz \r
steht hierbei für die Taste RETURN
.
Tastaturlayout ändern
Der Befehl swap kann verwendet werden, um zwei Tasten auf der Tastatur gegeneinander auszutauschen. Um zum Beispiel ein QWERTZ-Layout zu verwenden, genügt der folgende Befehl:
swap z y
Soll zwischen QWERTY und QWERTZ umgeschaltet werden können, kann der Befehl wie jeder andere Befehl an eine Taste gebunden werden:
y: swap z y
Meta-Y schaltet nun zwischen den Layouts hin und her.
Lizensierung
Copyright (C) 2016 Henning Bekel <h.bekel@googlemail.com>
Hardware lizensiert unter CERN OHL v.1.2, siehe ./hardware/LICENSE.txt
Software und Firmware lizensiert unter GNU GPLv3, siehe ./LICENSE
Die Software enthält Quelltext unter MIT-Lizenz von https://github.com/arkku/ihex für das Lesen von Intel HEX Dateien, Copyright (C) 2013-2015 Kimmo Kulovesi, siehe ./intelhex/LICENSE
Die Firmware enthält den V-USB-Treiber (https://www.obdev.at/vusb), (C)2008 Objective Development GmbH.
Mitgeliefert wird im ./bootloader Verzeichnis der USBasp bootloader, (C)2013 Stephan Baerwolf (matrixstorm@gmx.de) und (C)2008 Objective Development GmbH (https://www.obdev.at/vusb).
In Übereinstimmung mit den (identischen) Lizenzen für den V-USB-Treiber und den USBasp-Bootloader (./firmware/usbdrv/License.txt and ./bootloader/License.txt, ist das gesamte Projekt veröffentlicht unter
http://www.henning-bekel.de/keyman64
Zusätzlich enthält die Distribution
- Einen Schaltplan im PDF-Format, siehe ./hardware/keyman64-schematics.pdf
- Den vollständigen Quelltext für die Host-Software ./firmware
- Eine README-Datei im ASCII-Format, die den Zweck des Projekts beschreibt und darlegt, welche Komponenten in welchen Verzeichnissen und Dateien bereitgestellt werden
- Verweise auf (https://www.obdev.at/vusb)
Die USB-Product- und USB-Vendor-IDs für das Keyman64 USB-Gerät wurden freundlicherweise bereitgestellt von OpenMoko, Inc (http://openmoko.org).