-- Functional Description -- -- The keypad works with drive and sense lines. -- The rows are the sense lines. -- The columns are the drive lines. -- Each of the four sense lines is pulled up with a 10kohm -- resister. -- The drive lines drive all '0' and once a sense of '0' is -- seen then we know that a key has been pressed. -- Once the key has been pressed then a '1' bit is shifted through all -- of the drive lines. -- Then once the sense lines goes high again then we know which key -- was pressed. -- The key is then registed using the keydetected signal. -- Then the kaypad logic waits for the key to be released and for a signal -- to continue normal operation. -- -- -------------------------------------------------------- ------------------------------------------------------------------------ -- keypad ------------------------------------------------------------------------ LIBRARY IEEE; USE ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY keypad IS PORT( clk : IN STD_LOGIC; reset : IN STD_LOGIC; --KeyDetected : OUT STD_LOGIC; Key : OUT STD_LOGIC_VECTOR(3 downto 0); -- External Signals row : IN STD_LOGIC_VECTOR(3 downto 0); col : OUT STD_LOGIC_VECTOR(3 downto 0) ); END keypad; ARCHITECTURE behavioural OF keypad IS TYPE STATE_TYPE IS (Drive1, Drive2, Drive4, Drive8, Foundkey ); SIGNAL state : STATE_TYPE; -- SIGNAL stateDrive : STATE_TYPE; SIGNAL Sense : STD_LOGIC; --SIGNAL Key : STD_LOGIC_VECTOR(3 downto 0); SIGNAL rowint : STD_LOGIC_VECTOR(3 downto 0); SIGNAL IntCack : STD_LOGIC; BEGIN -- Latch the inputs Internalrow: PROCESS BEGIN IF(falling_edge(clk)) THEN rowint <= row; END IF; END PROCESS Internalrow; -- Create the sense signal. SenseDetect: PROCESS BEGIN Sense <= (rowint(0) AND rowint(1)) AND (rowint(2) AND rowint(3)); END PROCESS SenseDetect; -- This is the state that handles all of the state machine. StateLogic : PROCESS (reset, clk) BEGIN IF reset = '0' THEN --state <= Nokey; key <= "0000"; --keyDetected <= '0'; -- stateDrive <= Drive0; ELSIF rising_edge(clk) THEN CASE state IS WHEN Drive1 => IF Sense = '0' THEN IF rowint(0) = '0' THEN Key <= "0000"; -- Key 0 ELSIF rowint(1) = '0' THEN Key <= "0100"; --Key 4 ELSIF rowint(2) = '0' THEN Key <= "1000"; -- Key 8 ELSIF rowint(3) = '0' THEN Key <= "1100"; -- Key 12 end if; state <= Foundkey; ELSE state <= Drive2; END IF; WHEN Drive2 => IF Sense = '0' THEN if rowint(0) = '0' THEN Key <= "0001"; -- 1 ELSIF rowint(1) = '0' THEN Key <= "0101"; -- 5 ELSIF rowint(2) = '0' THEN Key <= "1001"; -- 9 ELSIF rowint(3) = '0' THEN Key <= "1101"; -- 13 end if; state <= Foundkey; ELSE state <= Drive4; END IF; WHEN Drive4 => IF Sense = '0' THEN if rowint(0) = '0' THEN Key <= "0010"; -- 2 ELSIF rowint(1) = '0' THEN Key <= "0110"; --6 ELSIF rowint(2) = '0' THEN Key <= "1010"; -- 10 ELSIF rowint(3) = '0' THEN Key <= "1110"; -- 14 END IF; state <= Foundkey; ELSE state <= Drive8; END IF; WHEN Drive8 => IF Sense = '0' THEN IF rowint(0) = '0' THEN Key <= "0011"; -- 3 ELSIF rowint(1) = '0' THEN Key <= "0111"; -- 7 ELSIF rowint(2) = '0' THEN Key <= "1011"; -- 11 ELSIF rowint(3) = '0' THEN Key <= "1111"; -- 15 END IF; state <= Foundkey; ELSE --state <= keyrelease; state <= Drive1; END IF; when Foundkey => --state <= debounce_out; if sense = '1' then --state <= debounce_out; --state <= keyrelease; state <= Drive1; else --state <= keyrelease; --state <= Nokey; state <= Foundkey; end if; END CASE; -- Button numbers for the keypad -- 0 1 2 3 -- 4 5 6 7 -- 8 9 10 11 -- 12 13 14 15 -- This case determines what key has been pressed -- based on the drive and the row. END IF; END PROCESS StateLogic; -------------------------------------------------------- -- Send the key to the output when the Register key state is found --Outputs: PROCESS(state) --BEGIN --IF(state = Foundkey) THEN --KeyData <= Key; --KeyDetected <= '1'; --ELSE --KeyData <= "0000"; --keyDetected <= '0'; --END IF; --END PROCESS Outputs; WITH state SELECT col <= "0111" WHEN Drive1, --7 "1011" WHEN Drive2, --11 "1101" WHEN Drive4, --13 "1110" WHEN Drive8, --14 --"0000" WHEN Drive0, --15 "0000" when others; END behavioural;