LIBRARY IEEE; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_1164.all; ENTITY mousestream IS PORT( clk : IN STD_LOGIC; enable : IN STD_LOGIC; leftbutton : IN STD_LOGIC; rightbutton : IN STD_LOGIC; middlebutton : IN STD_LOGIC; xsign : IN STD_LOGIC; ysign : IN STD_LOGIC; xmove : IN STD_LOGIC_VECTOR(7 DOWNTO 0); ymove : IN STD_LOGIC_VECTOR(7 DOWNTO 0); clk_10k : INOUT STD_LOGIC; clk_20k : OUT STD_LOGIC; MOUSE_DATA : INOUT STD_LOGIC); END mousestream; ARCHITECTURE a OF mousestream IS TYPE STATE_TYPE IS (INIT_STATE, STREAM_MODE, MOUSEDATA, LOAD_COMMAND1, LOAD_COMMAND2, WAIT_OUTPUT_READY, WAIT_OUTPUT_PAUSE); SIGNAL mouse_state : STATE_TYPE; SIGNAL ClkDivisor_10k : STD_LOGIC_VECTOR(10 DOWNTO 0); SIGNAL Clk_10k_buff : STD_LOGIC; SIGNAL Clk_20k_buff : STD_LOGIC; SIGNAL COUNT_STREAM : STD_LOGIC_VECTOR(16 DOWNTO 0); -- SIGNAL Clk_100_buff : STD_LOGIC; SIGNAL MOUSE_DATA_DIR : STD_LOGIC; SIGNAL MOUSE_DATA_BUF : STD_LOGIC; SIGNAL MOUSE_CLK_DIR : STD_LOGIC; SIGNAL STREAMMODE : STD_LOGIC; SIGNAL SEND_DATA, output_ready,IREADY_SET : STD_LOGIC; SIGNAL SEND_CHAR, READ_CHAR, SEND_UPDATE : STD_LOGIC; SIGNAL RECEIVE_DATA : STD_LOGIC; SIGNAL OUTCNT : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL INCNT : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CHARIN, CHAROUT : std_logic_vector(7 DOWNTO 0); SIGNAL SHIFTIN : std_logic_vector(8 DOWNTO 0); SIGNAL SHIFTOUT : std_logic_vector(10 DOWNTO 0); SIGNAL PACKET_COUNT : std_logic_vector(1 DOWNTO 0); SIGNAL PACKET_CHAR1, PACKET_CHAR2, PACKET_CHAR3 : std_logic_vector(7 DOWNTO 0); SIGNAL PAUSETIME : std_logic_vector(12 DOWNTO 0); SIGNAL COUNT_CLICKS : std_logic_vector(3 DOWNTO 0); SIGNAL xmovement : std_logic_vector(7 DOWNTO 0); SIGNAL ymovement : std_logic_vector(7 DOWNTO 0); BEGIN MOUSE_DATA <= 'Z' WHEN MOUSE_DATA_DIR = '0' ELSE MOUSE_DATA_BUF; clk_10k <= 'Z' WHEN MOUSE_CLK_DIR = '0' ELSE Clk_10k_buff; clk_20k <= clk_20k_buff; PROCESS (clk, enable) BEGIN IF clk'event AND clk = '1' THEN IF(ClkDivisor_10k = "10011100001") then -- IF(ClkDivisor_10k = "00011111001") then Clk_20k_buff <= NOT Clk_20k_buff; ClkDivisor_10k <= "00000000000"; Clk_10k_buff <= NOT CLK_10k_buff; ELSIF (ClkDivisor_10k = "1001110000") THEN -- ELSIF (ClkDivisor_10k = "0001111100") THEN Clk_20k_buff <= NOT Clk_20k_buff; clkDivisor_10k <= clkDivisor_10k + 1; ELSE clkDivisor_10k <= clkDivisor_10k + 1; END IF; IF (enable = '1') THEN COUNT_STREAM <= "00000000000000001"; END IF; IF COUNT_STREAM = "00010101101101100" THEN COUNT_STREAM <= "00000000000000000"; ELSIF (COUNT_STREAM > "00000000000000000") THEN COUNT_STREAM <= COUNT_STREAM + 1; END IF; END IF; END PROCESS; PROCESS(enable, COUNT_STREAM) BEGIN IF (COUNT_STREAM = "00010101101101100") THEN SEND_UPDATE <= '0'; ELSIF (enable'event AND enable = '1') THEN IF ((STREAMMODE = '1') AND (mouse_state = STREAM_MODE)) THEN SEND_UPDATE <= '1'; PACKET_CHAR1 <= "00" & ysign & xsign & '1' & middlebutton & rightbutton & leftbutton; PACKET_CHAR2 <= xmove; PACKET_CHAR3 <= ymove; END IF; END IF; END PROCESS; PROCESS (clk) BEGIN IF clk'EVENT AND clk = '1' THEN CASE mouse_state IS WHEN INIT_STATE => PACKET_COUNT <= "11"; STREAMMODE <= '1'; SEND_DATA <= '0'; RECEIVE_DATA <= '1'; mouse_state <= STREAM_MODE; WHEN STREAM_MODE => IF (SEND_UPDATE = '1') THEN IF (clk_10k_buff = '1' and Clk_20k_buff = '1') THEN mouse_state <= MOUSEDATA; ELSE mouse_state <= STREAM_MODE; END IF; ELSE mouse_state <= STREAM_MODE; END IF; WHEN MOUSEDATA => IF (PACKET_COUNT = "00") THEN PACKET_COUNT <= "11"; mouse_state <= STREAM_MODE; ELSIF (PACKET_COUNT = "01") THEN PACKET_COUNT <= PACKET_COUNT - 1; CHAROUT <= PACKET_CHAR3; mouse_state <= LOAD_COMMAND1; ELSIF (PACKET_COUNT = "10") THEN PACKET_COUNT <= PACKET_COUNT - 1; CHAROUT <= PACKET_CHAR2; mouse_state <= LOAD_COMMAND1; ELSIF (PACKET_COUNT = "11") THEN PACKET_COUNT <= PACKET_COUNT - 1; CHAROUT <= PACKET_CHAR1; mouse_state <= LOAD_COMMAND1; END IF; WHEN LOAD_COMMAND1 => SEND_DATA <= '1'; mouse_state <= LOAD_COMMAND2; WHEN LOAD_COMMAND2 => SEND_DATA <= '1'; mouse_state <= WAIT_OUTPUT_READY; WHEN WAIT_OUTPUT_READY => SEND_DATA <= '0'; IF (output_ready = '1') THEN mouse_state <= WAIT_OUTPUT_PAUSE; ELSE mouse_state <= WAIT_OUTPUT_READY; END IF; WHEN WAIT_OUTPUT_PAUSE => IF(PAUSETIME = "1110101001011") THEN -- IF(PAUSETIME = "0010011100001") THEN IF (Clk_10k_buff = '1' and Clk_20k_buff = '1') THEN PAUSETIME <= "0000000000000"; mouse_state <= MOUSEDATA; ELSE mouse_state <= WAIT_OUTPUT_PAUSE; END IF; ELSE PAUSETIME <= PAUSETIME + 1; mouse_state <= WAIT_OUTPUT_PAUSE; END IF; END CASE; END IF; END PROCESS; WITH mouse_state SELECT MOUSE_DATA_DIR <= '0' WHEN INIT_STATE, '0' WHEN STREAM_MODE, '0' WHEN MOUSEDATA, '1' WHEN LOAD_COMMAND1, '1' WHEN LOAD_COMMAND2, '1' WHEN WAIT_OUTPUT_READY, '0' WHEN WAIT_OUTPUT_PAUSE; WITH mouse_state SELECT MOUSE_CLK_DIR <= '0' WHEN INIT_STATE, '0' WHEN STREAM_MODE, '0' WHEN MOUSEDATA, '1' WHEN LOAD_COMMAND1, '1' WHEN LOAD_COMMAND2, '1' WHEN WAIT_OUTPUT_READY, '0' WHEN WAIT_OUTPUT_PAUSE; PROCESS (SEND_DATA, clk_20k_buff) BEGIN IF SEND_DATA = '1' THEN OUTCNT <= "0000"; SEND_CHAR <= '1'; OUTPUT_READY <= '0'; -- Send out Start Bit(0) + Command(F4) + Parity Bit(0) + Stop Bit(1) SHIFTOUT(8 DOWNTO 1) <= CHAROUT ; -- START BIT SHIFTOUT(0) <= '0'; -- COMPUTE ODD PARITY BIT SHIFTOUT(9) <= not (charout(7) xor charout(6) xor charout(5) xor charout(4) xor Charout(3) xor charout(2) xor charout(1) xor charout(0)); -- STOP BIT SHIFTOUT(10) <= '1'; -- Data Available Flag to Mouse -- Tells mouse to clock out command data (is also start bit) MOUSE_DATA_BUF <= '0'; ELSIF((clk_20k_buff'event) and (clk_20k_buff = '1')) THEN IF MOUSE_DATA_DIR='1' AND clk_10k = '1' THEN -- SHIFT OUT NEXT SERIAL BIT IF SEND_CHAR = '1' THEN -- Loop through all bits in shift register IF OUTCNT <= "1001" THEN OUTCNT <= OUTCNT + 1; -- Shift out next bit to mouse SHIFTOUT(9 DOWNTO 0) <= SHIFTOUT(10 DOWNTO 1); SHIFTOUT(10) <= '1'; MOUSE_DATA_BUF <= SHIFTOUT(1); OUTPUT_READY <= '0'; -- END OF CHARACTER ELSE SEND_CHAR <= '0'; OUTPUT_READY <= '1'; -- Signal the character has been output OUTCNT <= "0000"; END IF; END IF; END IF; END IF; END PROCESS; PROCESS(RECEIVE_DATA, clk_10k) BEGIN IF (RECEIVE_DATA = '1') THEN IREADY_SET <= '0'; INCNT <= "0000"; READ_CHAR <= '0'; CHARIN <= "00000000"; ELSE IF clk_10k'event and clk_10k ='1' THEN IF MOUSE_DATA_DIR ='0' THEN IF MOUSE_DATA ='0' AND READ_CHAR='0' THEN READ_CHAR <= '1'; IREADY_SET<= '0'; INCNT <= "0000"; ELSE -- SHIFT IN NEXT SERIAL BIT IF READ_CHAR = '1' THEN IF INCNT < "1001" THEN INCNT <= INCNT + 1; SHIFTIN(7 DOWNTO 0) <= SHIFTIN(8 DOWNTO 1); SHIFTIN(8) <= MOUSE_DATA; IREADY_SET <= '0'; -- END OF CHARACTER ELSE CHARIN <= SHIFTIN(7 DOWNTO 0); READ_CHAR <= '0'; IREADY_SET <= '1'; INCNT <= conv_std_logic_vector(0,4); END IF; END IF; END IF; END IF; END IF; END IF; END PROCESS; END a;