Skip to content

Commit 5edd277

Browse files
committed
add support for alternate settings
1 parent 49890d9 commit 5edd277

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "usb-device"
33
description = "Experimental device-side USB stack for embedded devices."
4-
version = "0.2.7"
4+
version = "0.3.0"
55
edition = "2018"
66
readme = "README.md"
77
keywords = ["no-std", "embedded", "usb"]

src/descriptor.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{Result, UsbError};
2-
use crate::bus::{UsbBus, InterfaceNumber};
2+
use crate::bus::{UsbBus, InterfaceNumber, StringIndex};
33
use crate::device;
44
use crate::endpoint::{Endpoint, EndpointDirection};
55

@@ -175,24 +175,64 @@ impl DescriptorWriter<'_> {
175175
pub fn interface(&mut self, number: InterfaceNumber,
176176
interface_class: u8, interface_sub_class: u8, interface_protocol: u8) -> Result<()>
177177
{
178-
match self.num_interfaces_mark {
179-
Some(mark) => self.buf[mark] += 1,
180-
None => return Err(UsbError::InvalidState),
178+
self.interface_alternate_setting(
179+
number,
180+
device::DEFAULT_ALTERNATE_SETTING,
181+
interface_class,
182+
interface_sub_class,
183+
interface_protocol,
184+
None,
185+
)
186+
}
187+
188+
/// Writes a interface descriptor with a specific alternate setting and
189+
/// interface string identifier.
190+
///
191+
/// # Arguments
192+
///
193+
/// * `number` - Interface number previously allocated with
194+
/// [`UsbBusAllocator::interface`](crate::bus::UsbBusAllocator::interface).
195+
/// * `alternate_setting` - number of the alternate setting
196+
/// * `interface_class` - Class code assigned by USB.org. Use `0xff` for vendor-specific devices
197+
/// that do not conform to any class.
198+
/// * `interface_sub_class` - Sub-class code. Depends on class.
199+
/// * `interface_protocol` - Protocol code. Depends on class and sub-class.
200+
/// * `interface_string` - Index of string descriptor describing this interface
201+
202+
pub fn interface_alternate_setting(
203+
&mut self,
204+
number: InterfaceNumber,
205+
alternate_setting: u8,
206+
interface_class: u8,
207+
interface_sub_class: u8,
208+
interface_protocol: u8,
209+
interface_string: Option<StringIndex>,
210+
) -> Result<()> {
211+
let ifndx = match interface_string {
212+
Some(si) => si.into(),
213+
None => 0,
181214
};
215+
if alternate_setting == device::DEFAULT_ALTERNATE_SETTING {
216+
match self.num_interfaces_mark {
217+
Some(mark) => self.buf[mark] += 1,
218+
None => return Err(UsbError::InvalidState),
219+
};
220+
}
182221

183222
self.num_endpoints_mark = Some(self.position + 4);
184223

185224
self.write(
186225
descriptor_type::INTERFACE,
187226
&[
188-
number.into(), // bInterfaceNumber
189-
device::DEFAULT_ALTERNATE_SETTING, // bAlternateSetting (how to even handle these...)
190-
0, // bNumEndpoints
191-
interface_class, // bInterfaceClass
227+
number.into(), // bInterfaceNumber
228+
alternate_setting, // bAlternateSetting (how to even handle these...)
229+
0, // bNumEndpoints
230+
interface_class, // bInterfaceClass
192231
interface_sub_class, // bInterfaceSubClass
193-
interface_protocol, // bInterfaceProtocol
194-
0, // iInterface
195-
])?;
232+
interface_protocol, // bInterfaceProtocol
233+
ifndx, // iInterface
234+
],
235+
)?;
196236

197237
Ok(())
198238
}
@@ -318,4 +358,4 @@ impl<'w, 'a: 'w> BosWriter<'w, 'a> {
318358
let position = self.writer.position as u16;
319359
self.writer.buf[2..4].copy_from_slice(&position.to_le_bytes());
320360
}
321-
}
361+
}

0 commit comments

Comments
 (0)