aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-02-18 11:55:21 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-02-18 15:30:39 +0100
commita954a23e52a28cda7af669303f5e9404641b3b6c (patch)
tree4ee189a1688eb873029f71b32290fe468013b8fb
parent8d9241e033e1babeccee49ab848c15edd8831516 (diff)
downloadntw-a954a23e52a28cda7af669303f5e9404641b3b6c.tar.gz
ntw-a954a23e52a28cda7af669303f5e9404641b3b6c.tar.bz2
hid: Add interrupt_in endpoint to HidClass
The HID standard requires an interrupt_in endpoint that can be used to send unrequested data from the device to the driver. This patch adds the interrupt_in endpoint, although there is no code that will ever write to it.
-rw-r--r--src/hid.rs29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/hid.rs b/src/hid.rs
index 6274e7f..9de68d6 100644
--- a/src/hid.rs
+++ b/src/hid.rs
@@ -1,12 +1,10 @@
// 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::endpoint::{EndpointAddress, EndpointIn};
use usb_device::Result;
const INTERFACE_CLASS_HID: u8 = 0x03;
@@ -30,9 +28,10 @@ enum_u8! {
pub struct HidClass<'a, B: UsbBus> {
interface: InterfaceNumber,
+ endpoint_interrupt_in: EndpointIn<'a, B>,
+ expect_interrupt_in_complete: bool,
subclass: Subclass,
protocol: Protocol,
- marker: PhantomData<&'a B>,
}
impl<B: UsbBus> HidClass<'_, B> {
@@ -43,9 +42,10 @@ impl<B: UsbBus> HidClass<'_, B> {
) -> HidClass<'_, B> {
HidClass {
interface: alloc.interface(),
+ endpoint_interrupt_in: alloc.interrupt(8, 10),
+ expect_interrupt_in_complete: false,
subclass,
protocol,
- marker: PhantomData,
}
}
}
@@ -53,7 +53,9 @@ impl<B: UsbBus> HidClass<'_, B> {
impl<B: UsbBus> UsbClass<B> for HidClass<'_, B> {
fn poll(&mut self) {}
- fn reset(&mut self) {}
+ fn reset(&mut self) {
+ self.expect_interrupt_in_complete = false;
+ }
fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
writer.interface(
@@ -61,14 +63,25 @@ impl<B: UsbBus> UsbClass<B> for HidClass<'_, B> {
INTERFACE_CLASS_HID,
self.subclass.into(),
self.protocol.into(),
- )
+ )?;
+ writer.endpoint(&self.endpoint_interrupt_in)?;
+
+ Ok(())
}
fn get_string(&self, _index: StringIndex, _lang_id: u16) -> Option<&str> {
None
}
- fn endpoint_in_complete(&mut self, _addr: EndpointAddress) {}
+ fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
+ if addr == self.endpoint_interrupt_in.address() {
+ if self.expect_interrupt_in_complete {
+ self.expect_interrupt_in_complete = false;
+ } else {
+ panic!("unexpected endpoint_in_complete");
+ }
+ }
+ }
fn endpoint_out(&mut self, _addr: EndpointAddress) {}