Hallo Besucher, der Thread wurde 109k mal aufgerufen und enthält 679 Antworten

letzter Beitrag von Emwee am

Keyman64: Tastatur- und Hardwarecontroller

  • Hallo,


    ich möchte mal eine Alternative zum Crosspoint-Switch vorstellen. Ich hatte mir vor kurzen auch ein kleines Board gebaut um eine C64-Tastatur zu emulieren und entsprechend Kommandos über die serielle Schnittstelle zu empfangen. Der Clou dabei ist, die Ports des CIA sind direkt mit 2 Ports des Atmega (in meinen Fall ein Atmega324) verbunden. Die Matrix wird nun in Software im AVR realisiert, in dem hier die Pin-Change-Interrupts verwendet werden. Sobald der C64 also ein Signal auf low zieht wird entsprechend der anderen Port von der Firmware angepasst (entsprechende Pins auf Masse legen bzw. weiterhin als Input konfiguriert). Damit das Ganze funktioniert, muss der Atmega recht schnell getaktet werden (in meinen Fall läuft er mit 14.56MHz) und es sollten keine weiteren Interrupts in der Firmware verwendet werden, da es sonst zu Verzögerungen in der Ausführung der Pin-Change-Interrupts kommen könnte.



    Anbei noch ein paar Bildchen.

  • zschunky:


    Ja, das funktioniert, aber für meine Anwendung ist das leider nicht möglich. Ich habe diesen Ansatz anfangs auch verfolgt.


    So wie ich es sehe hast du keine echte Tastatur mehr, d.h. du musst nicht kontinuierlich eine echte Tastatur scannen und deren Zustand an den C64 weiterleiten. Wenn ich das Scannen der Matrix jedesmal unterbrechen muss, wenn eine Leitung des auf Ausgang geschalteten C64-Ports auf low geht, um dem CIA den Zustand der entsprechenden Reihe mitzuteilen, bekomme ich praktisch Tastendrücke auf der echten Tastatur nicht mit, da das Scannen der Tastaturmatrix durch die (z.B. im Direktmodus) ständig auftretenden Pin-Change-Interrupts kontinuierlich verzögert wird.


    Außerdem funktioniert dein Ansatz doch auch nur, wenn du davon ausgehst, dass zum Scannen der Matrix Port A auf Ausgang und Port B auf Eingang steht, wie es die keyscan-Routine des Kernals zufällig macht, oder? Ich könnte doch auch auf dem C64 die Matrix anders herum scannen, Port B auf Ausgang und Port A auf Eingang setzen, und dann stünde Port B auf Ausgang gegen den AVR-Port, der ebenfalls (wie ich vermute) immer auf Ausgang steht. Oder hast du dafür eine Lösung? Du hast ja eigentlich keine Möglichkeit, zu erkennen, ob der CIA-Port auf Ausgang oder Eingang steht.


    Und vielleicht schalte ich Port A nur einmalig komplett auf low, wenn mich nur "any key" interessiert... dann bekommst du nur einen einzelnen Pin-Change-Interrupt, obwohl das C64-Program vielleicht öfters mal nach "any key" abfragt.


    Und schließlich brauche ich schon einen Pin-Change-Interrupt, um die serielle Schnittstelle zu realisieren...


    Mit einem Crosspoint Switch habe ich einfach eine Matrix aus 64 Schaltern, die ich beliebig ein und ausschalten kann, ohne mich darum kümmern zu müssen, ob jemand (CIA) diese Leitungen gerade abfragt und welche Reihe genau abgefragt wird. Damit wird das ganze viel einfacher. Aus Sicht der CIA ist das einfach auch nur eine passive Matrix, sodass alle Varianten der Abfrage genauso wie mit einer normalen Tastatur funktionieren, und ich keine Probleme mit der Geschwindigkeit bzw. keine Einschränkungen bei Interrupts habe.

  • Sollte gehen, das einzige SMD-Bauteil ist die Mini-USB-Buchse, sonst alles through-hole. Genauere Dokumentation gibts auf der Website bzw. direkt in den Design-Dateien. Löten solltest du allerdings schon können. Ich wollte auch nochmal schauen, ob ich das Design auf through-hole Mini-USB-Buchse umstellen kann.

    Das solltest Du tun. Die Through-Hole-Mini-USB-Buchse ist für'n Hobbybereich wesentlich einfacher zu löten als die SMD-Version. Gibt es auch bei Reichelt: "USB BWM", 0,49 EUR


    Zum Preis siehe Post #12, eine pessimistische Schätzung würde ich bei ca. 33€ Ansiedeln (ungefähr 13€ Teile, 10€ Crosspoint Switch (darin anteilig die Versandkosten bei Mouser für Privatpersonen, 20€), 10€ Platine). Je nach Anzahl der Besteller und Wahl des Platinenherstellers wird's dann günstiger.

    Mouser hat bei über 65 EUR Bestellwert keine Versandkosten (Fedex auswählen, da sonst Zoll evtl. zweimal berechnet wird...). Die Preise allerdings (7,76 EUR für den Crosspoint Switch ab 25 Stk.) sind ohne 19% Einfuhrumsatzsteuer. Die kommen noch drauf... Der passende Typ (DIL 28 ) ist übrigens der MT8808AE1.

  • So wie ich es sehe hast du keine echte Tastatur mehr, d.h. du musst nicht kontinuierlich eine echte Tastatur scannen und deren Zustand an den C64 weiterleiten. Wenn ich das Scannen der Matrix jedesmal unterbrechen muss, wenn eine Leitung des auf Ausgang geschalteten C64-Ports auf low geht, um dem CIA den Zustand der entsprechenden Reihe mitzuteilen, bekomme ich praktisch Tastendrücke auf der echten Tastatur nicht mit, da das Scannen der Tastaturmatrix durch die (z.B. im Direktmodus) ständig auftretenden Pin-Change-Interrupts kontinuierlich verzögert wird.

    Das kann man schon machen, aber man darf es eben nicht im Interrupt-Context tun. Es ist richtig dass diese Routinen dann vom Interrupt unterbrochen werden, das stört aber eigentlich in den meisten Fällen nicht, da dies nicht zeitkritisch ist (ob nun ein Tastenanschlag eine Millisekunde verzögert wird, wird niemand merken). Und der C64 liest ja auch nicht ständig die Tastatur aus, dass diese Interrupt ständig stattfinden.

    Außerdem funktioniert dein Ansatz doch auch nur, wenn du davon ausgehst, dass zum Scannen der Matrix Port A auf Ausgang und Port B auf Eingang steht, wie es die keyscan-Routine des Kernals zufällig macht, oder? Ich könnte doch auch auf dem C64 die Matrix anders herum scannen, Port B auf Ausgang und Port A auf Eingang setzen, und dann stünde Port B auf Ausgang gegen den AVR-Port, der ebenfalls (wie ich vermute) immer auf Ausgang steht. Oder hast du dafür eine Lösung? Du hast ja eigentlich keine Möglichkeit, zu erkennen, ob der CIA-Port auf Ausgang oder Eingang steht.

    Nein, ich verwende schon Pin-Change-Interrupts für beide Ports. Es ist also egal welcher der beiden Pins/Ports vom C64 auf Masse gezogen werden (kann ja auch vom Joystick aus passieren). Nur wenn die Firmware einen Pin selber auf Masse zieht, muss sie diesen Pin dann anders behandeln, damit sie diesen auch wieder rücksetzen kann. Das eigentliche Auswerten der Tasten findet auch nicht im Interrupt selber statt, sondern muss schon vorher über 2 Arrays berechnet werden (also für jeden Port ein Array, der Interrupt liest dann nur den Port aus nimmt sich dann dem Wert aus dem Array für den anderen Port), sonst wäre dies im Interrupt viel zu langsam.

    Und vielleicht schalte ich Port A nur einmalig komplett auf low, wenn mich nur "any key" interessiert... dann bekommst du nur einen einzelnen Pin-Change-Interrupt, obwohl das C64-Program vielleicht öfters mal nach "any key" abfragt.

    Das sollte aber trotzdem funktionieren. Denn die Ports werden auch bei einen neuen Input aktualisiert.

    Und schließlich brauche ich schon einen Pin-Change-Interrupt, um die serielle Schnittstelle zu realisieren...

    In meinen Ansatz verwende ich die UART ohne Interrupt, aber wie schon beschrieben wird der Ansatz nicht funktionieren wenn andere Interrupt-Quellen benötigt werden.

    Mit einem Crosspoint Switch habe ich einfach eine Matrix aus 64 Schaltern, die ich beliebig ein und ausschalten kann, ohne mich darum kümmern zu müssen, ob jemand (CIA) diese Leitungen gerade abfragt und welche Reihe genau abgefragt wird. Damit wird das ganze viel einfacher. Aus Sicht der CIA ist das einfach auch nur eine passive Matrix, sodass alle Varianten der Abfrage genauso wie mit einer normalen Tastatur funktionieren, und ich keine Probleme mit der Geschwindigkeit bzw. keine Einschränkungen bei Interrupts habe.

    von der Hardware her ist das sicherlich der saubere Ansatz, da hier der Atmega für mehr Spielraum hat. Falls man keine anderen zeitkritischen Sachen auf dem Atmega vor hat, ist es eben eine einfache Alternative. Bitte nicht falsch verstehen, es sollte keine Kritik auf Deine Arbeit sein, sonder nur ein kleiner Anreiz ;)



    Bei Interesse kann ich auch mal den Source-Code der Firmware veröffentlichen.

  • Freak: Danke für die Hinweise, vor allem bezüglich Mouser. Für die mini-USB-Buchse muss ich dann wohl noch einen footprint basteln, jedenfalls habe ich bisher keinen für Kicad gefunden.


    zschunky: Mag ja sein, dass es auch für den keyman so funktionieren könnte, für mich war der switch aber einfach der Weg des geringsten Widerstandes und dazu die technisch einfachere Lösung. Außerdem wollte ich soviele Steuerleitungen wie möglich frei haben. Für die Kontrolle des switches brauche ich 8 pins, für die Methode mit dem Atmega gleich 16, und dann wären nur noch 8 für allgemeine Zwecke übriggeblieben. Und ich brauchte für meine persönlichen Anforderungen eben schon 12 Leitungen, und habe jetzt noch 4 frei für zukünftige Erweiterungen. Und für die firmware habe ich noch andere Ideen, da wird der Atmega auch noch zeitkritische Dinge zu tun kriegen. Ehrlich gesagt bin ich ganz froh, es nicht mit den AVR-Ports hingekriegt zu haben... :)


    Die Methode, beide Ports auf Input zu setzen und wenn auf einem eine Leitung auf low geht davon auszugehen, dass der andere CIA-Port auf Eingang steht... kann man natürlich machen, funktioniert in der Praxis wahrscheinlich auch meistens. Die Anahme dabei ist allerdings, dass das auf dem C64 laufende Program vernünftig verhält und keine Fehler enthält. Theoretisch kann ich immer noch beide CIA Ports auf Ausgang schalten.


    Mit dem Crosspoint Switch bin ich da auf der sicheren Seite. Da hängt nämlich nichts dran, was potentiell gegen die CIA arbeiten könnte. AVR und CIA sind sauber voneinander getrennt.


    Auf deine firmware würde ich aber in jedem Fall einen Blick werfen wollen.

  • Bisher besteht Interesse an 18 Bausätzen. Sieht also schon ganz gut aus :)


    Ich habe bereits die folgenden Änderungen am Platinen-Layout vorgenommen:

    • Umstellung der USB-Buchse von SMD auf Through-Hole, weiterhin Mini-B
    • Möglichkeit, die Platine auch über USB mit Strom zu versorgen, um einen Standalone-Betrieb zu vereinfachen (siehe Ideen hier und hier)
    • Abstände von Kupferflächen zu Pads etwas vergrößert, um das Löten zu vereinfachen


    Ich sehe allerdings noch Verbesserungsmöglichkeiten, was die Möglichkeit der Befestigung angeht. Wie ihr auf dem im Eingangspost gezeigten Bild sehen könnt, hat die Platine bisher keine Bohrlöcher. Ich habe sie einfach von unten durch eingeklebte Holzstückchen gestützt und insgesamt mit einem Kabelbinder befestigt, der durch die Bohrlöcher der Plastikschienen am "Tastaturgehäuse" gesteckt ist. Das ist sicher nicht ideal.


    Wären Bohrlöcher vorhanden, könnte man auch selbstklebende Platinenhalter (z.B. diese hier) verwenden. Das würde allerdings auch die Einbauhöhe vergrößern (ich finde da nichts, was tiefer als 4,8mm wäre). Bisher passt die Platine von der Höhe her genau in die Tastatur, d.h. sie schließt auf der Tastaturplatine liegend bündig mit den Plastikschienen des "Tastaturghäuses" des C64 ab. Bei einem Brotkastengehäuse sollte die zusätzliche Höhe kein Problem sein. Beim Einbau in ein flaches Gehäuse wird es so oder so schon knapp.


    Um Bohrlöcher hinzufügen zu können, müsste ich die Platine nochmal vertikal etwas vergrößern, also nochmal ans Layout ran. Ob man nun selbstklebende Platinenhalter benutzt oder nicht, in jedem Fall denke ich, dass Bohrlöcher bei der Befestigung helfen könnten, oder?


    Mir ist halt noch keine zündende Idee zur Befestigung gekommen, aber vielleicht habt ihr ja eine Idee, wie man das lösen könnte.

  • Schönes Projekt!


    Ob man nun selbstklebende Platinenhalter benutzt oder nicht, in jedem Fall denke ich, dass Bohrlöcher bei der Befestigung helfen könnten, oder?

    Ja, denke ich auch, ein paar Löcher wären sehr hilfreich zur Befestigung. Und wer nicht will, muss sie ja nicht benutzen.


    Beim C64C wäre vielleicht auch ein Einbau im Gehäuseunterteil möglich, so wie ich das bei meinem AC/64 Netzteil gemacht habe. Da muss man aber genau messen, ob es reinpasst, viel Luft ist da ja nicht und es wird außerdem nach vorne immer flacher, da muss man die Bauteile etwas nach Bauhöhe sortiert anordnen. Zur Befestigung könnte man einen der übrigen "Platinenbefestigungsnippel" hernehmen oder evtl. auch die Lüftungsschlitze, entweder mit Schraube oder mit Kabelbindern.

  • Hier mal ein kurzes Update:


    Es sind bereits 21 Vorbestellungen eingegangen. Vielleicht werden es ja noch ein paar mehr...


    Hardware:


    Ich werde die Platine in jedem Fall noch weiter überarbeiten und den Stand dann auch hier zur Diskussion stellen, bevor ich die endgültige Revision festmache.


    lvr: Danke für den Hinweis auf die Möglichkeit des Einbaus im Gehäuseunterteils des C64C Gehäuses, diese werde ich auf jeden Fall in Betracht ziehen. Allerdings ist die Platine bereits 6cm hoch, für die Löcher müsste sie vertikal wohl mindestens auf 6,5cm vergrößert werden. Ich werde sehen.


    Generell versuche ich, die Platine so einbaufreundlich wie möglich zu machen, auch wenn ich kein Patentrezept habe. Ich gehe davon aus, dass u.U. ein wenig Kreativität vonnöten sein wird.


    Software:


    Auf github enthält der branch "remote-control" nun experimentell die Möglichkeit, die Funktionen des keyman64 auch vollständig vom PC aus über USB zu nutzen. Dabei wird das keyman64-Utility verwendet, um einzelne Befehle oder auch längere "Skripte" abzuspielen. Das sieht dann z.B. folgendermaßen aus:


    Code
    1. $ keyman64 type 'hello world!'
    2. $ keyman64 exec r
    3. $ keyman64 press f1
    4. $ keyman64 < befehle.txt
    5. $ rlwrap keyman64
    6. exec R
    7. sleep 3s
    8. type back from reset...
    9. ^D


    Das Konvertieren der Konfigurationsdatei in das binäre Format erfolgt dann über den expliziten Befehl "convert", z.B.:


    Code
    1. $ keyman64 convert example.conf example.bin


    Diese Änderungen werden in den nächsten offiziellen release einfließen, sobald ich es auch auf Windows erfolgreich getestet habe.

  • Würde gerne 2 Bausätze nehmen!


    Kann auch nur einer sein, falls es nicht anders geht "zwinker" :thumbsup:



    Beste Grüse


    Segi

  • Also ich würde auch nen Bausatz nehmen!

    lvr: Danke für den Hinweis auf die Möglichkeit des Einbaus im Gehäuseunterteils des C64C Gehäuses, diese werde ich auf jeden Fall in Betracht ziehen. Allerdings ist die Platine bereits 6cm hoch, für die Löcher müsste sie vertikal wohl mindestens auf 6,5cm vergrößert werden. Ich werde sehen.

    Und wenn Du die Platine in der Breite statt in der Höhe verlängerst, oder ist das ungünstig für's Layout?
    Aber wenn's nicht passt, muss man sie eben anders befestigen, auch kein Beinbruch.

  • Und wenn Du die Platine in der Breite statt in der Höhe verlängerst, oder ist das ungünstig für's Layout?


    Verbreitern ginge auch noch ein bischen... Allerdings habe ich mich erstmal auf 8x6 cm beschränkt, weil ich damit bei vielen PCB-Anbietern zwei Platinen auf einen Nutzen bekommen -- für's Prototyping ganz schön.


    Ich habe jetzt mal etwas geschraubt und die Bohrlöcher noch auf der bisherigen Größe untergebracht. Kleinster Abstand vom Rand sind 0.6mm -- Bei den Meisten Anbietern muss der Abstand >0.4mm sein. Ist natürlich etwas wenig, oder? Hier mal eine Ansicht:




    Ich bräuchte noch einen Tipp bezüglich des Bestückungsdrucks, da ich bisher nie Platinen mit Bestückungsdruck habe machen lassen: Was passiert, wenn der Bestückungsdruck über Pads verläuft? Wird das ausgespart oder wird dann über das Pad gedruckt? Letzteres wäre ja suboptimal. Der Bestückungsdruck wurde jetzt erstmal so gelegt, dass ich daraus einen schönen Bestückungsplan plotten kann.

  • Ich bräuchte noch einen Tipp bezüglich des Bestückungsdrucks, da ich bisher nie Platinen mit Bestückungsdruck habe machen lassen: Was passiert, wenn der Bestückungsdruck über Pads verläuft? Wird das ausgespart oder wird dann über das Pad gedruckt? Letzteres wäre ja suboptimal. Der Bestückungsdruck wurde jetzt erstmal so gelegt, dass ich daraus einen schönen Bestückungsplan plotten kann.


    Wenn der Platinenhersteller sein Handwerk versteht, wird das automatisch gemäß dem Lötstopplayer ausgeblendet.
    Ich hab es (sogar bei einem deutschen Hersteller!) aber auch schon anders erlebt. :abgelehnt
    Ich ordne den Bestückungsdruck immer neben den Pads an.

  • Ich bräuchte noch einen Tipp bezüglich des Bestückungsdrucks, da ich bisher nie Platinen mit Bestückungsdruck habe machen lassen: Was passiert, wenn der Bestückungsdruck über Pads verläuft? Wird das ausgespart oder wird dann über das Pad gedruckt? Letzteres wäre ja suboptimal. Der Bestückungsdruck wurde jetzt erstmal so gelegt, dass ich daraus einen schönen Bestückungsplan plotten kann.


    Bei KiCAD gibts dafür bei der Gerber-Erzeugung die Checkbox "Subtract soldermask from silkscreen", damit wird der Bestückungsdruck überall da weggelassen, wo auch kein Lötstopplack hinkommt.

  • Ich hab es (sogar bei einem deutschen Hersteller!) aber auch schon anders erlebt.

    Bei KiCAD gibts dafür bei der Gerber-Erzeugung die Checkbox "Subtract soldermask from silkscreen"


    Danke, das waren die Infos, die ich brauchte. Ich werde allerdings sehen, dass ich den Bestückungsdruck soweit möglich ausserhalb der Pads mache.