Verwendung des PS/2-Ports des Papilio One FPGA von VHDL

Ich versuche, Daten von einer Tastatur über den PS/2-Anschluss des Papilio One Arcade Megawing zu empfangen. Irgendwann möchte ich das von Grund auf neu implementieren, aber ich dachte, ich würde zuerst einen öffentlichen Code als eine Art Rauchtest zum Laufen bringen.

Die drei Quellen, mit denen ich gespielt habe, waren

Ich habe jedes modifiziert, indem ich die UCF-Datei in geändert habe

NET "Clk"      LOC="P89"  | IOSTANDARD = LVCMOS25 | PERIOD=31.25ns;
NET "Reset"    LOC="P67"  | IOSTANDARD=LVTTL | PULLDOWN;
NET "PS2_Clk"  LOC="P91"  | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP;
NET "PS2_Data" LOC="P92"  | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP;
NET "LED1"     LOC="P57"  | IOSTANDARD=LVTTL;
NET "LED2"     LOC="P53"  | IOSTANDARD=LVTTL;
NET "LED3"     LOC="P40"  | IOSTANDARD=LVTTL;

und ich fahre LED1direkt von PS2_Clk, LED2von PS2_Dataund LED3von einem Register, das von niedrig nach hoch gehen sollte (und hoch bleiben sollte), wenn der erste vollständige Scancode gelesen wird.

Das Problem ist bei allen drei Implementierungen, was ich stattdessen bekomme

  • LED1und LED2sind durchgehend an
  • LED3schaltet sich nie ein

Die Tastatur, die ich verwende, ist eine Microsoft Natural Keyboard 4000 über einen USB-zu-PS/2-Dongle. Die Funktionstastensperr-LED auf der Tastatur leuchtet auf, wenn ich sie mit dem Papilio verbinde, damit ich zumindest weiß, dass sie Saft bekommt.

Vollständige Xilinx ISE-Projekt-Dumps sind verfügbar unter http://forum.gadgetfactory.net/index.php?/topic/1917-ps2-ports-on-arcade-megawing/

@Leor erwähnte unten, dass der PS/2-Anschluss eine Taktfrequenz von 10 KHz verwendet. Bedeutet das nicht, dass ich eine blinkende LED (mit einer Frequenz von etwa 1,6 Sekunden) mit dem folgenden Code sehen sollte:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity main is
    Port ( CLK : in  STD_LOGIC;
           PS2_CLK : in  STD_LOGIC;
           LED : out  STD_LOGIC);
end main;

architecture Behavioral of main is
signal counter: unsigned(13 downto 0) := (others => '0');
signal PS2_CLK_PREV : std_logic := '1';
signal LED_clamped : std_logic := '0';
begin
LED <= LED_clamped;
process(CLK) is
begin
  if rising_edge(CLK) then
    if not (PS2_CLK = PS2_CLK_PREV) then
      counter <= counter + 1;
    end if;

    if counter = 0 then
      LED_clamped <= not LED_clamped;
    end if;

    PS2_CLK_PREV <= PS2_CLK;
  end if;
end process;

end Behavioral;

Denn wenn ich das versuche, leuchtet die LED immer noch dauerhaft.

Ich habe meinen Code so aktualisiert, dass die LED von einem Latch angesteuert wird, das jedes Mal umgedreht wird, wenn der Zähler 0 erreicht. Es ist immer noch für mich eingeschaltet.
Die Seite unter papilio.cc/index.php?n=Papilio.ArcadeMegaWing listet die PS/2-Clock-Pins als Ausgangspins auf , was mich noch mehr verwirrt.

Antworten (2)

PS/2 verwendet einen 10-kHz-Takt, sodass das Anschließen einer LED an die Takt- oder Datenleitungen nur dazu führt, dass die LED immer mit einer Helligkeit leuchtet, die dem Tastverhältnis des Signals entspricht.

Haben Sie versucht, den Beispielcode mit dem ISE-Simulator zu simulieren? Das würde Ihnen zumindest sagen, dass die Takt- und Datenausgänge etwas Vernünftiges tun.

Update Wenn ich den zweiten Code richtig verstehe:

Das CLK-Signal ist ein 32-MHz-Takt. Das PS2_CLK-Signal ist ein 10-kHz-Signal (PS2 erlaubt anscheinend zwischen 10 und 16 kHz - wissen Sie genau, was dieses Signal ist?), das ... irgendwo erzeugt wird?

Das zweite Stück Code, das Sie gepostet haben, geht zu:

  1. Starten Sie den Zähler bei 0, PS2_CLK_PREV bei 1
  2. Bei jeder ansteigenden CLK-Flanke (dh bei 32 MHz) wird der Prozess ausgeführt

Der von Ihnen definierte Prozess erhöht den Zähler immer dann, wenn sich PS2_CLK geändert hat.

Somit wird der Zähler einmal für jeden positiven und negativen Taktübergang auf PS2_CLK (dh bei 20 KHz) inkrementiert.

Der Zähler wird inkrementiert, bis er überläuft und auf 0 zurückgeht. Da es 14 Bit sind, bedeutet dies, dass 16384 Inkremente benötigt werden, was bei einer Inkrementrate von 20 KHz (zweimal pro Taktzyklus) 0,819 Sekunden beträgt.

Ihre LED ist nur 1, wenn der Zähler 0 ist, was alle 0,819 Sekunden für 5 uS geschieht. Das ist nicht lange genug, um zu bemerken, dass es eingeschaltet ist, und daher ist die LED im Wesentlichen 0.

Wenn die LED ständig eingeschaltet zu sein scheint, bedeutet dies, dass der Zähler konstant auf 0 steht. Das deutet darauf hin, dass PS2_CLK immer gleich PS2_CLK_PREV ist, was darauf hindeutet, dass Ihr PS2_CLK möglicherweise nichts tut. Ich würde vorschlagen, sich anzusehen, was dieses Taktsignal antreibt (ist es ein DCM, das Sie instanziiert haben? Ein einfacher Taktteiler?)

Die Erwähnung einer 10-kHz-Uhr brachte mich auf eine Idee; siehe meine bearbeitete Frage. Ich sehe immer noch kein Blinken auf der LED.
Ist Ihr 10-kHz-PS2-Takt derselbe wie Ihr logischer CLK? Die meiste FPGA-Logik läuft mit Taktraten im Bereich von 10 bis 100 MHz, was dazu führen würde, dass Ihr Timer in weniger als einer Millisekunde überläuft. Ich wäre überrascht, wenn Ihre Logik mit 10 MHz getaktet ist (es sei denn, Sie binden die Logik speziell an diesen Takt), da vor und nach der Datenübertragung viele andere Dinge passieren müssen.
Abgesehen davon sollte die LED ausgeschaltet erscheinen, wenn der obige Code korrekt funktioniert. Ich denke, es gibt irgendwo ein anderes Problem. Haben Sie erfolgreich Funktionscode geschrieben, synthetisiert und geladen, um etwas Einfaches zu tun – vielleicht eine LED blinken zu lassen?
Aber ich verringere den Zähler nur, wenn sich das PS2_CLK-Signal ändert. Ich taste das 10-kHz-Signal mit 32 MHz ab, dachte ich zumindest.
zum Rauchtesten des Boards an sich: Sachen funktionieren im Allgemeinen auf dem gleichen Board, zB habe ich gerade eine kleine Konfiguration geschrieben und darauf geladen, die die vier Tasten über einen Soft-Debouncer verwendet, um die vier LEDs umzuschalten. Ich würde sagen, das beweist, dass die Uhr und die LEDs funktionieren. Ich habe auch zuvor erfolgreich ein VGA-Signal auf derselben Karte generiert.
Ich habe meiner Antwort einige Kommentare zu Ihrem zweiten Code hinzugefügt.
Ich dachte, die Tastatur würde die PS2-Uhr erzeugen. Ist dies nicht der Fall?
Hmm, ich verstehe jetzt, warum die LED nur für die kleine Zeit 1 sein würde, wenn der Zähler genau 0 ist ... was ich wirklich tun wollte, war ein Ein-Bit-Register zu haben, das ich jedes Mal umdrehe, wenn der Zähler 0 ist. Ich werde mein reparieren programmieren und testen.
Sie haben Recht - das Gerät erzeugt das Taktsignal. Ich kenne mich mit PS/2 nicht aus.
Die Beschreibung des Protokolls hier: computer-engineering.org/ps2protocol legt nahe, dass die Uhr hoch ist, wenn dank eines Pullup-Widerstands keine Kommunikation stattfindet. Haben Sie Pullups auf Ihren Datenleitungen? Es gibt so viele Variablen, dass es schwierig ist, auf ein einzelnes Problem hinzuweisen. Ich würde vorschlagen, einen billigen Logikanalysator (billige Saleae-Klone kosten etwa 10 US-Dollar) oder ein Oszilloskop zu kaufen, um als Plausibilitätsprüfung zu fungieren.

Es stellte sich heraus, dass das Problem die Kombination aus der Microsoft Natural 4000-Tastatur war, die ich zum Testen verwendete, und dem USB-zu-PS/2-Dongle. Nachdem ich eine richtige PS/2-Tastatur bekommen habe, funktionieren die Testkonfigurationen wie erwartet.

Ich bin mir nicht sicher, ob ich diese Antwort von mir akzeptieren oder meine ursprüngliche Frage löschen soll ... Ich denke, ich werde diese Antwort akzeptieren, da jemand anderes mit einer neueren Tastatur in die gleiche Situation geraten könnte.