Skocz do zawartości

PS2_KEYBOARD


kroszkanorber

Pomocna odpowiedź

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity KEY_S1 is
    Port ( Clk : in  STD_LOGIC;
		   Reset : in  STD_LOGIC;
           PS2_D : inout  STD_LOGIC;
           PS2_C : inout  STD_LOGIC;
           Kbwe : out  STD_LOGIC;
           KbD : out  STD_LOGIC_VECTOR (7 downto 0)
			  );
end KEY_S1;

architecture Behavioral of KEY_S1 is

	signal D : std_logic_vector (9 downto 0) ;
	signal Din : std_logic_vector (7 downto 0) ;
	signal Cnt : std_logic_vector (7 downto 0) ;
	signal Cnt1 : std_logic_vector (13 downto 0) ;
	signal Clk1 : std_logic;
	signal KbWE : std_logic;
	
	signal PS2_Cin : std_logic;
	signal PS2_Cout : std_logic;
	signal PS2_Dout : std_logic;

	signal Brake : std_logic;
	signal Caps : std_logic;
	signal Num : std_logic;
	signal Scroll : std_logic;
	signal Ack : std_logic;
	signal ParityGen : std_logic_vector (6 downto 0);
	signal Parity : std_logic;
	
   type PS2State_type is (idle, datain, sel, we, we1, rts, rts1, rts2, dataout); 
   signal PS2State : PS2State_type;


begin
		
		process(Clk, PS2_C)								--oczekiwanie na stabilny sygnał zegarowy z klawiatury
		begin
			if PS2_C = '1' then
				Cnt <= (others => '0');
				PS2_Cin <= '1';
			else
				if Clk'event and Clk = '0' then
					if PS2_C = '0' then
						if Cnt = "11111111" then
							PS2_Cin <= '0';
						else
							Cnt <= Cnt + 1;
						end if;
					end if;
				end if;
			end if;
		end process;
		
		with PS2State select
			Clk1 <= Clk when rts,
					  Clk when rts1,
					  Clk when sel,
					  Clk when we,
					  Clk when we1,
					  PS2_Cin when others;
		
		with PS2State select
	  PS2_Dout <= '0' when rts1,
					  '0' when rts2,
					  D(0) when dataout,
					  '1' when others;
		
		with PS2State select
	  PS2_Cout <= '0' when rts,
					  '0' when rts1,
					  '1' when others;
		
		process(Clk1, Reset, PS2State, PS2_D)		--wysłanie, odbieranie danych z klawiatury w maszynie stanów
		begin
			if Reset = '0' then
				D <= "1000000000";
				Din <= "00000000";
				KbD <= "00000000";
				KbWE <= '0';
				Cnt1 <= (others => '0');
				PS2State <= idle;
			else
				if Clk1'event and Clk1 = '0' then
					case PS2State is
					
					when idle =>
								D <= "1000000000";
								PS2State <= datain;
					
					when datain =>
							if D(0) = '1' then
								D <= "1000000000";
								Din <= D(8 downto 1);
								PS2State <= sel;
							else
								D <= PS2_D & D(9 downto 1);
							end if;
					
					when sel =>
							if Din = X"F0" then
								Brake <= '1';
								PS2State <= idle;
						elsif ((Din = X"58") and (Brake <= '0') and (Ack = '0')) then
								Din <= X"ED";
								Caps <= not Caps;
								PS2State <= rts;
						elsif ((Din = X"77") and (Brake <= '0') and (Ack = '0')) then
								Din <= X"ED";
								Num <= not Num;
								PS2State <= rts;
						elsif ((Din = X"7E") and (Brake <= '0') and (Ack = '0')) then
								Din <= X"ED";
								Scroll <= not Scroll;
								PS2State <= rts;
						elsif ((Din = X"FA") and (Brake = '0') and (Ack = '0')) then
								Din <= "00000" & Caps & Num & Scroll;
								Ack <= '1';
								PS2State <= rts;
						elsif Brake = '1' then
								Brake <= '0';
								PS2State <= idle;
						elsif Ack = '1' then
								Ack <= '0';
								PS2State <= idle;
							else
								KbD <= Din;
								PS2State <= we;
							end if;
					
					when we =>
								KbWE <= '1';
								PS2State <= we1;
					
					when we1 =>
								KbWE <= '0';
								PS2State <= idle;
					
					when rts =>	 --reqest to send
							if Cnt1 = "11111100000000" then
								Cnt1 <= (others => '0');
								PS2State <= rts1;
							else
								Cnt1 <= Cnt1 + 1;
							end if;
					
					when rts1 =>	 --reqest to send
							if Cnt1 = "00000100000000" then
								Cnt1 <= (others => '0');
								PS2State <= rts2;
							else
								Cnt1 <= Cnt1 + 1;
							end if;
							
					when rts2 =>	 --reqest to send
								D <= '1' & Parity & Din;
								PS2State <= dataout;
							
					when dataout => --przesył danych do klawiatury
							if D = "0000000001" then
								PS2State <= idle;
							else
								D <= '0' & D(9 downto 1);
							end if;
							
					end case;
				end if;
			end if;
		end process;
		
		ParityGen(0) <= Din(0) xor Din(1);			--generator parztstości
		ParityGen(1) <= Din(2) xor Din(3);
		ParityGen(2) <= Din(4) xor Din(5);
		ParityGen(3) <= Din(6) xor Din(7);
		ParityGen(4) <= ParityGen(0) xor ParityGen(1);
		ParityGen(5) <= ParityGen(2) xor ParityGen(3);
		ParityGen(6) <= ParityGen(4) xor ParityGen(5);
		Parity <= not ParityGen(6);
		
		PS2_C <= 'Z' when PS2_Cout = '1' else '0';	--zmiana portów komunikacyjnych klawiatury z wejściowych na wyjściowe
		PS2_D <= 'Z' when PS2_Dout = '1' else '0';

end Behavioral;

Witam.

Załączam kod programu obsługującego klawiaturę ps2. Kod pisany dla układu z generatorem 100MHz.

Sygnał ack wysyłany z klawiatury jest nieodczytywany, sygnał brake wysyłany z klawiatury jest ignorowany.

Klawiatura po włączeniu wysyła kod X"AA" i ustawia się w tryb scan-code-set 2. (ustawienia fabryczne)

Można wiele ustawień zmienić lecz trzeba pamiętać że zmiana scan-code-set na 1 lub 3 zmienia także kody podpisane pod przyciski.

Naciśnięcie przycisków ( caps, num, scroll ) jest odczytywane i zostaje wysłany kod który zapala lub gasi naprzemiennie odpowiednie kontrolki na klawiaturze.

Dane z pozostałych klawiszy są wysyłane do wyjścia KbD i potwierdzane sygnałem KbWE (stan wysoki) trwającym jeden cykl zegara.

Do wyjścia podawany jest kod make, a brake jest ignorowany. Niektóre przyciski mają podwójny kod zaczynający się X"E0" a przycisk pause zaczyna się jako jedyny X"E1", X"E0" ...(scan-code-set 2).

Może się komuś przyda...

Pozdrawiam

 

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@FlyingDutch

Hej.

Czy próbowałeś uruchomić mysz ps2 na układzie FPGA?

Po podaniu kodu do zezwolenia na przesył danych x"f4" brak okcetptacji myszy. Wysyła kod x"fc" zamiast x"fa". Tylko kod reset x"ff" jest akceptowany i mysz wysyła w trzecim kodzie poprawny identyfikator. Reszta kodów nie działa. Nie mam pojęcia jak ten temat podjąć...

W wolnej chwili wstawię kod programu i otworzę nowy temat.

  • Lubię! 1
Link do komentarza
Share on other sites

@FlyingDutch Hej.

Udało mi się uruchomić wysyłanie pakietów danych z myszy i odczytuje je na wyświetlaczu LED 7 segmentowym. W internecie różne rzeczy piszą i trzeba samemu próbować. Jak uda mi się poprawnie rozkodować dane to wstawię post. Kod który wstawiłem na początku działa na klawiaturze lecz mysz ma większe wymagania co do przebiegu sygnałów CLK i dat . 

Pozdrawiam

  • Lubię! 1
Link do komentarza
Share on other sites

Witam.

Przedstawiony kod ps2_keyboard ma pewne wady.

1 kod nie posiada weryfikacji danych przychodzących z klawiatury pod względem błędów transmisji. ( Nigdy nie wystąpiły ze strony urządzenia, ale mogłoby się zdarzyć...)

2 gdy użyć chcemy kontrolera zewnętrznego który ma za zadanie inicjować urządzenie ps2 musimy przepisać kod co jest trudniejsze jak napisać go od początku. Rozwiązaniem jest kod który podałem w ps2_mouse część 2. Kod ten składa się z trzech czesci, a część tx służy do wysłania polecenia do urządzenia ps2.

Kod ps2 który opisałem w 2 części jest moim zdaniem uniwersalny pod względem obsługi urządzeń. Działa równie dobrze z myszą i klawiaturą ps2.

Pozdrawiam 

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.