📄 mousectrl.vhd
字号:
when reset_send_sample_rate_100 =>
tx_data <= "01100100"; -- 0x64
write <= '1';
state <= reset_send_sample_rate_100_wait_ack;
-- wait ack for sending the sample rate
when reset_send_sample_rate_100_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_set_sample_rate_80;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_send_sample_rate_100_wait_ack;
end if;
-- send set sample rate command
when reset_set_sample_rate_80 =>
tx_data <= SET_SAMPLE_RATE;
write <= '1';
state <= reset_set_sample_rate_80_wait_ack;
-- wait ack for sending the sample rate command
when reset_set_sample_rate_80_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_send_sample_rate_80;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_set_sample_rate_80_wait_ack;
end if;
-- send desired sample rate (80 = 0x50)
when reset_send_sample_rate_80 =>
tx_data <= "01010000"; -- 0x50
write <= '1';
state <= reset_send_sample_rate_80_wait_ack;
-- wait ack for sending the sample rate
when reset_send_sample_rate_80_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_read_id;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_send_sample_rate_80_wait_ack;
end if;
-- now the procedure for enabling wheel mode is done
-- the mouse id is read to determine is mouse is in
-- wheel mode.
-- Read ID command is sent to the mouse.
when reset_read_id =>
tx_data <= READ_ID;
write <= '1';
state <= reset_read_id_wait_ack;
-- wait ack for sending the read id command
when reset_read_id_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_read_id_wait_id;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_read_id_wait_ack;
end if;
-- received the mouse id
-- if the id is 00, then the mouse does not have
-- a wheel and haswheel is reset
-- if the id is 03, then the mouse is in scroll mode
-- and haswheel is set.
-- if anything else is received or an error occurred
-- then the FSM transitions to reset state.
when reset_read_id_wait_id =>
if(read = '1') then
if(rx_data = "000000000") then
-- the mouse does not have a wheel
haswheel <= '0';
state <= reset_set_resolution;
elsif(rx_data = "00000011") then -- 0x03
-- the mouse is in scroll mode
haswheel <= '1';
state <= reset_set_resolution;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_read_id_wait_id;
end if;
-- send the set resolution command to the mouse
when reset_set_resolution =>
tx_data <= SET_RESOLUTION;
write <= '1';
state <= reset_set_resolution_wait_ack;
-- wait ack for sending the set resolution command
when reset_set_resolution_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_send_resolution;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_set_resolution_wait_ack;
end if;
-- send the desired resolution (0x03 = 8 counts/mm)
when reset_send_resolution =>
tx_data <= RESOLUTION;
write <= '1';
state <= reset_send_resolution_wait_ack;
-- wait ack for sending the resolution
when reset_send_resolution_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_set_sample_rate_40;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_send_resolution_wait_ack;
end if;
-- send the set sample rate command
when reset_set_sample_rate_40 =>
tx_data <= SET_SAMPLE_RATE;
write <= '1';
state <= reset_set_sample_rate_40_wait_ack;
-- wait ack for sending the set sample rate command
when reset_set_sample_rate_40_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_send_sample_rate_40;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_set_sample_rate_40_wait_ack;
end if;
-- send the desired sampele rate.
-- 40 samples per second is sent.
when reset_send_sample_rate_40 =>
tx_data <= SAMPLE_RATE;
write <= '1';
state <= reset_send_sample_rate_40_wait_ack;
-- wait ack for sending the sample rate
when reset_send_sample_rate_40_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= reset_enable_reporting;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_send_sample_rate_40_wait_ack;
end if;
-- in this state enable reporting command is sent
-- to the mouse. Before this point, the mouse
-- does not send packets. Only after issuing this
-- command, the mouse begins sending data packets,
-- 3 byte packets if it doesn't have a wheel and
-- 4 byte packets if it is in scroll mode.
when reset_enable_reporting =>
tx_data <= ENABLE_REPORTING;
write <= '1';
state <= reset_enable_reporting_wait_ack;
-- wait ack for sending the enable reporting command
when reset_enable_reporting_wait_ack =>
if(read = '1') then
if(rx_data = FA) then
state <= read_byte_1;
else
state <= reset;
end if;
elsif(err = '1') then
state <= reset;
else
state <= reset_enable_reporting_wait_ack;
end if;
-- this is idle state of the FSM after the
-- initialization is complete.
-- Here the first byte of a packet is waited.
-- The first byte contains the state of the
-- buttons, the sign of the x and y movement
-- and overflow information about these movements
-- First byte looks like this:
-- 7 6 5 4 3 2 1 0
------------------------------------------------------
-- | Y OVF | X OVF | Y SIGN | X SIGN | 1 | M | R | L |
------------------------------------------------------
when read_byte_1 =>
-- reset new_event when back in idle state.
new_event <= '0';
-- reset last z delta movement
zpos <= (others => '0');
if(read = '1') then
-- mouse button states
left_down <= rx_data(0);
middle_down <= rx_data(2);
right_down <= rx_data(1);
-- sign of the movement data
x_sign <= rx_data(4);
-- y sign is changed to invert the y axis
-- because the mouse uses the lower-left corner
-- as axes origin and it is placed in the upper-left
-- corner by this inversion (suitable for displaying
-- a mouse cursor on the screen).
-- y movement data from the third packet must be
-- also negated.
y_sign <= not rx_data(5);
-- overflow status of the x and y movement
x_overflow <= rx_data(6);
y_overflow <= rx_data(7);
-- transition to state read_byte_2
state <= read_byte_2;
else
-- no byte received yet.
state <= read_byte_1;
end if;
-- wait the second byte of the packet
-- this byte contains the x movement counter.
when read_byte_2 =>
if(read = '1') then
-- put the delta movement in x_inc
x_inc <= rx_data;
-- signal the arrival of new x movement data.
x_new <= '1';
-- go to state read_byte_3.
state <= read_byte_3;
elsif(err = '1') then
state <= reset;
else
-- byte not received yet.
state <= read_byte_2;
end if;
-- wait the third byte of the data, that
-- contains the y data movement counter.
-- negate its value, for the axis to be
-- inverted.
-- If mouse is in scroll mode, transition
-- to read_byte_4, else go to mark_new_event
when read_byte_3 =>
if(read = '1') then
-- when y movement is 0, then ignore
if(rx_data /= "00000000") then
-- 2's complement positive numbers
-- become negative and vice versa
y_inc <= (not rx_data) + "00000001";
y_new <= '1';
end if;
-- if the mouse has a wheel then transition
-- to read_byte_4, else go to mark_new_event
if(haswheel = '1') then
state <= read_byte_4;
else
state <= mark_new_event;
end if;
elsif(err = '1') then
state <= reset;
else
state <= read_byte_3;
end if;
-- only reached when mouse is in scroll mode
-- wait for the fourth byte to arrive
-- fourth byte contains the z movement counter
-- only least significant 4 bits are relevant
-- the rest are sign extension.
when read_byte_4 =>
if(read = '1') then
-- zpos is the delta movement on z
zpos <= rx_data(3 downto 0);
-- packet completly received,
-- go to mark_new_event
state <= mark_new_event;
elsif(err = '1') then
state <= reset;
else
state <= read_byte_4;
end if;
-- set new_event high
-- it will be reset in next state
-- informs client new packet received and processed
when mark_new_event =>
new_event <= '1';
state <= read_byte_1;
-- if invalid transition occurred, reset
when others =>
state <= reset;
end case;
end if;
end process manage_fsm;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -