📄 ps2_mouse_interface.v
字号:
m1_rising_edge :
begin
rising_edge <= 1;
m1_next_state <= m1_rising_wait;
end
m1_rising_wait :
begin
clean_clk <= 1;
if (debounce_timer_done) m1_next_state <= m1_clk_h;
else m1_next_state <= m1_rising_wait;
end
default : m1_next_state <= m1_clk_h;
endcase
end
// State register
always @(posedge clk)
begin : m2_state_register
if (reset) m2_state <= m2_reset;
else m2_state <= m2_next_state;
end
// State transition logic
always @(m2_state
or q
or falling_edge
or rising_edge
or watchdog_timer_done
or bit_count
or packet_good
or ps2_data
or clean_clk
)
begin : m2_state_logic
// Output signals default to this value, unless changed in a state condition.
ps2_clk_hi_z <= 1;
ps2_data_hi_z <= 1;
error_no_ack <= 0;
output_strobe <= 0;
case (m2_state)
m2_reset : // After reset, sends command to mouse.
begin
m2_next_state <= m2_hold_clk_l;
end
m2_wait :
begin
if (falling_edge) m2_next_state <= m2_gather;
else m2_next_state <= m2_wait;
end
m2_gather :
begin
if (watchdog_timer_done && (bit_count == `TOTAL_BITS))
m2_next_state <= m2_verify;
else if (watchdog_timer_done && (bit_count < `TOTAL_BITS))
m2_next_state <= m2_hold_clk_l;
else m2_next_state <= m2_gather;
end
m2_verify :
begin
if (packet_good) m2_next_state <= m2_use;
else m2_next_state <= m2_wait;
end
m2_use :
begin
output_strobe <= 1;
m2_next_state <= m2_wait;
end
// The following sequence of 9 states is designed to transmit the
// "enable streaming mode" command to the mouse, and then await the
// response from the mouse. Upon completion of this operation, the
// receive shift register contains 22 bits of data which are "invalid"
// therefore, the m2_verify state will fail to validate the data, and
// control will be passed into the m2_wait state once again (but the
// mouse will then be enabled, and valid data packets will ensue whenever
// there is activity on the mouse.)
m2_hold_clk_l :
begin
ps2_clk_hi_z <= 0; // This starts the watchdog timer!
if (watchdog_timer_done && ~clean_clk) m2_next_state <= m2_data_low_1;
else m2_next_state <= m2_hold_clk_l;
end
m2_data_low_1 :
begin
ps2_data_hi_z <= 0; // Forms start bit, d[0] and d[1]
if (rising_edge && (bit_count == 3))
m2_next_state <= m2_data_high_1;
else m2_next_state <= m2_data_low_1;
end
m2_data_high_1 :
begin
ps2_data_hi_z <= 1; // Forms d[2]
if (rising_edge && (bit_count == 4))
m2_next_state <= m2_data_low_2;
else m2_next_state <= m2_data_high_1;
end
m2_data_low_2 :
begin
ps2_data_hi_z <= 0; // Forms d[3]
if (rising_edge && (bit_count == 5))
m2_next_state <= m2_data_high_2;
else m2_next_state <= m2_data_low_2;
end
m2_data_high_2 :
begin
ps2_data_hi_z <= 1; // Forms d[4],d[5],d[6],d[7]
if (rising_edge && (bit_count == 9))
m2_next_state <= m2_data_low_3;
else m2_next_state <= m2_data_high_2;
end
m2_data_low_3 :
begin
ps2_data_hi_z <= 0; // Forms parity bit
if (rising_edge) m2_next_state <= m2_data_high_3;
else m2_next_state <= m2_data_low_3;
end
m2_data_high_3 :
begin
ps2_data_hi_z <= 1; // Allow mouse to pull low (ack pulse)
if (falling_edge && ps2_data) m2_next_state <= m2_error_no_ack;
else if (falling_edge && ~ps2_data)
m2_next_state <= m2_await_response;
else m2_next_state <= m2_data_high_3;
end
m2_error_no_ack :
begin
error_no_ack <= 1;
m2_next_state <= m2_error_no_ack;
end
// In order to "cleanly" exit the setting of the mouse into "streaming"
// data mode, the state machine should wait for a long enough time to
// ensure the FA response is done being sent by the mouse. Unfortunately,
// this is tough to figure out, since the watchdog timeout might be longer
// or shorter depending upon the user. If the watchdog timeout is set to
// a small enough value (less than about 560 usec?) then the bit_count
// will get reset to zero by the watchdog before the FA response is
// received. In that case, bit_count will be 11.
// If the bit_count is not reset by the watchdog, then the
// total bit_count will be 22.
// In either case, when this state is reached, the watchdog timer is still
// running and it is best to let it expire before returning to normal
// operation. One easy way to do this is to check for the bit_count to
// reach 22 (which it will always do when receiving a normal packet) and
// then jump to "verify" which will always fail for that time.
m2_await_response :
begin
if (bit_count == 22) m2_next_state <= m2_verify;
else m2_next_state <= m2_await_response;
end
default : m2_next_state <= m2_wait;
endcase
end
// State register
always @(posedge clk)
begin : m3_state_register
if (reset) m3_state <= m3_data_ready_ack;
else m3_state <= m3_next_state;
end
// State transition logic
always @(m3_state or output_strobe or read)
begin : m3_state_logic
case (m3_state)
m3_data_ready_ack:
begin
data_ready <= 1'b0;
if (output_strobe) m3_next_state <= m3_data_ready;
else m3_next_state <= m3_data_ready_ack;
end
m3_data_ready:
begin
data_ready <= 1'b1;
if (read) m3_next_state <= m3_data_ready_ack;
else m3_next_state <= m3_data_ready;
end
default : m3_next_state <= m3_data_ready_ack;
endcase
end
// This is the bit counter
always @(posedge clk)
begin
if (reset) bit_count <= 0; // normal reset
else if (falling_edge) bit_count <= bit_count + 1;
else if (watchdog_timer_done) bit_count <= 0; // rx watchdog timer reset
end
// This is the shift register
always @(posedge clk)
begin
if (reset) q <= 0;
else if (falling_edge) q <= {ps2_data,q[`TOTAL_BITS-1:1]};
end
// This is the watchdog timer counter
// The watchdog timer is always "enabled" to operate.
always @(posedge clk)
begin
if (reset || rising_edge || falling_edge) watchdog_timer_count <= 0;
else if (~watchdog_timer_done)
watchdog_timer_count <= watchdog_timer_count + 1;
end
assign watchdog_timer_done = (watchdog_timer_count==WATCHDOG_TIMER_VALUE_PP-1);
// This is the debounce timer counter
always @(posedge clk)
begin
if (reset || falling_edge || rising_edge) debounce_timer_count <= 0;
// else if (~debounce_timer_done)
else debounce_timer_count <= debounce_timer_count + 1;
end
assign debounce_timer_done = (debounce_timer_count==DEBOUNCE_TIMER_VALUE_PP-1);
// This is the logic to verify that a received data packet is "valid"
// or good.
assign packet_good = (
(q[0] == 0)
&& (q[10] == 1)
&& (q[11] == 0)
&& (q[21] == 1)
&& (q[22] == 0)
&& (q[32] == 1)
&& (q[9] == ~^q[8:1]) // odd parity bit
&& (q[20] == ~^q[19:12]) // odd parity bit
&& (q[31] == ~^q[30:23]) // odd parity bit
);
// Output the special scan code flags, the scan code and the ascii
always @(posedge clk)
begin
if (reset)
begin
left_button <= 0;
right_button <= 0;
x_increment <= 0;
y_increment <= 0;
end
else if (output_strobe)
begin
left_button <= q[1];
right_button <= q[2];
x_increment <= {q[5],q[19:12]};
y_increment <= {q[6],q[30:23]};
end
end
endmodule
//`undefine TOTAL_BITS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -