1use crate::usb_class::prelude::*;
3use core::default::Default;
4use fugit::ExtU32;
5use packed_struct::prelude::*;
6use usb_device::bus::UsbBus;
7use usb_device::class_prelude::UsbBusAllocator;
8
9#[rustfmt::skip]
16pub const BOOT_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
17 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x95, 0x03, 0x75, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01, 0x75, 0x08, 0x95, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x81, 0x06, 0xC0, 0xC0, ];
44
45#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
47#[packed_struct(endian = "lsb", size_bytes = "3")]
48pub struct BootMouseReport {
49 #[packed_field]
50 pub buttons: u8,
51 #[packed_field]
52 pub x: i8,
53 #[packed_field]
54 pub y: i8,
55}
56
57#[rustfmt::skip]
61pub const WHEEL_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
62 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x95, 0x08, 0x75, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, 0x00, 0x25, 0x01, 0x81, 0x02, 0x75, 0x08, 0x95, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x81, 0x06, 0x15, 0x81, 0x25, 0x7F, 0x09, 0x38, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C, 0x0A, 0x38, 0x02, 0x95, 0x01, 0x81, 0x06, 0xC0, 0xC0, ];
98
99#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
100#[packed_struct(endian = "lsb")]
101pub struct WheelMouseReport {
102 #[packed_field]
103 pub buttons: u8,
104 #[packed_field]
105 pub x: i8,
106 #[packed_field]
107 pub y: i8,
108 #[packed_field]
109 pub vertical_wheel: i8,
110 #[packed_field]
111 pub horizontal_wheel: i8,
112}
113
114#[rustfmt::skip]
123pub const ABSOLUTE_WHEEL_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
124 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x26, 0xFF, 0x7F, 0x35, 0x00, 0x46, 0xFF, 0x7F, 0x95, 0x02, 0x75, 0x10, 0x81, 0x02, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F, 0x35, 0x81, 0x45, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0xC0, 0xC0, ];
162
163#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
164#[packed_struct(endian = "lsb")]
165pub struct AbsoluteWheelMouseReport {
166 #[packed_field]
167 pub buttons: u8,
168 #[packed_field]
169 pub x: u16,
170 #[packed_field]
171 pub y: u16,
172 #[packed_field]
173 pub wheel: i8,
174}
175
176pub struct BootMouse<'a, B: UsbBus> {
177 interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
178}
179
180impl<B: UsbBus> BootMouse<'_, B> {
181 pub fn write_report(&mut self, report: &BootMouseReport) -> Result<(), UsbHidError> {
182 let data = report.pack().map_err(|_| {
183 error!("Error packing BootMouseReport");
184 UsbHidError::SerializationError
185 })?;
186 self.interface
187 .write_report(&data)
188 .map(|_| ())
189 .map_err(UsbHidError::from)
190 }
191}
192
193pub struct BootMouseConfig<'a> {
194 interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
195}
196
197impl<'a> BootMouseConfig<'a> {
198 #[must_use]
199 pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
200 Self { interface }
201 }
202}
203
204impl Default for BootMouseConfig<'_> {
205 fn default() -> Self {
206 Self::new(
207 unwrap!(unwrap!(InterfaceBuilder::new(BOOT_MOUSE_REPORT_DESCRIPTOR))
208 .boot_device(InterfaceProtocol::Mouse)
209 .description("Mouse")
210 .in_endpoint(10.millis()))
211 .without_out_endpoint()
212 .build(),
213 )
214 }
215}
216
217impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for BootMouseConfig<'a> {
218 type Allocated = BootMouse<'a, B>;
219
220 fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
221 BootMouse {
222 interface: self.interface.allocate(usb_alloc),
223 }
224 }
225}
226
227impl<'a, B: UsbBus> DeviceClass<'a> for BootMouse<'a, B> {
228 type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
229
230 fn interface(&mut self) -> &mut Self::I {
231 &mut self.interface
232 }
233
234 fn reset(&mut self) {}
235
236 fn tick(&mut self) -> Result<(), UsbHidError> {
237 Ok(())
238 }
239}
240
241pub struct WheelMouse<'a, B: UsbBus> {
242 interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
243}
244
245impl<B: UsbBus> WheelMouse<'_, B> {
246 pub fn write_report(&mut self, report: &WheelMouseReport) -> Result<(), UsbHidError> {
247 let data = report.pack().map_err(|_| {
248 error!("Error packing WheelMouseReport");
249 UsbHidError::SerializationError
250 })?;
251 self.interface
252 .write_report(&data)
253 .map(|_| ())
254 .map_err(UsbHidError::from)
255 }
256}
257pub struct WheelMouseConfig<'a> {
258 interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
259}
260
261impl<'a> WheelMouseConfig<'a> {
262 #[must_use]
263 pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
264 Self { interface }
265 }
266}
267
268impl Default for WheelMouseConfig<'_> {
269 fn default() -> Self {
270 WheelMouseConfig::new(
271 unwrap!(
272 unwrap!(InterfaceBuilder::new(WHEEL_MOUSE_REPORT_DESCRIPTOR))
273 .boot_device(InterfaceProtocol::Mouse)
274 .description("Wheel Mouse")
275 .in_endpoint(10.millis())
276 )
277 .without_out_endpoint()
278 .build(),
279 )
280 }
281}
282
283impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for WheelMouseConfig<'a> {
284 type Allocated = WheelMouse<'a, B>;
285
286 fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
287 WheelMouse {
288 interface: self.interface.allocate(usb_alloc),
289 }
290 }
291}
292
293impl<'a, B: UsbBus> DeviceClass<'a> for WheelMouse<'a, B> {
294 type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
295
296 fn interface(&mut self) -> &mut Self::I {
297 &mut self.interface
298 }
299
300 fn reset(&mut self) {}
301
302 fn tick(&mut self) -> Result<(), UsbHidError> {
303 Ok(())
304 }
305}
306
307pub struct AbsoluteWheelMouse<'a, B: UsbBus> {
308 interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
309}
310
311impl<B: UsbBus> AbsoluteWheelMouse<'_, B> {
312 pub fn write_report(&mut self, report: &AbsoluteWheelMouseReport) -> Result<(), UsbHidError> {
313 let data = report.pack().map_err(|_| {
314 error!("Error packing WheelMouseReport");
315 UsbHidError::SerializationError
316 })?;
317 self.interface
318 .write_report(&data)
319 .map(|_| ())
320 .map_err(UsbHidError::from)
321 }
322}
323
324pub struct AbsoluteWheelMouseConfig<'a> {
325 interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
326}
327
328impl<'a> AbsoluteWheelMouseConfig<'a> {
329 #[must_use]
330 pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
331 Self { interface }
332 }
333}
334
335impl Default for AbsoluteWheelMouseConfig<'_> {
336 fn default() -> Self {
337 AbsoluteWheelMouseConfig::new(
338 unwrap!(unwrap!(InterfaceBuilder::new(
339 ABSOLUTE_WHEEL_MOUSE_REPORT_DESCRIPTOR
340 ))
341 .description("Absolute Wheel Mouse")
342 .in_endpoint(10.millis()))
343 .without_out_endpoint()
344 .build(),
345 )
346 }
347}
348
349impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for AbsoluteWheelMouseConfig<'a> {
350 type Allocated = AbsoluteWheelMouse<'a, B>;
351
352 fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
353 AbsoluteWheelMouse {
354 interface: self.interface.allocate(usb_alloc),
355 }
356 }
357}
358
359impl<'a, B: UsbBus> DeviceClass<'a> for AbsoluteWheelMouse<'a, B> {
360 type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
361
362 fn interface(&mut self) -> &mut Self::I {
363 &mut self.interface
364 }
365
366 fn reset(&mut self) {}
367
368 fn tick(&mut self) -> Result<(), UsbHidError> {
369 Ok(())
370 }
371}