feat(board): 板载 USB HID 口接 PS/2 鼠标,与板载按键并存
Nexys4DDR 的 USB HOST 口由板上芯片把 USB 键鼠转成 PS/2 信号(官方母版
Nexys4DDR_Master.xdc 标明 ps2_clk = F4、ps2_data = B2),所以不用写 USB 协议栈。
- cpu21_board_top.v:
* USE_PS2_MOUSE 默认打开;原来是 if/else 二选一(选鼠标就没按键),现在
cpu21_pointer 与 cpu21_ps2_mouse 同时例化,两路事件在顶层合并成 ev_valid/
ev_dx/ev_dy/ev_btn(同拍优先 PS/2),板载按键一个不删
* 新增 DEBUG_PS2_RX_LED(默认 1):把 PS/2 收到的字节数显示到 LED[15:3]
(LED[2:0] 仍是中断指示)。没有调试器时靠它判断 PS/2 到底有没有数据:
鼠标一动数字就跳 = 通了;一直是 0 = 根本没收到
- cpu21_board_top.xdc:ps2_clk/ps2_data 从 Pmod JA(C17/D18)改到板载 USB HID
(F4/B2),并在注释里留了改回 Pmod 的方法
软件侧不用改:鼠标事件与按键事件格式相同,且 PS/2 的 dx/dy 天然满足
"8 个计数 = 一格"(saolei.c 里就是 acc_x += dx; while (acc_x >= 8) 移动一格)。
额外好处:鼠标右键 = 插旗(handle_event 本来就支持)。
This commit is contained in:
@@ -53,7 +53,10 @@ module cpu21_board_top #(
|
||||
// 所以不会掩盖时序违例(约束偏严)。
|
||||
parameter integer CLK_DIV_INTRUPT = 32,
|
||||
// 鼠标事件源:0 = 板上 5 向按键(免外设,默认);1 = PS/2 鼠标(Pmod JA)
|
||||
parameter integer USE_PS2_MOUSE = 0,
|
||||
parameter integer USE_PS2_MOUSE = 1, // 1 = 启用板载 USB HID 口(PS/2 键鼠),板载按键同时有效
|
||||
// 调试:1 = 把 PS/2 收到的字节数显示在 LED[15:3](LED[2:0] 仍是中断指示)。
|
||||
// 验证 PS/2 通不通时打开:鼠标一动数字就跳;一直是 0 说明根本没收到 PS/2 数据。
|
||||
parameter integer DEBUG_PS2_RX_LED = 1,
|
||||
// 5 向按键去抖的采样周期(CPU 周期数):上板默认 50000(1 ms @50 MHz)。
|
||||
// 仿真里可以传一个小值,让"按一下"在几十微秒内就被识别。
|
||||
parameter integer POINTER_SAMPLE_DIV = 50000
|
||||
@@ -160,6 +163,7 @@ module cpu21_board_top #(
|
||||
wire [31:0] data_wdata;
|
||||
wire [ 3:0] data_wstrb;
|
||||
wire data_we;
|
||||
wire [15:0] ps2_rx_count; // PS/2 收到的字节数(用于 LED 调试显示)
|
||||
wire [31:0] led_data; // LED_ADDR 写入值,同时作为七段数码管显示数据
|
||||
wire led_valid;
|
||||
// 扫雷扩展外设的连线(先声明,例化在下面)
|
||||
@@ -337,7 +341,10 @@ module cpu21_board_top #(
|
||||
end
|
||||
end
|
||||
|
||||
assign led = {{13{1'b0}}, irq_led_q};
|
||||
// LED[15:3] 平时熄灭;DEBUG_PS2_RX_LED=1 时用它显示 PS/2 收到的字节数,
|
||||
// 便于在没有调试器的情况下判断"鼠标到底有没有数据进来"。
|
||||
assign led = (DEBUG_PS2_RX_LED != 0) ? {ps2_rx_count[12:0], irq_led_q}
|
||||
: {{13{1'b0}}, irq_led_q};
|
||||
|
||||
reg [23:0] led_we_cnt;
|
||||
|
||||
@@ -417,12 +424,34 @@ module cpu21_board_top #(
|
||||
.dp_o (dp)
|
||||
);
|
||||
|
||||
// ---- 鼠标事件源 ----
|
||||
// ---- 鼠标事件源:板载按键 与 PS/2 鼠标**同时**有效(两路事件在顶层合并) ----
|
||||
wire ev_valid;
|
||||
wire [7:0] ev_dx, ev_dy;
|
||||
wire [4:0] ev_btn;
|
||||
wire [4:0] btn_vec = {go, btnu, btnd, btnl, btnr}; // {BTNC, BTNU, BTND, BTNL, BTNR}
|
||||
|
||||
// 1) 板载按键:永远保留(BTNC 当左键、上下左右当移动、SW3 当插旗开关)
|
||||
wire ptr_valid;
|
||||
wire [7:0] ptr_dx, ptr_dy;
|
||||
wire [4:0] ptr_btn;
|
||||
|
||||
cpu21_pointer #(
|
||||
.SAMPLE_DIV(POINTER_SAMPLE_DIV)
|
||||
) u_ptr (
|
||||
.clk (clk_cpu),
|
||||
.reset (reset),
|
||||
.btn_i (btn_vec),
|
||||
.ev_valid_o(ptr_valid),
|
||||
.ev_dx_o (ptr_dx),
|
||||
.ev_dy_o (ptr_dy),
|
||||
.ev_btn_o (ptr_btn)
|
||||
);
|
||||
|
||||
// 2) PS/2 鼠标:板载 USB HID 口经板上芯片转成 PS/2 信号(ps2_clk/ps2_data)
|
||||
wire ps2_valid;
|
||||
wire [7:0] ps2_dx, ps2_dy;
|
||||
wire [4:0] ps2_btn;
|
||||
|
||||
generate
|
||||
if (USE_PS2_MOUSE != 0) begin : g_ps2
|
||||
cpu21_ps2_mouse u_ps2 (
|
||||
@@ -432,27 +461,27 @@ module cpu21_board_top #(
|
||||
.ps2_clk_oe_o (),
|
||||
.ps2_data_i (ps2_data),
|
||||
.ps2_data_oe_o(),
|
||||
.ev_valid_o (ev_valid),
|
||||
.ev_dx_o (ev_dx),
|
||||
.ev_dy_o (ev_dy),
|
||||
.ev_btn_o (ev_btn),
|
||||
.rx_count_o ()
|
||||
);
|
||||
end else begin : g_btn
|
||||
cpu21_pointer #(
|
||||
.SAMPLE_DIV(POINTER_SAMPLE_DIV)
|
||||
) u_ptr (
|
||||
.clk (clk_cpu),
|
||||
.reset (reset),
|
||||
.btn_i (btn_vec),
|
||||
.ev_valid_o(ev_valid),
|
||||
.ev_dx_o (ev_dx),
|
||||
.ev_dy_o (ev_dy),
|
||||
.ev_btn_o (ev_btn)
|
||||
.ev_valid_o (ps2_valid),
|
||||
.ev_dx_o (ps2_dx),
|
||||
.ev_dy_o (ps2_dy),
|
||||
.ev_btn_o (ps2_btn),
|
||||
.rx_count_o (ps2_rx_count)
|
||||
);
|
||||
end else begin : g_no_ps2
|
||||
assign ps2_valid = 1'b0;
|
||||
assign ps2_dx = 8'd0;
|
||||
assign ps2_dy = 8'd0;
|
||||
assign ps2_btn = 5'd0;
|
||||
assign ps2_rx_count = 16'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// 3) 合并:同一拍只有一方产生事件(两个源相互独立),优先 PS/2
|
||||
assign ev_valid = ps2_valid | ptr_valid;
|
||||
assign ev_dx = ps2_valid ? ps2_dx : ptr_dx;
|
||||
assign ev_dy = ps2_valid ? ps2_dy : ptr_dy;
|
||||
assign ev_btn = ps2_valid ? ps2_btn : ptr_btn;
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
||||
@@ -97,6 +97,9 @@ set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[
|
||||
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]
|
||||
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]
|
||||
|
||||
## PS/2 鼠标(可选:Pmod JA 插 Pmod PS2,顶层 USE_PS2_MOUSE=1)
|
||||
set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { ps2_clk }]
|
||||
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { ps2_data }]
|
||||
## PS/2 鼠标:接**板载 USB HID 口**(板上芯片把 USB 键鼠转成 PS/2)
|
||||
## Nexys4DDR_Master.xdc 里写明:ps2_clk = F4、ps2_data = B2
|
||||
## 顶层参数 USE_PS2_MOUSE=1 启用;板载按键仍然可用(两路事件在顶层合并)
|
||||
## 若改用 Pmod JA 上的 Pmod PS2,把下面两行的引脚换成 C17 / D18 即可
|
||||
set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { ps2_clk }]
|
||||
set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { ps2_data }]
|
||||
|
||||
Reference in New Issue
Block a user