Question

I need to code in vhdl a keypad encoder. I was thinking to make it with 4 states. when at columnn1 scan row1,row2,row2,row4. 4 states like this should be enough according to me but an example I found from the internet makes it with 8 states:

key_scanner_sm : process (clk)
  begin  -- process key_scanner
    if clk'event and clk = '1' then

      if state_inc = '1' then

        -- reset scan_complete
        scan_complete <= '0';

        case key_state is

          when pulse_row_1 =>
            key_read  <= (others => '0');
            key_row   <= "0001";
            key_state <= read_row_1;

          when read_row_1 =>
            case key_col is
              when "0001" => key_read <= X"31";  -- 1
              when "0010" => key_read <= X"32";  -- 2
              when "0100" => key_read <= X"33";  -- 3
              when "1000" => key_read <= X"41";  -- A
              when others => null;
            end case;
            key_state <= pulse_row_2;

          when pulse_row_2 =>
            key_row   <= "0010";
            key_state <= read_row_2;

          when read_row_2 =>
            case key_col is
              when "0001" => key_read <= X"34";  -- 4
              when "0010" => key_read <= X"35";  -- 5
              when "0100" => key_read <= X"36";  -- 6
              when "1000" => key_read <= X"42";  -- B
              when others => null;
            end case;
            key_state <= pulse_row_3;

          when pulse_row_3 =>
            key_row   <= "0100";
            key_state <= read_row_3;

          when read_row_3 =>
            case key_col is
              when "0001" => key_read <= X"37";  -- 7
              when "0010" => key_read <= X"38";  -- 8
              when "0100" => key_read <= X"39";  -- 9
              when "1000" => key_read <= X"43";  -- C
              when others => null;
            end case;
            key_state <= pulse_row_4;

          when pulse_row_4 =>
            key_row   <= "1000";
            key_state <= read_row_4;

          when read_row_4 =>
            case key_col is
              when "0001" => key_read <= X"2A";  -- *
              when "0010" => key_read <= X"30";  -- 0
              when "0100" => key_read <= X"23";  -- #
              when "1000" => key_read <= X"44";  -- D
              when others => null;
            end case;
            key_state     <= pulse_row_1;
            scan_complete <= '1';

          when others => null;
        end case;

      end if;
    end if;
  end process key_scanner_sm;

Is there a good reason behind this, does anybody know?

Was it helpful?

Solution

The example you provide needs the extra states because it is implemented as a single case statement. The assignment to key_row needs an extra cycle to take effect before key_col can be read. Since this is a simple cyclic scan the pulse_row_n states could be eliminated by assigning the next value of key_row from the preceding read_row_n state

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top