Project

General

Profile


--===============================================================================
---USB_DRVR Entity (Drives and Reads D+ and D- lines to send and receive packets)
--===============================================================================
-- USB Driver - Copywrite Hakim Haddadi arcade retro gaming.
--------------------------------------------------
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
use WORK.USBF_Declares.all;

--------------------------------------------------
entity USB_DRVR2 is
port(
clk_usb : in std_logic; -- 5MHz clock
pll_lock : in std_logic;
reset : in std_logic; -- fpga reset
dminus : inout std_logic; -- USB differential D+ line
dplus : inout std_logic; -- USB differential D+ line
joyright_out : out std_logic_vector(7 downto 0);
joyleft_out : out std_logic_vector(7 downto 0);
mousex_out : out std_logic_vector(11 downto 0);
mousey_out : out std_logic_vector(11 downto 0)
);
end USB_DRVR2;
---------------------------------------------------

architecture arch of USB_DRVR2 is
------------------------

component sub_pll IS
PORT
(
areset : IN STD_LOGIC := '0';
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC ;
locked : OUT STD_LOGIC
);
END component sub_pll;

component rom_com1 IS
PORT
(
address : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
clock : IN STD_LOGIC := '1';
rden : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END component rom_com1;
signal dp_last, dp_prev, dp1_last,dm1_last : std_logic;
signal nb_bits : std_logic_vector(3 downto 0); --bit counter for receive bits
signal stuffin1 : integer range 0 to 7; --counters for stuff-bits out and in
signal usb_lock : std_logic := '0';
--signal clk_usb : std_logic;
signal reg_10bits : std_logic_vector(9 downto 0);
signal reg_10bits_receive : std_logic_vector(9 downto 0);
signal dp2_prev : std_logic;
signal CLOCK12MHz : std_logic;
signal CLOCK12MHz_receive : std_logic;
signal token_pid2 : std_logic_vector(3 downto 0);
signal data_pkt1 : std_logic_vector(7 downto 0);
signal data_temp : std_logic_vector(7 downto 0);
signal data_rom : std_logic_vector(7 downto 0);
-- ROM signals
signal address_rom : std_logic_vector(8 downto 0);
signal rom_out : std_logic_vector(7 downto 0);
signal rden_sig : std_logic;
signal data_tosend : std_logic_vector(7 downto 0);
signal nb_byte_tosend : std_logic_vector(7 downto 0);
signal address_start : std_logic_vector(8 downto 0);
signal dm_previous : std_logic;
signal dp_previous : std_logic;
signal dplus_buf1 : std_logic;
signal dplus_buf2 : std_logic;
signal dminus_buf1 : std_logic;
signal dminus_buf2 : std_logic;
signal start_sendcom : std_logic;
signal send_frame : std_logic;
signal usb_reset : std_logic;
signal synch : std_logic;
signal read_byte_valid : std_logic;
signal read_byte_valid_c : std_logic;
signal data_available : std_logic;
signal data_valid : std_logic;
signal data_valid_temp : std_logic;
signal gamepad_basic : std_logic;
signal detach_ack : std_logic;
signal detach : std_logic;
signal joystick_type : std_logic;
signal joystick_updown : std_logic;
signal set_command : std_logic_vector(1 downto 0);
signal counter1 : std_logic_vector(7 downto 0);
signal counterdetach : std_logic_vector(3 downto 0);
signal counter2 : std_logic_vector(3 downto 0);
signal counter30ms : std_logic_vector(18 downto 0);
signal counter1_3ms : std_logic_vector(14 downto 0);
signal joyright_temp : std_logic_vector(7 downto 0);
signal joyleft_temp : std_logic_vector(7 downto 0);
signal data_byte2 : std_logic_vector(7 downto 0);
signal nb_reset : std_logic_vector(7 downto 0);
signal val : std_logic;
signal mouse_valid : std_logic;
signal mouse_counter1 : std_logic_vector(8 downto 0);
signal mousex_temp : std_logic_vector(7 downto 0);
signal mousey_temp : std_logic_vector(7 downto 0);
signal mousex_ctr : std_logic_vector(11 downto 0);
signal mousey_ctr : std_logic_vector(11 downto 0);
type usb1_sm_type is ( -- receive state machine
state1, state2, state3, --,
state4);
type usb_com_type is ( --send state machine #1 to read D+/D- lines
Idle,
send1, send2,send3, reset_start, --
send4, send5,send6, reset_released, --
send_bit0, send_bit1,send_bit2, --
send_bit3, send_bit4,send_bit5, --
send_bit6, send_bit7,send15, --
end_send1, end_send2, send_complete --
);

type usb_manage_type is ( --Tranceiver state machine #1 to read D+/D- lines
Idle,
usb_manage1, usb_manage2, --
usb_reset_state, crc_complete, usb_waitdetachrelease, wait_for_deviceconnect,
usb_wait30ms, end_set_address, end_set_configuration, end_set_idle,
read_pktin2, read_pktin3, read_pktin4, wait_pktin4,
setaddress_sendpkt1, setaddress_sendpkt1_end,
setaddress_sendpkt2, setaddress_sendpkt2_end,
setaddress_sendpkt3, setaddress_sendpkt3_end,
send_ack, send_ack_start, send_ack_end,
getreport_sendpkt1, getreport_sendpkt1_start, getreport_sendpkt1_end,
wait_pktin1, wait_pktin2, wait_pktin3,
wait_report_start, start_get_report,
send_getreport_ack, send_getreport_ack_start, send_getreport_ack_end,
start_get_data,
wait_read_byte2, wait_read_byte3, wait_read_byte4, wait_read_byte5, wait_read_byte6,
wait_read_byte7, wait_read_byte8, wait_read_byte9, wait_read_byte10, wait_read_byte11,
read_byte1, read_byte2, read_byte3, read_byte4, read_byte5, read_byte6,
read_byte7, read_byte8, read_byte9, read_byte10, read_byte11,
wait1, wait2, wait4, wait6,
wait20, wait21, wait30, wait40,
wait_ack2,
usb_reset_1ms_start, usb_reset_1ms_wait1, usb_reset_1ms_wait2, usb_reset_1ms_release
);
type usb_detach_type is ( --Tranceiver state machine #1 to read D+/D- lines
Idle,
detach_start, detach_wait,detach_valid -- --
);
type mouse_state_type is ( --Tranceiver state machine #1 to read D+/D- lines
Idle,
state1 -- --
);
signal usb_detach : usb_detach_type;
signal usb1_state : usb1_sm_type;
signal usb_send_com : usb_com_type;
signal usb_manage : usb_manage_type;
signal mouse_state : mouse_state_type;
------------------------------------------------------------

ATTRIBUTE keep : boolean;
ATTRIBUTE keep OF dminus : SIGNAL IS TRUE;
ATTRIBUTE keep OF dplus : SIGNAL IS TRUE;
ATTRIBUTE keep OF clk_usb : SIGNAL IS TRUE;
ATTRIBUTE keep OF CLOCK12MHz : SIGNAL IS TRUE;
ATTRIBUTE keep OF rom_out : SIGNAL IS TRUE;
ATTRIBUTE keep OF joyright_out : SIGNAL IS TRUE;
ATTRIBUTE keep OF joyleft_out : SIGNAL IS TRUE;
ATTRIBUTE keep OF joyright_temp : SIGNAL IS TRUE;
ATTRIBUTE keep OF joyleft_temp : SIGNAL IS TRUE;
begin

----------------------------------
-- instantiate the rom commands --
----------------------------------
rom_com_inst : rom_com1
PORT MAP (
address => address_rom,
clock => clk_usb,
rden => rden_sig AND CLOCK12MHz,
q => rom_out
);
usb_lock <= pll_lock;
-----------------------------
-- update of joystick data --
-----------------------------
PROCESS
(
usb_lock, -- External asynchronous reset
clk_usb -- 15 MHz clock (usb over sampling)

)
BEGIN
--
IF (usb_lock = '0') THEN
joyright_out <= "11111111";
joyleft_out <= "11111111";
ELSIF (rising_edge(clk_usb)) THEN
IF (data_available = '1') THEN
IF (data_valid = '1') THEN
-- bit 0 : 2
-- bit 1 : 4
-- bit 2 : 3
-- bit 3 : 1
-- bit 4 : fire button / start
-- bit 5 : fire button / start
-- bit 6 : button front right "2"
-- bit 7 : button front right "1"
joyright_out <= joyright_temp;
-- bit 0 : right
-- bit 1 : left
-- bit 2 : down
-- bit 3 : up
-- bit 4 : fire button / select
-- bit 5 : fire button / select
-- bit 6 : button front left "2"
-- bit 7 : button front left "1"
joyleft_out <= joyleft_temp;
ELSE
-- bit 0 : 2
-- bit 1 : 4
-- bit 2 : 3
-- bit 3 : 1
-- bit 4 : fire button / start
-- bit 5 : fire button / start
-- bit 6 : button front right "2"
-- bit 7 : button front right "1"
joyright_out <= joyright_temp;
-- bit 0 : Not active
-- bit 1 : Not active
-- bit 2 : Not active
-- bit 3 : Not active
-- bit 4 : fire button / select
-- bit 5 : fire button / select
-- bit 6 : button front left "2"
-- bit 7 : button front left "1"
joyleft_out(7 downto 4) <= joyleft_temp(7 downto 4);
joyleft_out(3 downto 0) <= "1111";
END IF;
END IF;
END IF;
END PROCESS;
----------------------------------------------
-- usb clock enable generation for sending --
----------------------------------------------
PROCESS
(
usb_lock, -- reset_process, -- External asynchronous reset
clk_usb -- over sampling clk 15MHz
)
BEGIN
--
IF (usb_lock = '0') THEN
reg_10bits <= "0000000001";
ELSIF (rising_edge(clk_usb)) THEN
reg_10bits <= reg_10bits(8 downto 0) & reg_10bits(9); --
END IF;
END PROCESS;
-- update clock enable USB
CLOCK12MHz <= reg_10bits(4);
------------------------------------------------
-- usb clock enable generation for receiving --
------------------------------------------------
-- process generating a 15 MHz clk enable signal in phase with the incoming data from the device
-- the process is using an oversampling clk of 15 MHz
PROCESS
(
usb_lock, --reset_process, -- External asynchronous reset
clk_usb -- over sampling clk 48MHz
)
BEGIN
--
IF (usb_lock = '0') THEN
reg_10bits_receive <= "0000000001";
dp2_prev <= dplus_buf2;
ELSIF (rising_edge(clk_usb)) THEN
dp2_prev <= dplus_buf2; -- sample the input D+ line
IF (dp2_prev /= dplus_buf2) THEN
reg_10bits_receive <= "0000000001"; -- reset the phase of the USB clk
ELSE
reg_10bits_receive <= reg_10bits_receive(8 downto 0) & reg_10bits_receive(9); --
END IF;
END IF;
END PROCESS;
-- update clock USB
CLOCK12MHz_receive <= reg_10bits_receive(4);
--------------------------------------------------------------------------------------
--------------------- buffering of Dplus - Dminus to avoid metastability ------------
--------------------------------------------------------------------------------------
process (clk_usb, usb_lock) is
begin
if usb_lock = '0' then
dplus_buf1 <= '0';
dplus_buf2 <= '0';
dminus_buf1 <= '0';
dminus_buf2 <= '0';
elsif rising_edge(clk_usb) then --
dplus_buf1 <= dplus;
dplus_buf2 <= dplus_buf1;
dminus_buf1 <= dminus;
dminus_buf2 <= dminus_buf1;
end if;
end process;
---------------------------------------------------------------------
------------------ state machine for acquiring usb data
---------------------------------------------------------------------
process (reset, clk_usb, CLOCK12MHz_receive) is
begin
if (reset = '0') then
dp1_last <= dplus_buf2;
dm1_last <= dminus_buf2;
data_pkt1 <= "00000000";
data_temp <= "00000000";
read_byte_valid <= '0';
usb1_state <= state1;
nb_bits <= "0000";
stuffin1 <= 0;
synch <= '0';
elsif (rising_edge(clk_usb) AND CLOCK12MHz_receive = '1') then
case usb1_state is
-------------- state1 ----------------
when state1 =>
read_byte_valid <= '1';
data_pkt1 <= "00000000";
data_temp <= "00000000";
if dplus_buf2 = '0' and dminus_buf2 = '0' then
usb1_state <= state1; -- reset state
elsif dplus_buf2 = '1' and dminus_buf2 = '0' then
dp1_last <= dplus_buf2;
dm1_last <= dminus_buf2;
usb1_state <= state2; -- go to state2 and wait for synch
end if;
nb_bits <= "0000";
-------------- state2 ----------------
when state2 =>
dp1_last <= dplus_buf2;
dm1_last <= dminus_buf2;
if dp1_last /= dplus_buf2 and dm1_last /= dminus_buf2 then
nb_bits <= nb_bits + 1; -- start of synch
elsif dplus_buf2 = '0' and dminus_buf2 = '0' then
usb1_state <= state1; -- reset state
nb_bits <= "0000";
end if;
if nb_bits = "0110" then
usb1_state <= state3; -- go to state 3 and wait for final synch
end if;
-------------- state3 ----------------
when state3 =>
dp1_last <= dplus_buf2;
dm1_last <= dminus_buf2;
if dplus_buf2 = '0' and dminus_buf2 = '1' then
nb_bits <= nb_bits + 1; -- start of synch
elsif dplus_buf2 = '0' and dminus_buf2 = '0' then
usb1_state <= state1; -- reset state
data_pkt1 <= "00000000";
data_temp <= "00000000";
nb_bits <= "0000";
end if;

if nb_bits = "0111" then
usb1_state <= state4; -- synch byte complete start aquiring packets
data_pkt1 <= "10000000";
data_temp <= "10000000";
read_byte_valid <= Not read_byte_valid;
nb_bits <= "0000";
synch <= '1';
end if;
-------------- state4 ----------------
when state4 =>
if detach = '1' then
usb1_state <= state1;
else
if dplus_buf2 = '0' and dminus_buf2 = '0' then
usb1_state <= state1; -- reset state
data_pkt1 <= data_temp;
data_temp <= "00000000";
nb_bits <= "0000";
else
dp1_last <= dplus_buf2;
if (stuffin1 = 6 and nb_bits = "0000") then
stuffin1 <= 0;
val <= '1';
elsif stuffin1 = 6 then -- after 6 '1's in a row = This is a stuff bit.
stuffin1 <= 0; -- ignore it and reset the stuff count.
val <= '0';
else -- no stuff bit, get the real bit based on D+/D- lines.
val <= '0';
nb_bits <= nb_bits + 1; -- Count the real bits. Current 'bitin' is always coming in.
if dp1_last = dplus_buf2 then -- NRZI test. no change -> 1
stuffin1 <= stuffin1 + 1; -- count the consecutive 1's
if(nb_bits = "0000") then
data_temp(0) <= '1';
elsif(nb_bits = "0001") then
data_temp(1) <= '1';
elsif(nb_bits = "0010") then
data_temp(2) <= '1';
elsif(nb_bits = "0011") then
data_temp(3) <= '1';
elsif(nb_bits = "0100") then
data_temp(4) <= '1';
elsif(nb_bits = "0101") then
data_temp(5) <= '1';
elsif(nb_bits = "0110") then
data_temp(6) <= '1';
else
data_temp(7) <= '1';
end if;
else
if(nb_bits = "0000") then
data_temp(0) <= '0';
elsif(nb_bits = "0001") then
data_temp(1) <= '0';
elsif(nb_bits = "0010") then
data_temp(2) <= '0';
elsif(nb_bits = "0011") then
data_temp(3) <= '0';
elsif(nb_bits = "0100") then
data_temp(4) <= '0';
elsif(nb_bits = "0101") then
data_temp(5) <= '0';
elsif(nb_bits = "0110") then
data_temp(6) <= '0';
else
data_temp(7) <= '0';
end if;
stuffin1 <= 0; --reset the stuff-bit count when a 0
end if;
end if;
end if;
if (nb_bits = "0111") AND (stuffin1 /= 6) then
usb1_state <= state4;
nb_bits <= "0000";
end if;
if nb_bits = "0000" AND synch = '1' then
synch <= '0';
elsif nb_bits = "0000" AND val = '1' then
data_pkt1 <= data_temp;
elsif nb_bits = "0000" then
data_pkt1 <= data_temp;
read_byte_valid <= Not read_byte_valid;
end if;
end if;
when others =>
usb1_state <= state1;
nb_bits <= "0000";
end case;
end if;
end process;
------------------------------------------------------
------ state machine for sending usb data
------------------------------------------------------
process (usb_lock, clk_usb, CLOCK12MHz) is
begin
if (usb_lock = '0') then
data_tosend <= "00000000";
nb_byte_tosend <= "00000000";
dp_previous <= '1';
dm_previous <= '0';
dplus <= '1';
dminus <= '0';
usb_send_com <= idle;
elsif (rising_edge(clk_usb) AND CLOCK12MHz = '1') then
case usb_send_com is
-------------- wait for the reset start trigger ----------------
when idle =>
data_tosend <= "00000000";
send_frame <= '0';
if (usb_reset = '1') then -- the start of sending data is initiated by the usb manage state machine
usb_send_com <= reset_start; -- reset start state
dplus <= '0';
dminus <= '0';
else
usb_send_com <= idle; -- go to idle state
end if;
-------------- wait for the start trigger ----------------
when reset_start =>
if (usb_reset = '0') then -- The reset is released
usb_send_com <= reset_released; -- end of reset state
dplus <= 'Z';
dminus <= 'Z';
else
usb_send_com <= reset_start;
end if;
-------------- wait for the start trigger ----------------
when reset_released =>
data_tosend <= "00000000";
send_frame <= '0';
if (usb_reset = '1') then
dplus <= '0';
dminus <= '0';
usb_send_com <= reset_start;
elsif (start_sendcom = '1') then -- the start of sending data is initiated by the usb manage state machine
usb_send_com <= send1; -- next state
rden_sig <= '1';
address_rom <= address_start; -- inialise the address_com with the address set by the usb state machine
else
dplus <= 'Z';
dminus <= 'Z';
usb_send_com <= reset_released; -- wait for send com trigger
end if;
-------------- prepare for the next read ----------------
when send1 =>
address_rom <= address_rom + "000000001"; -- prepare for the next read
rden_sig <= '1'; -- read the first byte
usb_send_com <= send2;
-------------- read the rom first byte ----------------
when send2 =>
nb_byte_tosend <= rom_out; -- read the first byte
usb_send_com <= send3;
-------------- read the next bytes to send ----------------
when send3 =>
data_tosend <= rom_out; -- read the next byte
rden_sig <= '0';
usb_send_com <= send_bit0;
-------------- send_bit0 ----------------
when send_bit0 =>
nb_byte_tosend <= nb_byte_tosend - "00000001";
rden_sig <= '0'; -- disable the rom read
if data_tosend(0) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
usb_send_com <= send_bit1;
-------------- send_bit1 ----------------
when send_bit1 =>
if data_tosend(1) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
usb_send_com <= send_bit2;
-------------- send_bit2 ----------------
when send_bit2 =>
if data_tosend(2) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
usb_send_com <= send_bit3;
-------------- send_bit3 ----------------
when send_bit3 =>
if data_tosend(3) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
usb_send_com <= send_bit4;
-------------- send_bit4 ----------------
when send_bit4 =>
if data_tosend(4) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
usb_send_com <= send_bit5;
-------------- send_bit5 ----------------
when send_bit5 =>
if data_tosend(5) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
address_rom <= address_rom + "000000001"; -- prepare for the next read
rden_sig <= '1';
usb_send_com <= send_bit6;
-------------- send_bit6 ----------------
when send_bit6 =>
if data_tosend(6) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
rden_sig <= '0';
usb_send_com <= send_bit7;
-------------- send_bit7 ----------------
when send_bit7 =>
if data_tosend(7) = '0' then
dplus <= NOT dp_previous;
dminus <= NOT dm_previous;
dp_previous <= NOT dp_previous;
dm_previous <= NOT dm_previous;
else
dplus <= dp_previous;
dminus <= dm_previous;
end if;
data_tosend <= rom_out;
rden_sig <= '0';
if nb_byte_tosend = "00000000" then
usb_send_com <= end_send1;
else
usb_send_com <= send_bit0; -- send next byte
end if;
-------------- send_end of frame ----------------
when end_send1 =>
dplus <= '0';
dminus <= '0';
usb_send_com <= end_send2;
-------------- send_end of frame ----------------
when end_send2 =>
dplus <= '0';
dminus <= '0';
usb_send_com <= send_complete;
-------------- send_complete ----------------
when send_complete =>
send_frame <= '1';
dplus <= 'Z';
dminus <= 'Z';
dp_previous <= '1';
dm_previous <= '0';
usb_send_com <= reset_released;
when others =>
usb_send_com <= idle;
end case;
end if;
end process;
--------------------------------------------------------------------------
------ state machine for managing sending and receiving usb data
--------------------------------------------------------------------------
process (usb_lock, clk_usb) is
begin
if (usb_lock = '0') then
joystick_type <= '0';
usb_reset <= '0';
data_available <= '0';
data_valid <= '0';
data_valid_temp <= '0';
start_sendcom <= '0';
counter1 <= "11111111";
counter2 <= "1000";
counter30ms <= "0101100110000100101";
counter1_3ms <= "100000100011011";
detach_ack <= '0';
usb_manage <= idle;
elsif (falling_edge(clk_usb)) then
case usb_manage is
-------------- idle state ----------------
when idle =>
set_command <= "00";
start_sendcom <= '0';
joystick_type <= '0';
mouse_valid <= '0';
if dplus = '1' then
usb_manage <= wait_for_deviceconnect;
else
usb_manage <= idle;
end if; --
-------------- confirm device connected ----------------
when wait_for_deviceconnect =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
usb_reset <= '1';
usb_manage <= usb_reset_state;
else
usb_manage <= wait_for_deviceconnect;
end if;
-------------- reset device state ----------------
when usb_reset_state =>
counter30ms <= counter30ms - 1;
if counter30ms = "0000000000000000000" then
counter30ms <= "1111111111111111111";
counter1_3ms <= "100000100011011";
counter2 <= "1011";
usb_reset <= '0';
detach_ack <= '1';
nb_reset <= "00011101"; -- 29 keep alive
usb_manage <= usb_reset_1ms_start;
else
usb_manage <= usb_reset_state;
end if;
-------------- usb_reset_1ms_start ----------------
when usb_reset_1ms_start =>
counter1_3ms <= counter1_3ms - 1;
if counter1_3ms = "0000000000000000" then
counter1_3ms <= "100000100011011";
counter2 <= "1011";
counter1_3ms <= counter1_3ms - 1;
detach_ack <= '0';
usb_reset <= '1';
usb_manage <= usb_reset_1ms_wait1;
else
usb_manage <= usb_reset_1ms_start;
end if;
-------------- usb_reset_1ms_start ----------------
when usb_reset_1ms_wait1 =>
usb_reset <= '1';
counter2 <= counter2 - '1';
if counter2 = "0000" then
usb_reset <= '0';
usb_manage <= usb_reset_1ms_release;
else
usb_manage <= usb_reset_1ms_wait1;
end if;
-------------- usb_reset_1ms_start ----------------
when usb_reset_1ms_release =>
usb_reset <= '0';
nb_reset <= nb_reset - 1;
if nb_reset = "00000000" then
usb_manage <= usb_manage2;
else
counter1_3ms <= "100000100011011";
counter2 <= "1011";
usb_manage <= usb_reset_1ms_start;
end if;
-------------- reset release state ----------------
when usb_wait30ms =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
detach_ack <= '0';
counter1 <= "11111111";
usb_manage <= usb_waitdetachrelease;
else
usb_manage <= usb_wait30ms;
end if;
-------------- confirm device attached ----------------
when usb_waitdetachrelease =>
counter2 <= counter2 - 1;
if counter2 = "0000" then
usb_manage <= usb_manage2;
else
usb_manage <= usb_waitdetachrelease;
end if;
-------------- end of reset state ----------------
when usb_manage2 =>
if detach = '1' then
usb_manage <= idle;
else
start_sendcom <= '0';
address_start <= "000010010";
usb_manage <= wait1; -- start set address
end if;
------------------------------------------------
-------------- SET ADDRESS 0x01 ----------------
------------------------------------------------
-------------- waiting state -------------------
when wait1 =>
counter2 <= counter2 - 1;
if counter2 = "0000" then
counter2 <= "1111";
usb_manage <= setaddress_sendpkt1;
else
usb_manage <= wait1;
end if;
-------------- send first packet "SETUP" packet ----------------
when setaddress_sendpkt1 =>
start_sendcom <= '1';
if set_command = "00" then
-- set address
address_start <= "000010010"; -- 0x12 - 0x2D 0x00 0x10 - 3 bytes
elsif set_command = "01" then
-- set configuration
address_start <= "001010000"; -- 0x50 - 0x2D 0x01 0xE8 - 3 bytes
else
-- set idle
address_start <= "001110000"; -- 0x70 - 0x2D 0x01 0xE8 - 3 bytes
end if;
usb_manage <= setaddress_sendpkt1_end; --
-------------- wait for completion of sending frame ----------------
when setaddress_sendpkt1_end =>
if detach = '1' then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1 <= "01010011";
usb_manage <= wait2;
else
usb_manage <= setaddress_sendpkt1_end;
end if;
end if;
--------------------- waiting state ----------------------
when wait2 =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
counter1 <= "01010011";
usb_manage <= setaddress_sendpkt2;
else
usb_manage <= wait2;
end if;
-------------- send the data packet for set address ---------
when setaddress_sendpkt2 =>
start_sendcom <= '1';
if set_command = "00" then
-- set address
address_start <= "000010111"; -- 0x17 - - 11 bytes
elsif set_command = "01" then
-- set configuration
address_start <= "001010101"; -- 0x55 - - 11 bytes
else
-- set idle
address_start <= "001110101"; -- 0x75 - - 11 bytes
end if;
usb_manage <= setaddress_sendpkt2_end; --
-------------- wait for completion of sending frame ----------------
when setaddress_sendpkt2_end =>
if detach = '1' then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1_3ms <= "100000100011011";
usb_manage <= wait_ack2;
else
usb_manage <= setaddress_sendpkt2_end;
end if;
end if;
-------------- waiting ACK ----------------
when wait_ack2 =>
if detach = '1' then
usb_manage <= idle;
else
counter1_3ms <= counter1_3ms - 1;
if data_pkt1 = "11010010" then
counter1_3ms <= "100000100011011";
usb_manage <= wait4; -- ack go top the next stage
elsif counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011"; -- no ack, retry sending the command
usb_manage <= setaddress_sendpkt1;
else
usb_manage <= wait_ack2;
end if;
end if;
---------------- waiting state ---------------------
when wait4 =>
counter2 <= counter2 - 1;
if counter2 = "0000" then
counter2 <= "1111";
usb_manage <= setaddress_sendpkt3;
else
usb_manage <= wait4;
end if;
-------------- prepare for sending the second packet ----------------
when setaddress_sendpkt3 =>
start_sendcom <= '1';
if set_command = "00" then
-- set address
address_start <= "000100100"; -- 0x24 - - 4 bytes
elsif set_command = "01" then
-- set configuration
address_start <= "001100010"; -- 0x62 - - 4 bytes
else
-- set idle
address_start <= "010000010"; -- 0x82 - - 4 bytes
end if;
usb_manage <= setaddress_sendpkt3_end; --
-------------- wait for completion of sending frame ----------------
when setaddress_sendpkt3_end =>
if detach = '1' then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1_3ms <= "100000100011011";
usb_manage <= wait_pktin1;
else
usb_manage <= setaddress_sendpkt3_end;
end if;
end if;
-------------- waiting for 1st byte ----------------
when wait_pktin1 =>
if detach = '1' then
usb_manage <= idle;
else
counter1_3ms <= counter1_3ms - 1;
if data_pkt1 = "10000000" then -- 0x80 wait for synch
usb_manage <= wait_pktin2; -- ack go to the next stage
elsif counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011"; -- no ack, retry sending the command
usb_manage <= setaddress_sendpkt3;
else
usb_manage <= wait_pktin1;
end if;
end if;
-------------- pktin2 "0x4B" -------------------------
when wait_pktin2 =>
if detach = '1' then
usb_manage <= idle;
else
if read_byte_valid = '0' then
usb_manage <= wait_pktin2;
else
usb_manage <= read_pktin2;
end if;
end if;
------------------ read_pktin2 "0x4B" ---------------------
when read_pktin2 =>
if detach = '1' then
usb_manage <= idle;
else
if data_pkt1 = "01001011" then -- 0x4B
usb_manage <= wait_pktin3; -- ack go top the next stage
else
usb_manage <= setaddress_sendpkt3; -- no ack, retry sending the command
end if;
end if;
-------------- pktin3 "0x00" -------------------------
when wait_pktin3 =>
if detach = '1' then
usb_manage <= idle;
else
if read_byte_valid = '1' then
usb_manage <= wait_pktin3;
else
usb_manage <= read_pktin3;
end if;
end if;
------------------ read_pktin3 "0x00" ---------------------
when read_pktin3 =>
if detach = '1' then
usb_manage <= idle;
else
if data_pkt1 = "00000000" then -- 0x00
usb_manage <= wait_pktin4; -- ack go top the next stage
else
usb_manage <= setaddress_sendpkt3; -- no ack, retry sending the command
end if;
end if;
-------------- pktin4 "0x00" -------------------------
when wait_pktin4 =>
if detach = '1' then
usb_manage <= idle;
else
if read_byte_valid = '0' then
usb_manage <= wait_pktin4;
else
usb_manage <= read_pktin4;
end if;
end if;
------------------ read_pktin4 "0x00" ---------------------
when read_pktin4 =>
if detach = '1' then
usb_manage <= idle;
else
if data_pkt1 = "00000000" then -- 0x00
counter1 <= "00001111";
usb_manage <= wait6; -- go to "send ack" state
else
usb_manage <= setaddress_sendpkt3; -- no ack, retry sending the command
end if;
end if;
-------------------- waiting state before sending ack --------------------------
when wait6 =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
counter1 <= "11111111";
usb_manage <= send_ack;
else
usb_manage <= wait6;
end if;
-------------- inialise ROM address for send ack ----------------
when send_ack =>
start_sendcom <= '1';
address_start <= "001000000"; -- 0x40 - - 2 bytes
usb_manage <= send_ack_end; -- send_ack_start; --
-------------- wait for completion of sending frame ----------------
when send_ack_end =>
if detach = '1' then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1_3ms <= "000000000000001";
if set_command = "00" then
usb_manage <= end_set_address;
elsif set_command = "01" then
usb_manage <= end_set_configuration;
else
usb_manage <= end_set_idle;
end if;
else
usb_manage <= send_ack_end;
end if;
end if;
------------------------------ End of Set Address -----------------------------
when end_set_address =>
counter1_3ms <= counter1_3ms - 1;
if counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011";
set_command <= "01"; -- set_command set to SetConfiguration
nb_reset <= "00000000"; -- 1 keep alive
usb_manage <= usb_reset_1ms_start;
else
usb_manage <= end_set_address;
end if;
when end_set_configuration =>
counter1_3ms <= counter1_3ms - 1;
if counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011";
set_command <= "10"; -- set_command set to SetConfiguration
nb_reset <= "00000000"; -- 1 keep alive
usb_manage <= usb_reset_1ms_start;
else
usb_manage <= end_set_configuration;
end if;

when end_set_idle =>
counter1_3ms <= counter1_3ms - 1;
if counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011";
counter1 <= "00011001";
set_command <= "00"; -- set_command set to Setaddress in case of a detach/attach
usb_manage <= wait21; -- wait20; -- go to get report
else
usb_manage <= end_set_idle;
end if;


---------------------------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
-------------- GET REPORT ----------------
when wait20 => -- wait 1.3ms * 9
counter1_3ms <= counter1_3ms - 1;
if counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011";
usb_manage <= wait21;
else
usb_manage <= wait20;
end if;
--------------------- wait -------------
when wait21 => --
counter1 <= counter1 - 1;
if counter1 = "00000000" then
data_available <= '0';
data_valid <= '0';
counter1_3ms <= "100000100011011";
usb_manage <= getreport_sendpkt1;
else
counter1_3ms <= "100000100011011";
usb_manage <= wait21;
end if;
-------------- read the next bytes to send ----------------
when getreport_sendpkt1 =>
start_sendcom <= '1';
address_start <= "010010000"; -- 0x90 - 0x69 0x81 0x58 - 3 bytes
usb_manage <= getreport_sendpkt1_end;
-------------- wait for completion of sending frame ----------------
when getreport_sendpkt1_end =>
if detach = '1' then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1 <= "00000111";
usb_manage <= wait30;
else
usb_manage <= getreport_sendpkt1_end;
end if;
end if;
------------- waiting state ------------------------
when wait30 =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
counter1 <= "11111111";
counter1_3ms <= "100000100011011";
usb_manage <= wait_report_start;
else
usb_manage <= wait30;
end if;
-------------- waiting ACK ----------------
when wait_report_start =>
if detach = '1' then
usb_manage <= idle;
else
counter1_3ms <= counter1_3ms - 1;
if data_pkt1 = "10000000" then -- wait for synch
counter1_3ms <= "100000100011011";
counter1 <= "01111000";
read_byte_valid_c <= read_byte_valid;
usb_manage <= start_get_data; -- ack go top the next stage
elsif counter1_3ms = "000000000000000" then
counter1_3ms <= "100000100011011"; -- no ack, retry sending the command
usb_manage <= getreport_sendpkt1;
else
usb_manage <= wait_report_start;
end if;
end if;
-------------- byte1 -------------------------
when start_get_data =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= start_get_data;
else
read_byte_valid_c <= read_byte_valid;
usb_manage <= read_byte1;
end if;
end if;
------------------ read_byte1 ---------------------
when read_byte1 =>
if (data_pkt1 = "01001011" or data_pkt1 = "11000011") then
data_valid_temp <= '1';
read_byte_valid_c <= read_byte_valid;
usb_manage <= wait_read_byte2;
counter1 <= "11111111";
else
counter1 <= "11111111";
usb_manage <= wait21;
end if;
-------------- byte2 -------------------------
when wait_read_byte2 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte2;
else
usb_manage <= read_byte2;
end if;
end if;
------------------ read_byte2 ---------------------
when read_byte2 =>
if joystick_type = '0' then
--joyleft_temp ( 1 downto 0) <= NOT ((NOT data_pkt1(6)) & data_pkt1(7)); -- game pad joystick
data_byte2 <= data_pkt1;
---
if (data_pkt1 = "01111111" OR data_pkt1 = "11111111" OR data_pkt1 = "00000000") then
data_valid_temp <= '1';
else
data_valid_temp <= '0';
end if;
else
-- data_valid_temp <= '1';
if (data_pkt1 = "10000000") then
joystick_updown <= '1'; -- either up or down
elsif (data_pkt1 = "00000000") then
joystick_updown <= '0'; -- left
joyright_temp(1 downto 0) <= "10";
elsif (data_pkt1 = "11111111") then
joystick_updown <= '0'; -- left
joyright_temp(1 downto 0) <= "01";
end if;
end if;

---
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte3;
-------------- byte3 -------------------------
when wait_read_byte3 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte3;
else
usb_manage <= read_byte3;
end if;
end if;
------------------ read_byte3 ---------------------
when read_byte3 =>
if joystick_type = '1' then
joyright_temp(3 downto 2) <= NOT (data_pkt1(0) & NOT data_pkt1(0));
else
--- not actif
if (data_byte2 = "01111111" AND data_pkt1 = "01111111") then
joyleft_temp(3 downto 0) <= "1111";
--- up right
elsif (data_byte2 = "11111111" AND data_pkt1 = "00000000") then
joyleft_temp(3 downto 0) <= "0110";
--- up left
elsif (data_byte2 = "00000000" AND data_pkt1 = "00000000") then
joyleft_temp(3 downto 0) <= "0101";
--- down right
elsif (data_byte2 = "11111111" AND data_pkt1 = "11111111") then
joyleft_temp(3 downto 0) <= "1010";
--- down left
elsif (data_byte2 = "00000000" AND data_pkt1 = "11111111") then
joyleft_temp(3 downto 0) <= "1001";
--- up
elsif (data_byte2 = "01111111" AND data_pkt1 = "00000000") then
joyleft_temp(3 downto 0) <= "0111";
--- down
elsif (data_byte2 = "01111111" AND data_pkt1 = "11111111") then
joyleft_temp(3 downto 0) <= "1011";
--- right
elsif (data_byte2 = "11111111" AND data_pkt1 = "01111111") then
joyleft_temp(3 downto 0) <= "1110";
--- left
elsif (data_byte2 = "00000000" AND data_pkt1 = "01111111") then
joyleft_temp(3 downto 0) <= "1101";
else
-- mouse detected,
mousex_temp <= data_byte2;
mousey_temp <= data_pkt1;
joyleft_temp(3 downto 0) <= "1111";
mouse_valid <= '1';
end if;
end if;
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte4;
-------------- byte4 -------------------------
when wait_read_byte4 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte4;
else
usb_manage <= read_byte4;
end if;
end if;
------------------ read_byte4 ---------------------
when read_byte4 =>
mouse_valid <= '0';
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte5;
-------------- byte5 -------------------------
when wait_read_byte5 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte5;
else
usb_manage <= read_byte5;
end if;
end if;
------------------ read_byte11 ---------------------
when read_byte5 =>
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte6;
-------------- byte6 -------------------------
when wait_read_byte6 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte6;
else
usb_manage <= read_byte6;
end if;
end if;
------------------ read_byte6 ---------------------
when read_byte6 =>
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte7; -- joystick type = gamepad
-------------- byte7 -------------------------
when wait_read_byte7 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte7;
else
usb_manage <= read_byte7;
end if;
end if;
------------------ read_byte7 ---------------------
when read_byte7 =>
if data_pkt1(3 downto 0) = "1111" then -- checking if data valid
joyright_temp(3 downto 0) <= NOT (data_pkt1(4) & data_pkt1(6) & data_pkt1(7) & data_pkt1(5));
else
data_valid_temp <= '0';
end if;
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte8;
-------------- byte8 -------------------------
when wait_read_byte8 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte8;
else
usb_manage <= read_byte8;
end if;
end if;
------------------ read_byte8 ---------------------
when read_byte8 =>
joyright_temp(7 downto 4) <= NOT (data_pkt1(1) & data_pkt1(3) & data_pkt1(5) & data_pkt1(5));
joyleft_temp(7 downto 4) <= NOT (data_pkt1(0) & data_pkt1(2) & data_pkt1(4) & data_pkt1(4));
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte9;
-------------- byte9 -------------------------
when wait_read_byte9 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte9;
else
usb_manage <= read_byte9;
end if;
end if;
------------------ read_byte9 ---------------------
when read_byte9 =>
--- test if analogue ON/OFF
if (data_pkt1 = "01000000") then
-- analogue ON
data_valid <= '0';
elsif (data_pkt1 = "00000000" OR data_pkt1 = "11000000") then
data_valid <= data_valid_temp;
else
data_valid <= '0';
end if;
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte10;
-------------- byte10 -------------------------
when wait_read_byte10 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte10;
else
usb_manage <= read_byte10;
end if;
end if;
------------------ read_byte10 ---------------------
when read_byte10 =>
read_byte_valid_c <= read_byte_valid;
counter1 <= "11111111";
usb_manage <= wait_read_byte11;
-------------- byte11 -------------------------
when wait_read_byte11 =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if read_byte_valid = read_byte_valid_c then
usb_manage <= wait_read_byte11;
else
usb_manage <= read_byte11;
end if;
end if;
------------------ read_byte11 ---------------------
when read_byte11 =>
counter1 <= "00001111";
usb_manage <= wait40;
----------------------------------------------------
------------ check CRC ---------------------------
----------------------------------------------------
------------- if valid data then issue an ack ----
when wait40 =>
counter1 <= counter1 - 1;
if counter1 = "00000000" then
counter1 <= "11111111";
usb_manage <= send_getreport_ack;
else
usb_manage <=wait40;
end if;
-------------- read the next bytes to send ----------
when send_getreport_ack =>
counter2 <= "1111";
start_sendcom <= '1';
address_start <= "001000000"; -- 0x40 - - 2 bytes
counter1 <= "11111111";
usb_manage <= send_getreport_ack_end;
-------------- wait for completion of sending frame ----------------
when send_getreport_ack_end =>
counter1 <= counter1 - 1;
if detach = '1' OR counter1 = "00000000" then
usb_manage <= idle;
else
if send_frame = '1' then
start_sendcom <= '0';
counter1_3ms <= "100000100011011";
counter2 <= "1111";
usb_manage <= crc_complete; --
else
usb_manage <= send_getreport_ack_end;
end if;
end if;
------------------------------ CRC check -----------------------------
when crc_complete =>
if detach = '1' then
usb_manage <= idle;
else
data_available <= '1';
usb_manage <= wait20;
end if;
when others =>
usb_manage <= idle;
end case;
end if;
end process;

--------------------------------------------------------------------------
------ detach detection process
--------------------------------------------------------------------------
process (
usb_lock,
CLOCK12MHz,
detach_ack,
counterdetach,
dplus_buf2,
dminus_buf2
) is
begin
if (usb_lock = '0') then
counterdetach <= "1111";
detach <= '0';
usb_detach <= idle;
elsif (falling_edge(CLOCK12MHz)) then
case usb_detach is
-------------- wait for the start trigger ----------------
when idle =>
if dplus_buf2 = '0' AND dminus_buf2 = '0' then
counterdetach <= "1111";
usb_detach <= detach_start;
else
usb_detach <= idle;
end if; --
-------------- read the rom first byte ----------------
when detach_start =>
if dplus_buf2 = '0' AND dminus_buf2 = '0' then
if counterdetach = "0000" then
usb_detach <= detach_valid;
else
usb_detach <= detach_start;
counterdetach <= counterdetach - 1;
end if;
else
counterdetach <= "1111";
usb_detach <= idle;
end if;
-------------- wait for 30ms ----------------
when detach_valid =>
detach <= '1';
usb_detach <= detach_wait;

-------------- wait for 30ms ----------------
when detach_wait =>
if detach_ack = '1' then
detach <= '0';
counterdetach <= "1111";
usb_detach <= idle;
else
usb_detach <= detach_wait;
end if;
when others =>
counterdetach <= "1111";
usb_detach <= idle;
end case;
end if;
end process;
------------------------------------------------------
------ state machine for the mouse
------------------------------------------------------
process (usb_lock, clk_usb, CLOCK12MHz) is
begin
if (usb_lock = '0') then
mouse_counter1 <= "000000000";
mousex_ctr <= "000000000000";
mousey_ctr <= "000000000000";
mouse_state <= idle;
elsif (rising_edge(CLOCK12MHz) AND mouse_valid = '1') then
case mouse_state is
-------------- xxxxxxxxxxxxxxxxxxxxxxxxxxx ----------------
when idle =>
if (mouse_counter1 = "000000000") then --
mouse_state <= state1; --
else
mouse_counter1 <= mouse_counter1 - 1;
mouse_state <= idle; --
end if;
-------------- xxxxxxxxxxxxxxxxxxxxxxxxxxx ----------------
when state1 =>
--
IF ((mousex_temp /= "10000000")) THEN
IF ((mousex_temp(7) = '1') OR (mousex_temp = "01111110")) THEN
-- move right
mousex_ctr <= mousex_ctr + ("00000000" & mousex_temp(7 downto 4));
ELSE
-- move left
mousex_ctr <= mousex_ctr - ("00000000" & NOT(mousex_temp(7 downto 4)));
END IF;
END IF;
IF (mousey_temp /= "10000000") THEN
IF ((mousey_temp(7) = '0')) THEN
--IF ((mousex_temp /= "01111110") AND (mousex_temp /= "11111110")) THEN
-- move up
mousey_ctr <= mousey_ctr + ("00000000" & NOT (mousey_temp(7 downto 4)));
--END IF;
ELSE
-- move down
mousey_ctr <= mousey_ctr - ("00000000" & mousey_temp(7 downto 4));
END IF;
END IF;
mousex_out <= mousex_ctr;
mousey_out <= mousey_ctr;
mouse_counter1 <= "000000111";
mouse_state <= idle;
when others =>
mouse_state <= idle;
end case;
end if;
end process;
------------------------------------------------------------
end arch;
(16-16/16)