diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-02-18 11:55:21 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-02-18 15:30:39 +0100 |
commit | a954a23e52a28cda7af669303f5e9404641b3b6c (patch) | |
tree | 4ee189a1688eb873029f71b32290fe468013b8fb | |
parent | 8d9241e033e1babeccee49ab848c15edd8831516 (diff) | |
download | ntw-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.rs | 29 |
1 files changed, 21 insertions, 8 deletions
@@ -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) {} |