I'm trying to receive data from a keyboard via the PS/2 port on the Papilio One Arcade Megawing. Eventually I'll want to implement this from scratch, but I thought I'd get some public code working first as a form of smoke-test.
The three sources I played with were
- http://soclab.cn.nctu.edu.tw/course/FPGA102/ps2_ctrl.pdf
- http://hamsterworks.co.nz/mediawiki/index.php/Papilio_Plus/PS2_Keyboard
- https://github.com/thelonious/ps2_io/tree/master/keyboard_scan_code
I've modified each by changing the UCF file to
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;
and I'm driving LED1
straight from PS2_Clk
, LED2
from PS2_Data
and LED3
from a register that should go from low to high (and stay high) when the first complete scancode is read.
The problem is, with all three implementations, what I get instead is
LED1
andLED2
are continuously onLED3
never turns on
The keyboard I'm using is a Microsoft Natural Keyboard 4000 via a USB-to-PS/2 dongle. The function key lock LED on the keyboard lights up when I connect it to the Papilio so at least I know it's getting juice.
Full Xilinx ISE project dumps are available at http://forum.gadgetfactory.net/index.php?/topic/1917-ps2-ports-on-arcade-megawing/
@Leor mentioned below that the PS/2 port uses a clock frequency of 10 KHz. Does n't that mean that I should see a blinking LED (with about 1.6 second frequency) with the following code:
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;
Because if I try this, the LED is still continuously on.