User:1sfoerster/enes245/spring/joystick

Problem
Joysticks in general don't behave according to most people's intuition.

The goal is to develop VHDL modules for every logisim part. The logisim joystick needs the most work. Joystics in general don't behave according to most people's intuition.

A joystick is physically ringed with switches. Sometimes two or more switches are depressed at once. The center position may or may not have a button underneath it. The logisim joystick doesn't have a button under it. The papilio logic start megawing does.

The starting point is to simulate this circuit logisim joystick (has a bit width of 2 in the logisim settings).

Comparison to Joystick in Logisms
Logism Joystick logisim joystick

5 LEDs were assigned to the Papilio Joystick outputs (up down left right and center push) to understand how it works. Here is what was found:
 * The logic start mega wing joystick outputs are normally one and then turn momentarily to zero in different patterns when the joystick is moved.
 * The logisim's joystick outputs are normally zero and then turn momentarily into a 1 in different patterns when the joystick is moved.
 * The logisim joystick has no center switch like the logic start mega wing.

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all;

entity JOY_LED is   Port ( LED : out  STD_LOGIC_VECTOR (4 downto 0);           JOY_RIGHT : in  STD_LOGIC;           JOY_LEFT : in  STD_LOGIC;           JOY_UP : in  STD_LOGIC;           JOY_DOWN : in  STD_LOGIC;           JOY_SELECT: in  STD_LOGIC); end JOY_LED;

architecture Behavioral of JOY_LED is

begin LED(0) <= not JOY_SELECT; LED(1) <= not JOY_LEFT; LED(2) <= not JOY_UP; LED(3) <= not JOY_RIGHT; LED(4) <= not JOY_DOWN;

end Behavioral;



Joystick to LED

Design
Each segment is treated as a state. When a segment is selected it goes to that state and remains in that state until another choice is made.

The five state are: state up, state down, state left, state right and state center.

Whenever the corresponding joystick option to a state is selected the papillio would go to that state and remain in that state even after the joystick is released.

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all;

entity Joy is   Port ( JOY_UP : in  STD_LOGIC;           JOY_RIGHT : in  STD_LOGIC;           JOY_DOWN : in  STD_LOGIC;           JOY_LEFT : in  STD_LOGIC;           JOY_SELECT : in  STD_LOGIC;           LED : out  STD_LOGIC_VECTOR (3 downto 0);           CLK : in  STD_LOGIC); end Joy;

architecture Behavioral of Joy is constant state_center	:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000000"; constant state_up		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000001"; constant state_right		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000011"; constant state_down	:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000111"; constant	state_left		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00001111";

signal 	state			:	STD_LOGIC_VECTOR(7 downto 0)	:= (others => '0');

begin clk_proc: process(CLK) begin if rising_edge(CLK) then CASE state is		when state_up => LED <="0001"; when state_right => LED <= "0010"; when state_down => LED<= "0100"; when state_left => LED <= "1000"; when state_center => LED <= "0000"; when others => LED <= "0000"; END CASE; CASE state is when state_up => if JOY_UP = '1' then state <= state_up; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if;

when state_right => if JOY_RIGHT = '1' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_down => if JOY_DOWN = '1' then state <= state_down; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_left => if JOY_LEFT = '1' then state <= state_left; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_center => if JOY_SELECT = '1' then state <= state_center; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; when others => if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; END CASE; end if; end process;

end Behavioral;



Joystick testing demo

Implementation
It was hard to test whether it was working by just looking at individual LED's. So setup four different flashing patterns of the LED's Different patterns for up down left right and then off after pressing the middle of the joystick down.

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all;

entity patern is   Port ( JOY_SELECT : in  STD_LOGIC;           JOY_UP : in  STD_LOGIC;           JOY_DOWN : in  STD_LOGIC;           JOY_RIGHT : in  STD_LOGIC;           JOY_LEFT : in  STD_LOGIC;           LED : out  STD_LOGIC_VECTOR (7 downto 0);           CLK : in  STD_LOGIC); end patern;

architecture Behavioral of patern is

COMPONENT blinking PORT (   clk : IN STD_LOGIC;    q : OUT STD_LOGIC_VECTOR(29 DOWNTO 0)  ); END COMPONENT;

COMPONENT patern1 PORT (   clka : IN STD_LOGIC;    addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)  ); END COMPONENT;

COMPONENT patern2 PORT (   clka : IN STD_LOGIC;    addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)  ); END COMPONENT;

COMPONENT patern3 PORT (   clka : IN STD_LOGIC;    addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)  ); END COMPONENT;

COMPONENT JOYSTICK PORT(		JOY_SELECT : IN std_logic;		JOY_UP : IN std_logic;		JOY_DOWN : IN std_logic;		JOY_LEFT : IN std_logic;		JOY_RIGHT : IN std_logic;		CLK : IN std_logic;		pat1 : IN std_logic_vector(7 downto 0);		pat2 : IN std_logic_vector(7 downto 0);		pat3 : IN std_logic_vector(7 downto 0);         		LED : OUT std_logic_vector(7 downto 0)		); END COMPONENT;

signal 	count	:	STD_LOGIC_VECTOR(29 downto 0);

signal pat1 :	STD_LOGIC_VECTOR(7 downto 0); signal pat2 :	STD_LOGIC_VECTOR(7 downto 0); signal pat3 :	STD_LOGIC_VECTOR(7 downto 0);

begin

count30 : blinking PORT MAP (   clk => CLK,    q => count  );

P1 : patern1 PORT MAP (   clka => CLK,    addra => count(29 downto 21),    douta => pat1  ); P2 : patern2 PORT MAP (   clka => CLK,    addra => count(29 downto 21),    douta => pat2  ); P3 : patern3 PORT MAP (   clka => CLK,    addra => count(29 downto 21),    douta => pat3  ); Inst_JOYSTICK: JOYSTICK PORT MAP(		JOY_SELECT => JOY_SELECT ,		JOY_UP => JOY_UP ,		JOY_DOWN => JOY_DOWN ,		JOY_LEFT => JOY_LEFT ,		JOY_RIGHT => JOY_RIGHT,		LED => LED ,		CLK => CLK ,		pat1 => pat1,		pat2 => pat2,		pat3 => pat3	); end Behavioral;

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all;

entity JOYSTICK is   Port ( JOY_SELECT : in  STD_LOGIC;           JOY_UP : in  STD_LOGIC;           JOY_DOWN : in  STD_LOGIC;           JOY_LEFT : in  STD_LOGIC;           JOY_RIGHT : in  STD_LOGIC;           LED : out  STD_LOGIC_VECTOR (7 downto 0);           CLK : in  STD_LOGIC;			  pat1: in STD_LOGIC_VECTOR (7 downto 0);			  pat2:in STD_LOGIC_VECTOR (7 downto 0);			  pat3:in STD_LOGIC_VECTOR (7 downto 0)); end JOYSTICK;

architecture Behavioral of JOYSTICK is constant state_center	:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000000"; constant state_up			:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000001"; constant state_right		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000011"; constant state_down		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00000111"; constant	state_left		:	STD_LOGIC_VECTOR(7 downto 0)	:= "00001111";

signal 	state				:	STD_LOGIC_VECTOR(7 downto 0)	:= (others => '0');

begin

clk_proc: process(CLK) begin if rising_edge(CLK) then CASE state is		when state_up => LED <= pat1; when state_right => LED <= pat2; when state_down => LED<= pat3; when state_left => LED <= "11111111"; when state_center => LED <= "00000000"; when others => LED <= "00000000"; END CASE; CASE state is when state_up => if JOY_UP = '1' then state <= state_up; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if;

when state_right => if JOY_RIGHT = '1' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_down => if JOY_DOWN = '1' then state <= state_down; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_left => if JOY_LEFT = '1' then state <= state_left; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; when state_center => if JOY_SELECT = '1' then state <= state_center; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; when others => if JOY_RIGHT = '0' then state <= state_right; end if; if JOY_LEFT = '0' then state <= state_left; end if; if JOY_UP = '0' then state <= state_up; end if; if JOY_DOWN = '0' then state <= state_down; end if; if JOY_SELECT = '0' then state <= state_center; end if; END CASE; end if; end process;

end Behavioral;

Demo

Next Step
Build logisim microphone in and sound out circuits that mirror papilio logic start mega wing functionality and then write VHDL modules at mirror the logisim circuit. Sound out should have different notes as input. Microphone in should produce patterns on the LED's based upon amplitude heard.

Other VHDL modules can be built that mirror logisim's 7-segment display, hex digit display, and TTL through the logic start mega wing VGA port.