Usando el puerto PS / 2 del Papilio One FPGA de VHDL

2

Estoy intentando recibir datos de un teclado a través del puerto PS / 2 en Papilio One Arcade Megawing. Eventualmente, querré implementar esto desde cero, pero pensé que primero obtendría un código público que funcionara como una forma de prueba de humo.

Las tres fuentes con las que jugué eran

He modificado cada uno cambiando el archivo UCF a

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;

y estoy manejando LED1 directamente desde PS2_Clk , LED2 desde PS2_Data y LED3 desde un registro que debe ir de bajo a alto (y mantenerse alto) cuando se lee el primer scancode completo .

El problema es que, con las tres implementaciones, lo que obtengo es

  • LED1 y LED2 están continuamente en
  • LED3 nunca se enciende

El teclado que estoy usando es un Microsoft Natural Keyboard 4000 a través de un dongle USB a PS / 2. El LED de bloqueo de teclas de función en el teclado se ilumina cuando lo conecto al Papilio, por lo que al menos sé que se está agotando.

Los volcados completos del proyecto ISE de Xilinx están disponibles en enlace

@Leor menciona a continuación que el puerto PS / 2 utiliza una frecuencia de reloj de 10 KHz. ¿No significa eso que debería ver un LED parpadeante (con una frecuencia de aproximadamente 1,6 segundos) con el siguiente código:

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;

Porque si lo intento, el LED sigue encendido.

    
pregunta Cactus

2 respuestas

0

Resultó que el problema era la combinación del teclado Microsoft Natural 4000 que estaba usando para las pruebas y el dispositivo USB a PS / 2. Después de obtener un teclado PS / 2 adecuado, las configuraciones de prueba funcionan como se esperaba.

    
respondido por el Cactus
1

PS / 2 utiliza un reloj de 10 KHz, por lo que conectar un LED al reloj o líneas de datos solo hará que el LED aparezca siempre con un brillo correspondiente al ciclo de trabajo de la señal.

¿Ha intentado simular el código de ejemplo con el simulador ISE? Al menos eso le diría que el reloj y las salidas de datos están haciendo algo sensato.

Actualizar Si estoy entendiendo el segundo código correctamente:

La señal CLK es un reloj de 32 MHz La señal PS2_CLK es de 10 KHz (PS2 permite entre 10 y 16 KHz aparentemente, ¿sabe exactamente qué es esta señal?) Que se genera ... en algún lugar?

La segunda parte del código que publicaste va a:

  1. Iniciar el contador en 0, PS2_CLK_PREV en 1
  2. En cada flanco ascendente de CLK (es decir, a 32 MHz), el proceso se ejecutará

El proceso que ha definido incrementará el contador cada vez que PS2_CLK haya cambiado.

Por lo tanto, el contador se incrementará una vez por cada transición de reloj positiva y negativa en PS2_CLK (es decir, a 20 KHz).

El contador aumentará hasta que se desborde y vuelva a 0. Como es de 14 bits, eso significa que tomará 16384 incrementos, que a una velocidad de incremento de 20 KHz (dos veces por ciclo de reloj) es de 0.819 segundos.

Su LED es solo 1 cuando el contador es 0, lo que ocurrirá durante 5 uS cada 0,819 segundos. No es lo suficientemente largo para que note que está encendido, por lo que el LED es esencialmente 0.

Si el LED parece estar encendido constantemente, significa que el contador está constantemente en 0. Eso sugiere que PS2_CLK siempre es igual a PS2_CLK_PREV, lo que sugiere que quizás su PS2_CLK no esté haciendo nada. Sugiero que mire lo que está impulsando esa señal de reloj (¿es un DCM que ha creado una instancia? ¿Un divisor de reloj simple?)

    
respondido por el LeoR

Lea otras preguntas en las etiquetas