From 6e013152be9d1128bb705f35e29d60183819e69d Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 6 Aug 2021 04:37:05 -0700 Subject: [PATCH] generic interval --- Cargo.toml | 3 +++ src/bus.rs | 28 ++++++++++++++++++++-------- src/control_pipe.rs | 10 +++++----- src/descriptor.rs | 13 ++++++++++--- src/device.rs | 21 +++++++++++---------- src/endpoint.rs | 12 +++++++----- src/lib.rs | 4 +++- src/test_class.rs | 9 ++++++--- 8 files changed, 65 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d582a0f..02d4a71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,9 @@ license = "MIT" authors = ["Matti Virkkunen "] repository = "https://github.com/mvirkkunen/usb-device" +[dependencies] +embedded-time = "0.12.0" + [dev-dependencies] rusb = "0.8.0" rand = "0.6.1" diff --git a/src/bus.rs b/src/bus.rs index cd176d3..e47e9e2 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,3 +1,5 @@ +use embedded_time::duration::{Extensions, Generic}; + use crate::endpoint::{Endpoint, EndpointAddress, EndpointDirection, EndpointType}; use crate::{Result, UsbDirection, UsbError}; use core::cell::RefCell; @@ -41,7 +43,7 @@ pub trait UsbBus: Sync + Sized { ep_addr: Option, ep_type: EndpointType, max_packet_size: u16, - interval: u8, + interval: Generic, ) -> Result; /// Enables and initializes the USB peripheral. Soon after enabling the device will be reset, so @@ -211,12 +213,12 @@ impl UsbBusAllocator { /// /// This directly delegates to [`UsbBus::alloc_ep`], so see that method for details. In most /// cases classes should call the endpoint type specific methods instead. - pub fn alloc<'a, D: EndpointDirection>( + pub fn alloc( &self, ep_addr: Option, ep_type: EndpointType, max_packet_size: u16, - interval: u8, + interval: Generic, ) -> Result> { self.bus .borrow_mut() @@ -240,8 +242,13 @@ impl UsbBusAllocator { /// feasibly recoverable. #[inline] pub fn control(&self, max_packet_size: u16) -> Endpoint<'_, B, D> { - self.alloc(None, EndpointType::Control, max_packet_size, 0) - .expect("alloc_ep failed") + self.alloc( + None, + EndpointType::Control, + max_packet_size, + 0u32.milliseconds().into(), + ) + .expect("alloc_ep failed") } /// Allocates a bulk endpoint. @@ -256,8 +263,13 @@ impl UsbBusAllocator { /// feasibly recoverable. #[inline] pub fn bulk(&self, max_packet_size: u16) -> Endpoint<'_, B, D> { - self.alloc(None, EndpointType::Bulk, max_packet_size, 0) - .expect("alloc_ep failed") + self.alloc( + None, + EndpointType::Bulk, + max_packet_size, + 0u32.milliseconds().into(), + ) + .expect("alloc_ep failed") } /// Allocates an interrupt endpoint. @@ -272,7 +284,7 @@ impl UsbBusAllocator { pub fn interrupt( &self, max_packet_size: u16, - interval: u8, + interval: Generic, ) -> Endpoint<'_, B, D> { self.alloc(None, EndpointType::Interrupt, max_packet_size, interval) .expect("alloc_ep failed") diff --git a/src/control_pipe.rs b/src/control_pipe.rs index a38a0df..1c5b6b2 100644 --- a/src/control_pipe.rs +++ b/src/control_pipe.rs @@ -65,7 +65,7 @@ impl ControlPipe<'_, B> { self.state = ControlState::Idle; } - pub fn handle_setup<'p>(&'p mut self) -> Option { + pub fn handle_setup(&mut self) -> Option { let count = match self.ep_out.read(&mut self.buf[..]) { Ok(count) => count, Err(UsbError::WouldBlock) => return None, @@ -122,10 +122,10 @@ impl ControlPipe<'_, B> { return Some(req); } - return None; + None } - pub fn handle_out<'p>(&'p mut self) -> Option { + pub fn handle_out(&mut self) -> Option { match self.state { ControlState::DataOut(req) => { let i = self.i; @@ -160,7 +160,7 @@ impl ControlPipe<'_, B> { } } - return None; + None } pub fn handle_in_complete(&mut self) -> bool { @@ -191,7 +191,7 @@ impl ControlPipe<'_, B> { } }; - return false; + false } fn write_in_chunk(&mut self) { diff --git a/src/descriptor.rs b/src/descriptor.rs index c622222..fe877e3 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -1,3 +1,8 @@ +use core::convert::TryFrom; + +use embedded_time::duration::Milliseconds; +use embedded_time::fixed_point::FixedPoint; + use crate::bus::{InterfaceNumber, StringIndex, UsbBus}; use crate::device; use crate::endpoint::{Endpoint, EndpointDirection}; @@ -278,8 +283,10 @@ impl DescriptorWriter<'_> { endpoint.address().into(), // bEndpointAddress endpoint.ep_type() as u8, // bmAttributes mps as u8, - (mps >> 8) as u8, // wMaxPacketSize - endpoint.interval(), // bInterval + (mps >> 8) as u8, // wMaxPacketSize + Milliseconds::::try_from(endpoint.interval()) + .unwrap() + .integer() as u8, // bInterval ], )?; @@ -325,7 +332,7 @@ pub struct BosWriter<'w, 'a: 'w> { impl<'w, 'a: 'w> BosWriter<'w, 'a> { pub(crate) fn new(writer: &'w mut DescriptorWriter<'a>) -> Self { Self { - writer: writer, + writer, num_caps_mark: None, } } diff --git a/src/device.rs b/src/device.rs index defc49c..bebbf06 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,3 +1,5 @@ +use embedded_time::duration::*; + use crate::bus::{PollResult, StringIndex, UsbBus, UsbBusAllocator}; use crate::class::{ControlIn, ControlOut, UsbClass}; use crate::control; @@ -75,7 +77,7 @@ impl UsbDevice<'_, B> { Some(0x00.into()), EndpointType::Control, config.max_packet_size_0 as u16, - 0, + 0.milliseconds().into(), ) .expect("failed to alloc control endpoint"); @@ -84,7 +86,7 @@ impl UsbDevice<'_, B> { Some(0x80.into()), EndpointType::Control, config.max_packet_size_0 as u16, - 0, + 0.milliseconds().into(), ) .expect("failed to alloc control endpoint"); @@ -193,14 +195,13 @@ impl UsbDevice<'_, B> { if (ep_in_complete & 1) != 0 { let completed = self.control.handle_in_complete(); - if !B::QUIRK_SET_ADDRESS_BEFORE_STATUS { - if completed && self.pending_address != 0 { - self.bus.set_device_address(self.pending_address); - self.pending_address = 0; + if !B::QUIRK_SET_ADDRESS_BEFORE_STATUS && ( completed && self.pending_address != 0 ) { + self.bus.set_device_address(self.pending_address); + self.pending_address = 0; - self.device_state = UsbDeviceState::Addressed; - } + self.device_state = UsbDeviceState::Addressed; } + } let req = if (ep_setup & 1) != 0 { @@ -275,7 +276,7 @@ impl UsbDevice<'_, B> { } } - return false; + false } fn control_in(&mut self, classes: &mut ClassList<'_, B>, req: control::Request) { @@ -508,7 +509,7 @@ impl UsbDevice<'_, B> { classes .iter() .filter_map(|cls| cls.get_string(index, lang_id)) - .nth(0) + .next() } }; diff --git a/src/endpoint.rs b/src/endpoint.rs index 520bccb..4d47682 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -1,3 +1,5 @@ +use embedded_time::duration::Generic; + use crate::bus::UsbBus; use crate::{Result, UsbDirection}; use core::marker::PhantomData; @@ -53,17 +55,17 @@ pub struct Endpoint<'a, B: UsbBus, D: EndpointDirection> { address: EndpointAddress, ep_type: EndpointType, max_packet_size: u16, - interval: u8, + interval: Generic, _marker: PhantomData, } impl Endpoint<'_, B, D> { - pub(crate) fn new<'a>( - bus_ptr: &'a AtomicPtr, + pub(crate) fn new( + bus_ptr: &AtomicPtr, address: EndpointAddress, ep_type: EndpointType, max_packet_size: u16, - interval: u8, + interval: Generic, ) -> Endpoint<'_, B, D> { Endpoint { bus_ptr, @@ -100,7 +102,7 @@ impl Endpoint<'_, B, D> { } /// Gets the poll interval for interrupt endpoints. - pub fn interval(&self) -> u8 { + pub fn interval(&self) -> Generic { self.interval } diff --git a/src/lib.rs b/src/lib.rs index d7744c9..32ba7e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,8 @@ #![no_std] #![warn(missing_docs)] +use embedded_time::duration::Generic; + /// A USB stack error. #[derive(Debug)] pub enum UsbError { @@ -207,7 +209,7 @@ fn _ensure_sync() { _ep_addr: Option, _ep_type: EndpointType, _max_packet_size: u16, - _interval: u8, + _interval: Generic, ) -> Result { Err(UsbError::EndpointOverflow) } diff --git a/src/test_class.rs b/src/test_class.rs index 9e60e88..0a4b745 100644 --- a/src/test_class.rs +++ b/src/test_class.rs @@ -1,5 +1,7 @@ #![allow(missing_docs)] +use embedded_time::duration::Extensions; + use crate::class_prelude::*; use crate::descriptor; use crate::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid}; @@ -70,8 +72,9 @@ impl TestClass<'_, B> { iface: alloc.interface(), ep_bulk_in: alloc.bulk(sizes::BULK_ENDPOINT), ep_bulk_out: alloc.bulk(sizes::BULK_ENDPOINT), - ep_interrupt_in: alloc.interrupt(sizes::INTERRUPT_ENDPOINT, 1), - ep_interrupt_out: alloc.interrupt(sizes::INTERRUPT_ENDPOINT, 1), + ep_interrupt_in: alloc.interrupt(sizes::INTERRUPT_ENDPOINT, 1u32.milliseconds().into()), + ep_interrupt_out: alloc + .interrupt(sizes::INTERRUPT_ENDPOINT, 1u32.milliseconds().into()), control_buf: [0; sizes::BUFFER], bulk_buf: [0; sizes::BUFFER], interrupt_buf: [0; sizes::BUFFER], @@ -105,7 +108,7 @@ impl TestClass<'_, B> { &'a self, usb_bus: &'b UsbBusAllocator, ) -> UsbDeviceBuilder<'b, B> { - UsbDeviceBuilder::new(&usb_bus, UsbVidPid(VID, PID)) + UsbDeviceBuilder::new(usb_bus, UsbVidPid(VID, PID)) .manufacturer(MANUFACTURER) .product(PRODUCT) .serial_number(SERIAL_NUMBER)