Forum Discussion
Help with PS/2 Keyboard protocol
Hi, I've been trying to get keyboard input to work, but I'm having some trouble with it. I followed the procedure from a website (WHY do I have to have 5 posts to have links...), but it doesn't seem to be working the way I want it to. It seems to be returning the wrong codes for things. I've looked at scan code sets 1, 2, and 3 but they don't match up. For example, I press "a" and I get 0x39, but the possible scan codes are 0x1E, 0x1C. I don't see any break codes that match either. Heres my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ps2controller is
PORT ( C25 : in BIT;
BCLK : inout UNSIGNED(0 downto 0);
KDATA : inout UNSIGNED(0 downto 0);
CHAR : out UNSIGNED(7 downto 0)
);
end ps2controller;
architecture p2cbehav of ps2controller is
signal READ_DATA : UNSIGNED(0 downto 0) := "0";
signal SCAN : BIT := '1';
signal F_CLK : BIT;
signal FILTER : UNSIGNED(7 downto 0);
signal DATA_COUNT : UNSIGNED(3 downto 0);
signal CHAR_DATA : UNSIGNED(8 downto 0);
begin
--process to filter
process(C25)
begin
if C25'event and C25='1' then
FILTER(6 downto 0) <= FILTER(7 downto 1);
FILTER(7) <= BCLK(0);
if FILTER = x"FF" then F_CLK <= '1';
elsif FILTER = x"00" then F_CLK <= '0';
end if;
end if;
end process;
process(F_CLK)
begin
if F_CLK'event and F_CLK = '1' then --using the new filtered clock
if KDATA = "0" and READ_DATA = "0" then -- if the data stream is set low AND were not in a read state
-- then this is the start bit
READ_DATA <= "1"; -- set read flag on
elsif READ_DATA <= "1" then --if that read flag is on and less than 9, inc counter and take in the new bit
if DATA_COUNT < x"9" then
DATA_COUNT <= DATA_COUNT + 1;
CHAR_DATA(7 downto 0) <= CHAR_DATA(8 downto 1); -- shift in the new bit
CHAR_DATA(8) <= KDATA(0);
else --else, were done with the data input, so output first 8 bits (ignoring parity for now) and set read off
CHAR <= CHAR_DATA(7 downto 0);
READ_DATA <= "0";
DATA_COUNT <= x"0";
end if;
end if;
end if;
end process;
end p2cbehav;
It continuously gets input and outputs it to my display part. From what I can tell, the numbers I get for each key are constant, i.e. I always get 0x39 for "a". Can anybody help me find out whats going on?5 Replies
- Altera_Forum
Honored Contributor
I suggest not using a "filtered clock" as a real clock. use a system clock for everything, and treat everything else like clock enables.
- Altera_Forum
Honored Contributor
The website I found (http://proton.ucting.udg.mx/~mariocc/cap10.pdf, yay 5 posts) suggests that so I put it in on a "why not?" sort of thing. When I had this problem first, I took it out, thinking the same thing you are. But then it was MUCH WORSE. There was NO continuity between key presses, maybe because of what the website says - something about reflected signals.
- Altera_Forum
Honored Contributor
Since the PS/2 keyboard interface is actually a (ttl level ?) uart - you should be able to 'scope the raw data.
I also can't remember if the keyboard needs to be sent a 'reset' sequence (that might be the mouse) before it will behave properly. Might be worth testing the tx side by trying to change the keyboard leds. - Altera_Forum
Honored Contributor
Should you not be reading on the falling edge of the PS/2 clock, not the rising edge?
--- Quote Start --- I also can't remember if the keyboard needs to be sent a 'reset' sequence (that might be the mouse) before it will behave properly --- Quote End --- The keyboard should work without initialization; it is indeed the mouse that needs an init sequence. - Altera_Forum
Honored Contributor
Hey thanks, I inverted the keyboard clock and its working!