Skip to content

Commit 26dd1fd

Browse files
committedAug 6, 2024
usb hid host support
1 parent 15b3f55 commit 26dd1fd

File tree

8 files changed

+193
-16
lines changed

8 files changed

+193
-16
lines changed
 

‎Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ RTL_PICO=rtl/sysctl_pico.v rtl/uart.v \
77
rtl/pll_ecp5.v \
88
rtl/cpu/picorv32/picorv32.v
99

10+
ifdef USB
11+
RTL_PICO += ext/usb_hid_host/src/usb_hid_host.v \
12+
ext/usb_hid_host/src/usb_hid_host_rom.v
13+
endif
14+
1015
BOARD_LC = $(shell echo '$(BOARD)' | tr '[:upper:]' '[:lower:]')
1116
BOARD_UC = $(shell echo '$(BOARD)' | tr '[:lower:]' '[:upper:]')
1217

‎README.md

+9
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ For example:
5757
make BOARD=eis flash
5858
```
5959

60+
### Enable USB HID Host Support
61+
62+
```
63+
$ cd ext
64+
$ git clone https://github.com/nand2mario/usb_hid_host
65+
$ cd ..
66+
$ make USB=1 BOARD=eis
67+
```
68+
6069
### Serial Console
6170

6271
The default configuration assumes that a UART PMOD is connected to PMODB (or PMODA if there's only one PMOD on the device).

‎boards/obst_v0.lpf

+10-7
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ LOCATE COMP "CLK_48" SITE "A7";
55
IOBUF PORT "CLK_48" IO_TYPE=LVCMOS33;
66
FREQUENCY PORT "CLK_48" 48.0 MHz;
77

8-
# SELTSAM on USB1
9-
#LOCATE COMP "UART0_RX" SITE "B1"; # USB1DP -> SELTSAM -> CH340N RX
10-
#IOBUF PORT "UART0_RX" IO_TYPE=LVCMOS33;
11-
#IOBUF PORT "UART0_RX" PULLMODE=NONE;
12-
#LOCATE COMP "UART0_TX" SITE "B2"; # USB1DN <- SELTSAM <- CH340N TX
13-
#IOBUF PORT "UART0_TX" IO_TYPE=LVCMOS33;
14-
#IOBUF PORT "UART0_TX" PULLMODE=NONE;
8+
# USB HOST
9+
LOCATE COMP "USBH0_DP" SITE "B1";
10+
IOBUF PORT "USBH0_DP" IO_TYPE=LVCMOS33;
11+
LOCATE COMP "USBH0_DN" SITE "B2";
12+
IOBUF PORT "USBH0_DN" IO_TYPE=LVCMOS33;
13+
14+
LOCATE COMP "USBH1_DP" SITE "C1";
15+
IOBUF PORT "USBH1_DP" IO_TYPE=LVCMOS33;
16+
LOCATE COMP "USBH1_DN" SITE "C2";
17+
IOBUF PORT "USBH1_DN" IO_TYPE=LVCMOS33;
1518

1619
# PMOD A (USB-UART)
1720
LOCATE COMP "UART0_RTS" SITE "E5";

‎firmware/firmware.c

+38-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
#define reg_sd (*(volatile uint8_t*)0xf0002000)
1818
#define reg_ps2_data (*(volatile uint8_t*)0xf0003000)
1919
#define reg_ps2_ctrl (*(volatile uint8_t*)0xf0003004)
20+
21+
#define reg_uhh_info (*(volatile uint32_t*)0xf0004000)
22+
#define reg_uhh_keys (*(volatile uint32_t*)0xf0004004)
23+
#define reg_uhh_mouse (*(volatile uint32_t*)0xf0004008)
24+
2025
#define reg_gamepad_l (*(volatile uint32_t*)0xf0005000)
2126
#define reg_gamepad_r (*(volatile uint32_t*)0xf0005004)
2227
#define reg_delay_us (*(volatile uint32_t*)0xf0006000)
@@ -36,6 +41,8 @@
3641
#define PS2_CTRL_BUSY 0x02
3742
#define PS2_CTRL_DR 0x01
3843

44+
#define UHH_INFO_DR 0x80000000
45+
3946
#define SD_MISO 0x01
4047
#define SD_MOSI 0x02
4148
#define SD_SCK 0x04
@@ -58,6 +65,7 @@
5865
#define LIX_SIZE 262144
5966

6067
#include "scancodes.h"
68+
#include "hidcodes.h"
6169

6270
uint16_t curs_x = 0;
6371
uint16_t curs_y = 0;
@@ -71,6 +79,7 @@ uint32_t xfer_recv(uint32_t addr);
7179
uint32_t crc32b(char *data, uint32_t len);
7280
void putchar_vga(const char c);
7381
char scantoascii(uint8_t scancode);
82+
char hidtoascii(uint8_t code);
7483

7584
void sd_init(void);
7685
void sd_spi_xfer(uint8_t b);
@@ -130,14 +139,21 @@ int getchar()
130139
{
131140
int uart_dr = ((reg_uart_ctrl & UART_CTRL_DR) == UART_CTRL_DR);
132141
int kbd_dr = ((reg_ps2_ctrl & PS2_CTRL_DR) == PS2_CTRL_DR);
142+
int uhh_dr = ((reg_uhh_info & UHH_INFO_DR) == UHH_INFO_DR);
133143
char c;
134144

135-
if (!uart_dr && !kbd_dr) {
145+
if (!uart_dr && !kbd_dr && !uhh_dr) {
136146
return EOF;
137147
} else {
138148
if (kbd_dr) {
139149
c = scantoascii(reg_ps2_data);
140150
if (c) return c; else return EOF;
151+
} else if (uhh_dr) {
152+
uint32_t keys = reg_uhh_keys;
153+
uint8_t key = (keys >> 24) & 0xff;
154+
if (!key) return EOF;
155+
uint8_t c = hidtoascii(key);
156+
if (c) return c; else return EOF;
141157
} else {
142158
return reg_uart_data;
143159
}
@@ -169,6 +185,15 @@ char scantoascii(uint8_t scancode) {
169185

170186
};
171187

188+
char hidtoascii(uint8_t scancode) {
189+
190+
for (int i = 0; i < sizeof(hid_codes); i++) {
191+
if (hid_codes[i] == scancode) return i + 0x30;
192+
}
193+
return 0;
194+
195+
};
196+
172197
uint32_t xfer_recv(uint32_t addr_ptr)
173198
{
174199

@@ -354,6 +379,18 @@ void cmd_info() {
354379
print_hex(tmp, 2);
355380
print(" ");
356381

382+
print("uhh info: 0x");
383+
print_hex(reg_uhh_info, 8);
384+
print(" ");
385+
386+
print("uhh keys: 0x");
387+
print_hex(reg_uhh_keys, 8);
388+
print(" ");
389+
390+
print("uhh mouse: 0x");
391+
print_hex(reg_uhh_mouse, 8);
392+
print("\n");
393+
357394
print("uptime: 0x");
358395
tmp32 = reg_rtc;
359396
print_hex(tmp32, 8);

‎firmware/hidcodes.h

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
uint8_t hid_codes[] = {
2+
3+
// usage id key
4+
0x27, // 0
5+
0x1e, // 1
6+
0x1f, // 2
7+
0x20, // 3
8+
0x21, // 4
9+
0x22, // 5
10+
0x23, // 6
11+
0x24, // 7
12+
0x25, // 8
13+
0x27, // 9
14+
15+
0x00,
16+
0x00,
17+
0x00,
18+
0x00,
19+
0x00,
20+
0x00,
21+
0x00,
22+
23+
0x04, // a
24+
0x05, // b
25+
0x06, // c
26+
0x07, // d
27+
0x08, // e
28+
0x09, // f
29+
0x0a, // g
30+
0x0b, // h
31+
0x0c, // i
32+
0x0d, // j
33+
0x0e, // k
34+
0x0f, // l
35+
0x10, // m
36+
0x11, // n
37+
0x12, // o
38+
0x13, // p
39+
0x14, // q
40+
0x15, // r
41+
0x16, // s
42+
0x17, // t
43+
0x18, // u
44+
0x19, // v
45+
0x1a, // w
46+
0x1b, // x
47+
0x1c, // y
48+
0x1d, // z
49+
50+
};

‎rtl/boards.vh

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@
209209
`define EN_VIDEO
210210
`define EN_VIDEO_VGA
211211
`define EN_QQSPI
212+
`define EN_USB_HID_HOST
212213

213214
`elsif LAKRITZ
214215

‎rtl/pll_ecp5.v

+13-6
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ module pll0
44
(
55
input clkin, // 48 MHz, 0 deg
66
output clkout0, // 100 MHz, 0 deg
7-
output clkout2, // 75 MHz, 0 deg
8-
output clkout3, // 50 MHz, 0 deg
7+
output clkout1, // 75 MHz, 0 deg
8+
output clkout2, // 50 MHz, 0 deg
9+
output clkout3, // 12 MHz, 0 deg
910
output locked
1011
);
1112
(* FREQUENCY_PIN_CLKI="48" *)
1213
(* FREQUENCY_PIN_CLKOP="100" *)
13-
(* FREQUENCY_PIN_CLKOS2="75" *)
14-
(* FREQUENCY_PIN_CLKOS3="50" *)
14+
(* FREQUENCY_PIN_CLKOS="75" *)
15+
(* FREQUENCY_PIN_CLKOS2="50" *)
16+
(* FREQUENCY_PIN_CLKOS3="12" *)
1517
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
1618
EHXPLLL #(
1719
.PLLRST_ENA("DISABLED"),
@@ -27,12 +29,16 @@ EHXPLLL #(
2729
.CLKOP_DIV(6),
2830
.CLKOP_CPHASE(2),
2931
.CLKOP_FPHASE(0),
32+
.CLKOS_ENABLE("ENABLED"),
33+
.CLKOS_DIV(8),
34+
.CLKOS_CPHASE(2),
35+
.CLKOS_FPHASE(0),
3036
.CLKOS2_ENABLE("ENABLED"),
31-
.CLKOS2_DIV(8),
37+
.CLKOS2_DIV(12),
3238
.CLKOS2_CPHASE(2),
3339
.CLKOS2_FPHASE(0),
3440
.CLKOS3_ENABLE("ENABLED"),
35-
.CLKOS3_DIV(12),
41+
.CLKOS3_DIV(50),
3642
.CLKOS3_CPHASE(2),
3743
.CLKOS3_FPHASE(0),
3844
.FEEDBK_PATH("CLKOP"),
@@ -42,6 +48,7 @@ EHXPLLL #(
4248
.STDBY(1'b0),
4349
.CLKI(clkin),
4450
.CLKOP(clkout0),
51+
.CLKOS(clkout1),
4552
.CLKOS2(clkout2),
4653
.CLKOS3(clkout3),
4754
.CLKFB(clkout0),

‎rtl/sysctl_pico.v

+67-2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,13 @@ module sysctl #()
255255
input RP_HOLD,
256256
`endif
257257

258+
`ifdef EN_USB_HID_HOST
259+
inout USBH0_DP,
260+
inout USBH0_DN,
261+
//inout USBH1_DP,
262+
//inout USBH1_DN,
263+
`endif
264+
258265
);
259266

260267
reg [31:0] reg_cfg_sys = (SYSCLK / 1_000_000);
@@ -264,6 +271,7 @@ module sysctl #()
264271

265272
wire clk;
266273

274+
wire clk12mhz;
267275
wire clk25mhz;
268276
wire clk50mhz;
269277
wire clk75mhz;
@@ -484,8 +492,9 @@ module sysctl #()
484492
pll0 #() ecp5_pll0 (
485493
.clkin(CLK_48),
486494
.clkout0(clk100mhz),
487-
.clkout2(clk75mhz),
488-
.clkout3(clk50mhz),
495+
.clkout1(clk75mhz),
496+
.clkout2(clk50mhz),
497+
.clkout3(clk12mhz),
489498
);
490499
pll1 #() ecp5_pll1 (
491500
.clkin(clk100mhz),
@@ -594,6 +603,27 @@ module sysctl #()
594603
);
595604
`endif
596605

606+
`ifdef EN_USB_HID_HOST
607+
608+
reg uhh_dr;
609+
wire uhh_usb_report;
610+
wire [1:0] uhh_usb_type;
611+
wire [7:0] uhh_key_modifiers, uhh_key1, uhh_key2, uhh_key3, uhh_key4;
612+
wire [7:0] uhh_mouse_btn;
613+
wire signed [7:0] uhh_mouse_dx, uhh_mouse_dy;
614+
615+
usb_hid_host usb (
616+
.usbclk(clk12mhz), .usbrst_n(resetn),
617+
.usb_dm(USBH0_DN), .usb_dp(USBH0_DP),
618+
.typ(uhh_usb_type), .report(uhh_usb_report),
619+
.key_modifiers(uhh_key_modifiers),
620+
.key1(uhh_key1), .key2(uhh_key2), .key3(uhh_key3), .key4(uhh_key4),
621+
.mouse_btn(uhh_mouse_btn),
622+
.mouse_dx(uhh_mouse_dx), .mouse_dy(uhh_mouse_dy),
623+
);
624+
625+
`endif
626+
597627
`ifdef EN_RPINT
598628
wire [31:0] rpint_rdata;
599629
wire [1:0] rpint_reg;
@@ -1344,6 +1374,10 @@ module sysctl #()
13441374
ps2_rstrb <= 0;
13451375
`endif
13461376

1377+
`ifdef EN_USB_HID_HOST
1378+
if (!uhh_dr) uhh_dr <= uhh_usb_report;
1379+
`endif
1380+
13471381
uart0_transmit <= 0;
13481382

13491383
`ifdef EN_GPU_FB
@@ -1654,6 +1688,10 @@ module sysctl #()
16541688
gpu_blit_ctr <= 0;
16551689
`endif
16561690

1691+
`ifdef EN_USB_HID_HOST
1692+
uhh_dr <= 0;
1693+
`endif
1694+
16571695
end else if (mem_valid && !mem_ready) begin
16581696

16591697
(* parallel_case *)
@@ -2177,6 +2215,33 @@ module sysctl #()
21772215

21782216
`endif
21792217

2218+
`ifdef EN_USB_HID_HOST
2219+
16'h4000: begin
2220+
if (!mem_wstrb) begin
2221+
mem_rdata <= { uhh_dr, 5'b0, uhh_usb_type,
2222+
16'b0,
2223+
uhh_key_modifiers };
2224+
end
2225+
mem_ready <= 1;
2226+
end
2227+
2228+
16'h4004: begin
2229+
if (!mem_wstrb) begin
2230+
mem_rdata <= { uhh_key1, uhh_key2, uhh_key3, uhh_key4 };
2231+
end
2232+
uhh_dr <= 0;
2233+
mem_ready <= 1;
2234+
end
2235+
2236+
16'h4008: begin
2237+
if (!mem_wstrb) begin
2238+
mem_rdata <= { 8'b0, uhh_mouse_btn,
2239+
uhh_mouse_dx, uhh_mouse_dy };
2240+
end
2241+
mem_ready <= 1;
2242+
end
2243+
`endif
2244+
21802245
`ifdef EN_RPINT
21812246
16'h5000: begin
21822247
if (!mem_wstrb) begin

0 commit comments

Comments
 (0)
Please sign in to comment.