Skip to content

Commit d1cb19c

Browse files
committed
wip checkin
1 parent 1a2e06b commit d1cb19c

File tree

1 file changed

+128
-24
lines changed

1 file changed

+128
-24
lines changed

src/main.rs

Lines changed: 128 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,100 @@ use usbd_hid::descriptor::generator_prelude::*;
3030
use usbd_hid::descriptor::MouseReport;
3131
use usbd_hid::hid_class::HIDClass;
3232

33+
#[gen_hid_descriptor(
34+
(collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = 0x05) = {
35+
// Button packet
36+
(collection = PHYSICAL, report_id = 0x20) = {
37+
(usage_page = GENERIC_DESKTOP, usage = 0x00) = {
38+
#[item_settings constant,variable,absolute] unknown=input;
39+
};
40+
(usage_page = GENERIC_DESKTOP, usage = 0x3b) = {
41+
#[item_settings data,variable,absolute] payload_size=input;
42+
};
43+
(usage_page = BUTTON, usage_min = 1, usage_max = 16) = {
44+
#[packed_bits 16] #[item_settings data,variable,absolute] buttons=input;
45+
};
46+
(usage_page = GENERIC_DESKTOP,) = {
47+
(usage = 0x33,) = {
48+
#[item_settings data,variable,absolute] rx=input;
49+
};
50+
(usage = 0x34,) = {
51+
#[item_settings data,variable,absolute] ry=input;
52+
};
53+
};
54+
(usage_page = GENERIC_DESKTOP, usage = POINTER,) = {
55+
(collection = PHYSICAL,) = {
56+
(usage_page = GENERIC_DESKTOP,) = {
57+
(usage = X,) = {
58+
#[item_settings data, variable, absolute] x=input;
59+
};
60+
(usage = Y,) = {
61+
#[item_settings data, variable, absolute] y=input;
62+
};
63+
};
64+
};
65+
};
66+
(usage_page = GENERIC_DESKTOP, usage = POINTER,) = {
67+
(collection = PHYSICAL,) = {
68+
(usage_page = GENERIC_DESKTOP,) = {
69+
(usage = Z,) = {
70+
#[item_settings data, variable, absolute] z=input;
71+
};
72+
(usage = 0x35,) = {
73+
#[item_settings data, variable, absolute] rz=input;
74+
};
75+
};
76+
};
77+
};
78+
};
79+
// Xbox button packet
80+
(collection = PHYSICAL, report_id = 0x07) = {
81+
(usage_page = GENERIC_DESKTOP,usage = 0x00) = {
82+
#[item_settings constant, variable, absolute] unknown2=input;
83+
};
84+
85+
(usage_page = GENERIC_DESKTOP, usage = 0x3b) = {
86+
#[item_settings constant, variable, absolute] payload_size2=input;
87+
};
88+
89+
(usage_page = BUTTON, usage = 0x10) = {
90+
#[packed_bits 1] #[item_settings data, variable, absolute] xbox_button=input;
91+
}
92+
};
93+
}
94+
)]
95+
struct GamepadReport {
96+
// Normal buttons
97+
unknown: [u8; 2],
98+
payload_size: u8,
99+
buttons: u16,
100+
rx: u16,
101+
ry: u16,
102+
x: i16,
103+
y: i16,
104+
z: i16,
105+
rz: i16,
106+
// Xbox button
107+
unknown2: [u8; 2],
108+
payload_size2: u8,
109+
xbox_button: u8,
110+
}
111+
112+
#[repr(C, packed)]
113+
struct GamepadReportButtons {
114+
report_id: u8,
115+
// Normal buttons
116+
unknown: [u8; 2],
117+
payload_size: u8,
118+
buttons: u16,
119+
rx: u16,
120+
ry: u16,
121+
x: i16,
122+
y: i16,
123+
z: i16,
124+
rz: i16,
125+
}
126+
33127
#[entry]
34128
fn main() -> ! {
35129
info!("Program start");
@@ -68,10 +162,10 @@ fn main() -> ! {
68162
};
69163

70164
// Set up the USB HID Class Device driver, providing Mouse Reports
71-
let usb_hid = HIDClass::new(bus_ref, MouseReport::desc(), 60);
165+
let usb_hid = HIDClass::new(bus_ref, GamepadReport::desc(), 60);
72166

73167
// Create a USB device with a fake VID and PID
74-
let usb_device = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x16c0, 0x27da))
168+
let usb_device = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x24c6, 0xfafe))
75169
.strings(&[StringDescriptors::default()
76170
.manufacturer("Fake company")
77171
.product("Twitchy Mousey")
@@ -93,42 +187,52 @@ fn main() -> ! {
93187
};
94188

95189
// Move the cursor up and down every 200ms
190+
let mut sequence = 0;
191+
let mut buttons = GamepadReportButtons {
192+
report_id: 0x20, // Button packet
193+
unknown: [0, sequence],
194+
payload_size: 0x0e, //core::mem::size_of::<GamepadReportButtons>() as u8,
195+
buttons: 0,
196+
rx: 0,
197+
ry: 0,
198+
x: 0,
199+
y: 0,
200+
z: 0,
201+
rz: 0,
202+
};
203+
96204
loop {
97205
delay.delay_ms(100);
98-
99-
let rep_up = MouseReport {
100-
x: 0,
101-
y: 4,
102-
buttons: 0,
103-
wheel: 0,
104-
pan: 0,
105-
};
106-
push_mouse_movement(rep_up).ok().unwrap_or(0);
206+
buttons.buttons = 0;
207+
buttons.unknown[1] = sequence;
208+
sequence += 1;
209+
push_movement(&buttons).ok().unwrap_or(0);
107210

108211
delay.delay_ms(100);
109212

110-
let rep_down = MouseReport {
111-
x: 0,
112-
y: -4,
113-
buttons: 0,
114-
wheel: 0,
115-
pan: 0,
116-
};
117-
push_mouse_movement(rep_down).ok().unwrap_or(0);
213+
buttons.buttons = 0xffff;
214+
buttons.unknown[1] = sequence;
215+
sequence += 1;
216+
push_movement(&buttons).ok().unwrap_or(0);
118217
}
119218
}
120219

220+
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
221+
core::slice::from_raw_parts((p as *const T) as *const u8, core::mem::size_of::<T>())
222+
}
223+
121224
/// Submit a new mouse movement report to the USB stack.
122225
///
123226
/// We do this with interrupts disabled, to avoid a race hazard with the USB IRQ.
124-
fn push_mouse_movement(report: MouseReport) -> Result<usize, usb_device::UsbError> {
227+
fn push_movement(report: &GamepadReportButtons) -> Result<usize, usb_device::UsbError> {
125228
critical_section::with(|token| {
126229
// Now interrupts are disabled, grab the global variable and, if
127230
// available, send it a HID report
128-
GADGET
129-
.borrow_ref_mut(token)
130-
.as_ref()
131-
.map(|gadget| gadget.usb_hid.push_input(&report))
231+
GADGET.borrow_ref_mut(token).as_ref().map(|gadget| {
232+
gadget
233+
.usb_hid
234+
.push_raw_input(unsafe { any_as_u8_slice(&report) })
235+
})
132236
})
133237
.unwrap()
134238
}

0 commit comments

Comments
 (0)