use crate::usb_class::prelude::*;
use core::default::Default;
use fugit::ExtU32;
use packed_struct::prelude::*;
use usb_device::bus::UsbBus;
use usb_device::class_prelude::UsbBusAllocator;
#[rustfmt::skip]
pub const BOOT_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
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, ];
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
#[packed_struct(endian = "lsb", size_bytes = "3")]
pub struct BootMouseReport {
#[packed_field]
pub buttons: u8,
#[packed_field]
pub x: i8,
#[packed_field]
pub y: i8,
}
#[rustfmt::skip]
pub const WHEEL_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
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, ];
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
#[packed_struct(endian = "lsb")]
pub struct WheelMouseReport {
#[packed_field]
pub buttons: u8,
#[packed_field]
pub x: i8,
#[packed_field]
pub y: i8,
#[packed_field]
pub vertical_wheel: i8,
#[packed_field]
pub horizontal_wheel: i8,
}
#[rustfmt::skip]
pub const ABSOLUTE_WHEEL_MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
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, ];
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
#[packed_struct(endian = "lsb")]
pub struct AbsoluteWheelMouseReport {
#[packed_field]
pub buttons: u8,
#[packed_field]
pub x: u16,
#[packed_field]
pub y: u16,
#[packed_field]
pub wheel: i8,
}
pub struct BootMouse<'a, B: UsbBus> {
interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
}
impl<B: UsbBus> BootMouse<'_, B> {
pub fn write_report(&mut self, report: &BootMouseReport) -> Result<(), UsbHidError> {
let data = report.pack().map_err(|_| {
error!("Error packing BootMouseReport");
UsbHidError::SerializationError
})?;
self.interface
.write_report(&data)
.map(|_| ())
.map_err(UsbHidError::from)
}
}
pub struct BootMouseConfig<'a> {
interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
}
impl<'a> BootMouseConfig<'a> {
#[must_use]
pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
Self { interface }
}
}
impl Default for BootMouseConfig<'_> {
fn default() -> Self {
Self::new(
unwrap!(unwrap!(InterfaceBuilder::new(BOOT_MOUSE_REPORT_DESCRIPTOR))
.boot_device(InterfaceProtocol::Mouse)
.description("Mouse")
.in_endpoint(10.millis()))
.without_out_endpoint()
.build(),
)
}
}
impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for BootMouseConfig<'a> {
type Allocated = BootMouse<'a, B>;
fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
BootMouse {
interface: self.interface.allocate(usb_alloc),
}
}
}
impl<'a, B: UsbBus> DeviceClass<'a> for BootMouse<'a, B> {
type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
fn interface(&mut self) -> &mut Self::I {
&mut self.interface
}
fn reset(&mut self) {}
fn tick(&mut self) -> Result<(), UsbHidError> {
Ok(())
}
}
pub struct WheelMouse<'a, B: UsbBus> {
interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
}
impl<B: UsbBus> WheelMouse<'_, B> {
pub fn write_report(&mut self, report: &WheelMouseReport) -> Result<(), UsbHidError> {
let data = report.pack().map_err(|_| {
error!("Error packing WheelMouseReport");
UsbHidError::SerializationError
})?;
self.interface
.write_report(&data)
.map(|_| ())
.map_err(UsbHidError::from)
}
}
pub struct WheelMouseConfig<'a> {
interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
}
impl<'a> WheelMouseConfig<'a> {
#[must_use]
pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
Self { interface }
}
}
impl Default for WheelMouseConfig<'_> {
fn default() -> Self {
WheelMouseConfig::new(
unwrap!(
unwrap!(InterfaceBuilder::new(WHEEL_MOUSE_REPORT_DESCRIPTOR))
.boot_device(InterfaceProtocol::Mouse)
.description("Wheel Mouse")
.in_endpoint(10.millis())
)
.without_out_endpoint()
.build(),
)
}
}
impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for WheelMouseConfig<'a> {
type Allocated = WheelMouse<'a, B>;
fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
WheelMouse {
interface: self.interface.allocate(usb_alloc),
}
}
}
impl<'a, B: UsbBus> DeviceClass<'a> for WheelMouse<'a, B> {
type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
fn interface(&mut self) -> &mut Self::I {
&mut self.interface
}
fn reset(&mut self) {}
fn tick(&mut self) -> Result<(), UsbHidError> {
Ok(())
}
}
pub struct AbsoluteWheelMouse<'a, B: UsbBus> {
interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>,
}
impl<B: UsbBus> AbsoluteWheelMouse<'_, B> {
pub fn write_report(&mut self, report: &AbsoluteWheelMouseReport) -> Result<(), UsbHidError> {
let data = report.pack().map_err(|_| {
error!("Error packing WheelMouseReport");
UsbHidError::SerializationError
})?;
self.interface
.write_report(&data)
.map(|_| ())
.map_err(UsbHidError::from)
}
}
pub struct AbsoluteWheelMouseConfig<'a> {
interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>,
}
impl<'a> AbsoluteWheelMouseConfig<'a> {
#[must_use]
pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self {
Self { interface }
}
}
impl Default for AbsoluteWheelMouseConfig<'_> {
fn default() -> Self {
AbsoluteWheelMouseConfig::new(
unwrap!(unwrap!(InterfaceBuilder::new(
ABSOLUTE_WHEEL_MOUSE_REPORT_DESCRIPTOR
))
.description("Absolute Wheel Mouse")
.in_endpoint(10.millis()))
.without_out_endpoint()
.build(),
)
}
}
impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for AbsoluteWheelMouseConfig<'a> {
type Allocated = AbsoluteWheelMouse<'a, B>;
fn allocate(self, usb_alloc: &'a UsbBusAllocator<B>) -> Self::Allocated {
AbsoluteWheelMouse {
interface: self.interface.allocate(usb_alloc),
}
}
}
impl<'a, B: UsbBus> DeviceClass<'a> for AbsoluteWheelMouse<'a, B> {
type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>;
fn interface(&mut self) -> &mut Self::I {
&mut self.interface
}
fn reset(&mut self) {}
fn tick(&mut self) -> Result<(), UsbHidError> {
Ok(())
}
}