Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Debugging key pressed on DE2 board

See second post for the solution

=================

I am trying to hook up the VGA and Keyboard together. So when user presses 'W', it means move the object on the screen up. Letter 'S' is downward.

I am having problem getting my code working properly. So I am debugging W and S now (up, and down, respectively).

block diagram

keyboard scan code layout

See attachments

As you can see, I linked the outputs Up and Down (W and S, respectively) to the LED switches Red[0] and Red[1].

I have three scenarios in total (codes are provided at the end)

scenario i

Send make code

if W is detected, Red[0] is on

if S is detected, Red[1] is on

if "F0" is detected, go to Received_Break state

In the received_break state, we will receive the 2nd byte of the break code, and hence, turn off the respective Red[x] LED.

scenario ii

Send make code

if W is detected, Red [0] is on

if "F0" is detected, go to Received_Break state

In the receive break state, turn off Red[0]

scenario iii

Do the same as II for the letter key "S"

result:

scenario i failed. Only "S" is able to turn on the LED light. Pressing W has no effect.

Scenario II passed.

Scenario III passed.

This shows me that only one key was able to exist in my state machine. More than one is not possible. So something is not correct about my scenario I state machine.

Key Detector for W and S

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity move_key_detector is
    PORT(
        clk : IN STD_LOGIC;
        done : IN STD_LOGIC;
        hex : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        up, down : out std_logic
    );
END move_key_detector;
architecture arch of move_key_detector is
    type statetype is (IDLE, RECEIVED_BREAK);
    signal current_state, next_state : statetype;
    signal intUp    : std_logic := '0';
    signal intDown : std_logic := '0';
    
begin
up <= intUp;
down <= intDown;
process (Clk) begin
    if(rising_edge(Clk)) then
        current_state <= next_state;
    end if;
end process;
-- Use this for all three cases.. just comment out one of them for II and III
process(done) begin
    if (done = '1') then
        if (current_state = IDLE) then
            if (hex = "00011100") then intUp <= '1';
            --elsif(hex = "00011011") then intDown <= '1';
            --check to see if a break code is sent
            elsif (hex = "11110000") then next_state <= RECEIVED_BREAK; 
            end if; 
                
        elsif (current_state = RECEIVED_BREAK) then
            if (hex = "00011100") then intUp <= '0'; 
            --elsif(hex="00011011") then intDown <= '0';
            end if;             
            --we always go back to idle after a key is released
            next_state <= IDLE; 
        end if;
    end if;
Position Controller (calculating new position of the object after Up / Down)


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Pos_Controler is
port
(
    Up, Down, Reset: in std_logic;
    Init_X, Init_Y: out std_logic_vector(9 downto 0)
);
end Pos_Controler;
architecture arch of Pos_Controler is
signal x, y: unsigned(9 downto 0):= "0011001000";   -- 200
begin
Init_X <= std_logic_vector(x);
Init_Y <= std_logic_vector(Y);
Process(Reset, Up, Down)
begin
    if(Reset = '1') then        -- relocate object at (96,96)
        x <= "0001100000";        
        y <= "0001100000";
    elsif(Up = '1') then
        y <= y+4;
    elsif(Down = '1') then
        y <= y-4;
    end if;
end process;
end arch;
What's the problem here?

Thank you very much :))

========================================

edit (more testings on various of keys)

What is interesting is when we have WW, TT, SS (all the way till the bottom)

Scan code: W = 00011101, S = 00011011, T = 00101100

--Original Order
--if(key)  intUp <= '1',  elsif(key)  intDown <='1'
-- Reverse is the opposite
W = Up,  S = Down,  DOWN LED is on  
S = Up,  W = Down,  DOWN LED is on  
-- Reverse the order of if-statement
W = Down,  S = Up,  DOWN LED is on  
S = Down,  W = Up,  DOWN LED is on  
-- Use T and S combination  (original order)
T = Up,  S = Down,  DOWN LED is on  
S = Up,  T = Down,  DOWN LED is on  
-- Use W and T combination
W = Up,  T = Down,  DOWN LED is on  
T = Up,  W = Down,  DOWN LED is on  
-- Let's reverse the order
W = Down,  T = Up,  DOWN LED is on  
T = Down,  W = Up,  DOWN LED is on  
-- Lastly, how about  WW, TT, SS in original order
W = Up,  W = Down,  UP LED is on  
S  = Up,  S = Down,  UP LED is on  
T  = Up,  T = Down,  UP LED is on  
-- In reverse order
W = Down,  W = Up,  DOWN LED is on  
S = Down,  S = Up,  DOWN LED is on  
T = Down,  T = Up,  DOWN LED is on  

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi guys.

    I already solved my problem. We figured that even a single press (say a second duration) could mean many many make codes are being sent out from the keyboard.

    Our solution is to detect the key press at the end of the break stage (using the second byte of the break code: break code is F0 follows by the make code of the key being released).

    This is our solution:

    
     process(done) begin
            if(done = '1') then
                  if(current_state = IDLE) then
                        intLeft                 <= '0';
                        intRight                <= '0';
                        intDown                 <= '0';
                        intUp                   <= '0';
                        int_move_en             <= '0';
                        if (hex = "11110000") then next_state <= RECEIVED_BREAK; end if;  -- if F0 is received
                        
                  elsif(current_state = RECEIVED_BREAK) then
                        if(hex = "00011101") then intUp <= '1'; int_move_en <= '1'; end if;
                        if(hex = "00011011") then intDown <= '1'; int_move_en <= '1'; end if;
                        if(hex = "00100011") then intRight <= '1'; int_move_en <= '1'; end if;
                        if(hex = "00011100") then intLeft <= '1';  int_move_en <= '1'; end if;
                        next_state <= IDLE;
                  end if;
            end if;
      end process;