From a954a23e52a28cda7af669303f5e9404641b3b6c Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 18 Feb 2019 11:55:21 +0000 Subject: 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. --- src/hid.rs | 29 +++++++++++++++++++++-------- 1 file 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 // 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 HidClass<'_, B> { @@ -43,9 +42,10 @@ impl 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 HidClass<'_, B> { impl UsbClass 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 UsbClass 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) {} -- cgit v1.2.1