OpenCores
URL https://opencores.org/ocsvn/aoocs/aoocs/trunk

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [terasic_de2_70/] [drv_mouse.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file
26
 * \brief PS/2 mouse driver.
27
 */
28
 
29
/*! \brief \copybrief drv_mouse.v
30
*/
31
module drv_mouse(
32
    //% \name Clock and reset
33
    //% @{
34
    input           clk_30,
35
    input           reset_n,
36
    //% @}
37
 
38
    //% \name drv_keyboard interface
39
    //% @{
40
    output reg      mouse_moved,
41
    output [8:0]    mouse_y_move,
42
    output [8:0]    mouse_x_move,
43
    output          mouse_left_button,
44
    output          mouse_right_button,
45
    output          mouse_middle_button,
46
    //% @}
47
 
48
    //% \name PS/2 mouse hardware interface
49
    //% @{
50
    inout           ps2_mouseclk,
51
    inout           ps2_mousedat
52
    //% @}
53
);
54
assign ps2_mouseclk = (send_counter >= 12'd1 && send_counter < 12'd4000) ? 1'b0 : 1'bZ;
55
assign ps2_mousedat = (send_counter >= 12'd4000 && send_counter <= 12'd4009) ? send_shift[0] : 1'bZ;
56
 
57
reg [15:0] mv;
58
reg mv_wait;
59
reg was_ps2_mouseclk;
60
always @(posedge clk_30 or negedge reset_n) begin
61
    if(reset_n == 1'b0) begin
62
        mv                  <= 16'd0;
63
        mv_wait             <= 1'b0;
64
        was_ps2_mouseclk    <= 1'b0;
65
    end
66
    else begin
67
        mv <= { mv[14:0], ps2_mouseclk };
68
 
69
        if(mv_wait == 1'b0 && mv[15:12] == 4'b1111 && mv[3:0] == 4'b0000) begin
70
            was_ps2_mouseclk <= 1'b1;
71
            mv_wait <= 1'b1;
72
        end
73
        else if(mv_wait == 1'b1 && mv[15:0] == 16'h0000) begin
74
            mv_wait <= 1'b0;
75
            was_ps2_mouseclk <= 1'b0;
76
        end
77
        else begin
78
            was_ps2_mouseclk <= 1'b0;
79
        end
80
    end
81
end
82
 
83
reg [11:0] send_counter;
84
reg [9:0] send_shift;
85
always @(posedge clk_30 or negedge reset_n) begin
86
    if(reset_n == 1'b0) begin
87
        send_counter    <= 12'd0;
88
        send_shift      <= 10'd0;
89
    end
90
    else if(send_start == 1'b1) begin
91
        send_counter <= 12'd1;
92
        send_shift <= send_contents;
93
    end
94
    else if(send_counter > 12'd0 && send_counter < 12'd4000) begin
95
        send_counter <= send_counter + 12'd1;
96
    end
97
    else if(send_counter >= 12'd4000 && send_counter <= 12'd4009 && was_ps2_mouseclk == 1'b1) begin
98
        send_counter <= send_counter + 12'd1;
99
        if(send_counter <= 12'd4007) begin
100
            send_shift <= { send_shift[9] ^ send_shift[0], 1'b0, send_shift[8:1] };
101
        end
102
        else if(send_counter == 12'd4008) begin
103
            send_shift <= { 9'd0, send_shift[9] ^ send_shift[0] };
104
        end
105
    end
106
    else if(send_counter == 12'd4010 && was_ps2_mouseclk == 1'b1) begin
107
        if(ps2_mousedat == 1'b0) send_counter <= send_counter + 12'd1;
108
    end
109
    else if(send_counter == 12'd4011 && ps2_mouseclk == 1'b1 && ps2_mousedat == 1'b1) begin
110
        send_counter <= 12'd0;
111
    end
112
end
113
 
114
reg send_start;
115
reg [9:0] send_contents;
116
reg [23:0] ctrl_counter;
117
always @(posedge clk_30 or negedge reset_n) begin
118
    if(reset_n == 1'b0) begin
119
        send_start      <= 1'b0;
120
        send_contents   <= 10'd0;
121
        ctrl_counter    <= 24'd0;
122
    end
123
    else if(ctrl_counter < 24'hFFFFF0) begin
124
        ctrl_counter <= ctrl_counter + 16'd1;
125
    end
126
    else if(ctrl_counter == 24'hFFFFF0) begin
127
        send_contents <= { 1'b1, 8'hF4, 1'b0 };
128
        send_start <= 1'b1;
129
        ctrl_counter <= ctrl_counter + 24'd1;
130
    end
131
    else if(ctrl_counter == 24'hFFFFF1) begin
132
        send_start <= 1'b0;
133
        ctrl_counter <= ctrl_counter + 24'd1;
134
    end
135
    else if(ctrl_counter == 24'hFFFFF2 && send_counter == 12'd0) begin
136
        ctrl_counter <= ctrl_counter + 24'd1;
137
    end
138
    else if(ctrl_counter == 24'hFFFFF3 && new_ps2 == 1'b1 && mousedat[8:1] == 8'hFA) begin
139
        ctrl_counter <= 24'hFFFFFF;
140
    end
141
    else if(ctrl_counter == 24'hFFFFFF && (mousedat_timeout == 24'hFFFFFF || movement_timeout == 24'hFFFFFF)) begin
142
        ctrl_counter <= 24'h0;
143
    end
144
end
145
 
146
wire new_ps2;
147
assign new_ps2 = (was_ps2_mouseclk == 1'b1 && mousedat_counter == 4'd10 && mousedat[0] == 1'b0 && ps2_mousedat == 1'b1 && mousedat_parity == 1'b1);
148
 
149
reg [9:0] mousedat;
150
reg [3:0] mousedat_counter;
151
reg [23:0] mousedat_timeout;
152
reg mousedat_parity;
153
 
154
always @(posedge clk_30 or negedge reset_n) begin
155
    if(reset_n == 1'b0) begin
156
        mousedat            <= 10'd0;
157
        mousedat_counter    <= 4'd0;
158
        mousedat_parity     <= 1'b0;
159
        mousedat_timeout    <= 24'd0;
160
    end
161
    else if(ctrl_counter >= 24'hFFFFF3 && mousedat_timeout != 24'hFFFFFF) begin
162
 
163
        if(mousedat_counter != 4'd0)        mousedat_timeout <= mousedat_timeout + 24'd1;
164
        else if(mousedat_counter == 4'd0)   mousedat_timeout <= 24'd0;
165
 
166
        if(was_ps2_mouseclk == 1'b1) begin
167
            mousedat <= { ps2_mousedat, mousedat[9:1] };
168
 
169
            if(mousedat_counter == 4'd10) begin
170
                mousedat_counter <= 4'd0;
171
            end
172
            else begin
173
                mousedat_counter <= mousedat_counter + 4'd1;
174
                if(mousedat_counter == 4'd0)   mousedat_parity <= 1'b0;
175
                else if(ps2_mousedat == 1'b1)  mousedat_parity <= ~mousedat_parity;
176
            end
177
        end
178
    end
179
    else begin
180
        mousedat            <= 10'd0;
181
        mousedat_counter    <= 4'd0;
182
        mousedat_parity     <= 1'b0;
183
        mousedat_timeout    <= 24'd0;
184
    end
185
end
186
 
187
assign mouse_y_move = (movement[23] == 1'b0)? { movement[21], movement[7:0] }  : 9'd0;
188
assign mouse_x_move = (movement[22] == 1'b0)? { movement[20], movement[15:8] }  : 9'd0;
189
assign mouse_left_button    = movement[16];
190
assign mouse_right_button   = movement[17];
191
assign mouse_middle_button  = movement[18];
192
 
193
reg [1:0] movement_counter;
194
reg [23:0] movement;
195
reg [23:0] movement_timeout;
196
 
197
always @(posedge clk_30 or negedge reset_n) begin
198
    if(reset_n == 1'b0) begin
199
        movement_counter    <= 2'd0;
200
        movement            <= 24'd0;
201
        mouse_moved         <= 1'b0;
202
        movement_timeout    <= 24'd0;
203
    end
204
    else if(ctrl_counter == 24'hFFFFFF && movement_timeout != 24'hFFFFFF) begin
205
 
206
        if(movement_counter != 4'd0)        movement_timeout <= movement_timeout + 24'd1;
207
        else if(movement_counter == 4'd0)   movement_timeout <= 24'd0;
208
 
209
        if(mouse_moved == 1'b1) mouse_moved <= 1'b0;
210
 
211
        if(new_ps2 == 1'b1) begin
212
            movement <= { movement[15:0], mousedat[8:1] };
213
            if(movement_counter == 2'd2) begin
214
                movement_counter <= 2'd0;
215
 
216
                if(movement[11] == 1'b1)    mouse_moved <= 1'b1;
217
                else                        movement_timeout <= 24'hFFFFFF;
218
            end
219
            else movement_counter <= movement_counter + 2'd1;
220
        end
221
    end
222
    else begin
223
        movement_counter    <= 2'd0;
224
        movement            <= 24'd0;
225
        mouse_moved         <= 1'b0;
226
        movement_timeout    <= 24'd0;
227
    end
228
end
229
 
230
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.