aboutsummaryrefslogtreecommitdiff
path: root/src/hid.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/hid.rs')
-rw-r--r--src/hid.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/hid.rs b/src/hid.rs
new file mode 100644
index 0000000..4f1d506
--- /dev/null
+++ b/src/hid.rs
@@ -0,0 +1,88 @@
+// Copyright 2019 Robin Krahl <robin.krahl@ireas.org>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+use core::marker::PhantomData;
+
+use usb_device::bus::{InterfaceNumber, StringIndex, UsbBus, UsbBusAllocator};
+use usb_device::class::{ControlIn, ControlOut, UsbClass};
+use usb_device::descriptor::DescriptorWriter;
+use usb_device::endpoint::EndpointAddress;
+use usb_device::Result;
+
+const INTERFACE_CLASS_HID: u8 = 0x03;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(u8)]
+pub enum Subclass {
+ None = 0x00,
+ BootInterface = 0x01,
+}
+
+impl From<Subclass> for u8 {
+ fn from(subclass: Subclass) -> u8 {
+ subclass as u8
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(u8)]
+pub enum Protocol {
+ None = 0x00,
+ Keyboard = 0x01,
+ Mouse = 0x02,
+}
+
+impl From<Protocol> for u8 {
+ fn from(protocol: Protocol) -> u8 {
+ protocol as u8
+ }
+}
+
+pub struct HidClass<'a, B: UsbBus> {
+ interface: InterfaceNumber,
+ subclass: Subclass,
+ protocol: Protocol,
+ marker: PhantomData<&'a B>,
+}
+
+impl<B: UsbBus> HidClass<'_, B> {
+ pub fn new(
+ alloc: &UsbBusAllocator<B>,
+ subclass: Subclass,
+ protocol: Protocol,
+ ) -> HidClass<'_, B> {
+ HidClass {
+ interface: alloc.interface(),
+ subclass,
+ protocol,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<B: UsbBus> UsbClass<B> for HidClass<'_, B> {
+ fn poll(&mut self) {}
+
+ fn reset(&mut self) {}
+
+ fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
+ writer.interface(
+ self.interface,
+ INTERFACE_CLASS_HID,
+ self.subclass.into(),
+ self.protocol.into(),
+ )
+ }
+
+ fn get_string(&self, _index: StringIndex, _lang_id: u16) -> Option<&str> {
+ None
+ }
+
+ fn endpoint_in_complete(&mut self, _addr: EndpointAddress) {}
+
+ fn endpoint_out(&mut self, _addr: EndpointAddress) {}
+
+ fn control_in(&mut self, _xfer: ControlIn<B>) {}
+
+ fn control_out(&mut self, _xfer: ControlOut<B>) {}
+}