4 * PS2 Mouse to Mac interface module
6 module ps2_mouse(input sysclk,
18 output reg [15:0] debug
36 wire[1:0] dbg_lowstate;
38 ps2 ps20(.sysclk(sysclk),
48 .dbg_state(dbg_lowstate));
52 * - at state_init: wait for BAT reply
54 * * 0xfa -> send 0xff -> state_init
55 * * bad reply -> send 0xff -> state_init
56 * * timeout -> send 0xff -> state_init
58 * - at state_id: wait for device_id
59 * * 0x00 -> send 0xf4 -> state_setup
60 * * bad reply -> send 0xff -> state_init
61 * * timeout -> send 0xff -> state_init
63 * - at state_setup: wait for enable data reporting ack
64 * * 0xfa -> state_byte0
65 * * bad reply -> send 0xff -> state_init
66 * * timeout -> send 0xff -> state_init
68 * - at state_byte0: wait for data byte 0
69 * * data -> state_byte1
70 * * data -> state_byte1
71 * * timeout -> send 0xff -> state_init
73 * - at state_byte1: wait for data byte 1
74 * * data -> state_byte2
75 * * timeout -> send 0xff -> state_init
77 * - at state_byte2: wait for data byte 2
78 * * data -> state_byte0
79 * * timeout -> send 0xff -> state_init
81 localparam ps2m_state_init = 0;
82 localparam ps2m_state_id = 1;
83 localparam ps2m_state_setup = 2;
84 localparam ps2m_state_byte0 = 3;
85 localparam ps2m_state_byte1 = 4;
86 localparam ps2m_state_byte2 = 5;
88 /* Unlike my other modules, here I'll play with a big fat
89 * combo logic. The outputs are:
90 * - oreq : triggers sending of a byte. Set based on either
91 * timeout or istrobe, and as such only set for a
94 * - obyte : next byte to send
96 always@(timeout or state or istrobe or ibyte) begin
101 next = ps2m_state_init;
103 end else if (istrobe)
105 ps2m_state_init: begin
107 next = ps2m_state_id;
108 else if (ibyte != 8'hfa)
113 if (ibyte == 8'h00) begin
115 next = ps2m_state_setup;
117 next = ps2m_state_init;
119 ps2m_state_setup: begin
121 next = ps2m_state_byte0;
124 next = ps2m_state_init;
127 ps2m_state_byte0: next = ps2m_state_byte1;
128 ps2m_state_byte1: next = ps2m_state_byte2;
129 ps2m_state_byte2: next = ps2m_state_byte0;
133 /* State related latches. We latch oreq and obyte, we don't
134 * necessarily have to but that avoids back to back
135 * receive/send at the low level which can upset things
137 always@(posedge sysclk or posedge reset)
139 state <= ps2m_state_init;
142 always@(posedge sysclk or posedge reset)
147 always@(posedge sysclk or posedge reset)
153 /* Capture button state */
154 always@(posedge sysclk or posedge reset)
157 else if (istrobe && state == ps2m_state_byte0)
160 /* Clock divider to flush accumulators */
161 always@(posedge sysclk or posedge reset)
165 clkdiv <= clkdiv + 1;
166 assign tick = clkdiv == 0;
168 /* Toggle output lines base on accumulator */
169 always@(posedge sysclk or posedge reset) begin
173 end else if (tick && xacc != 0) begin
175 x2 <= ~x1 ^ ~xacc[9];
178 always@(posedge sysclk or posedge reset) begin
182 end else if (tick && yacc != 0) begin
184 y2 <= ~y1 ^ ~yacc[9];
188 /* Capture sign bits */
189 always@(posedge sysclk or posedge reset) begin
193 end else if (istrobe && state == ps2m_state_byte0) begin
199 /* Movement accumulators. Needs tuning ! */
200 always@(posedge sysclk or posedge reset) begin
204 /* Add movement, convert to a 10-bit number if not over */
205 if (istrobe && state == ps2m_state_byte1 && xacc[8] == xacc[9])
206 xacc <= xacc + { xsign, xsign, ibyte };
209 if (tick && xacc != 0)
210 xacc <= xacc + { {9{~xsign}}, 1'b1 };
214 always@(posedge sysclk or posedge reset) begin
218 /* Add movement, convert to a 10-bit number if not over*/
219 if (istrobe && state == ps2m_state_byte2 && yacc[8] == yacc[9])
220 yacc <= yacc + { ysign, ysign, ibyte };
223 if (tick && yacc != 0)
224 yacc <= yacc + { {9{~ysign}}, 1'b1 };
228 /* Some debug signals for my own sanity */
229 always@(posedge sysclk or posedge reset) begin
234 debug[15:8] <= ibyte;
235 debug[7:0] <= { ps2clk, ps2dat, dbg_lowstate, 1'b0,