mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 12:20:37 +00:00
Merge pull request #4397 from korbin/allocate-numbered-endpoints
Make USB endpoint allocator methods accept an optional `EndpointAddress`
This commit is contained in:
commit
f525386fca
@ -121,10 +121,11 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
|
||||
let index = self.alloc_in.allocate(ep_type)?;
|
||||
let index = self.alloc_in.allocate(ep_type, ep_addr)?;
|
||||
let ep_addr = EndpointAddress::from_parts(index, Direction::In);
|
||||
Ok(Endpoint::new(EndpointInfo {
|
||||
addr: ep_addr,
|
||||
@ -137,10 +138,11 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
|
||||
let index = self.alloc_out.allocate(ep_type)?;
|
||||
let index = self.alloc_out.allocate(ep_type, ep_addr)?;
|
||||
let ep_addr = EndpointAddress::from_parts(index, Direction::Out);
|
||||
Ok(Endpoint::new(EndpointInfo {
|
||||
addr: ep_addr,
|
||||
@ -734,7 +736,11 @@ impl Allocator {
|
||||
Self { used: 0 }
|
||||
}
|
||||
|
||||
fn allocate(&mut self, ep_type: EndpointType) -> Result<usize, driver::EndpointAllocError> {
|
||||
fn allocate(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
) -> Result<usize, driver::EndpointAllocError> {
|
||||
// Endpoint addresses are fixed in hardware:
|
||||
// - 0x80 / 0x00 - Control EP0
|
||||
// - 0x81 / 0x01 - Bulk/Interrupt EP1
|
||||
@ -748,7 +754,27 @@ impl Allocator {
|
||||
|
||||
// Endpoint directions are allocated individually.
|
||||
|
||||
let alloc_index = match ep_type {
|
||||
let alloc_index = if let Some(addr) = ep_addr {
|
||||
// Use the specified endpoint address
|
||||
let requested_index = addr.index();
|
||||
// Validate the requested index based on endpoint type
|
||||
match ep_type {
|
||||
EndpointType::Isochronous => {
|
||||
if requested_index != 8 {
|
||||
return Err(driver::EndpointAllocError);
|
||||
}
|
||||
}
|
||||
EndpointType::Control => return Err(driver::EndpointAllocError),
|
||||
EndpointType::Interrupt | EndpointType::Bulk => {
|
||||
if requested_index < 1 || requested_index > 7 {
|
||||
return Err(driver::EndpointAllocError);
|
||||
}
|
||||
}
|
||||
}
|
||||
requested_index
|
||||
} else {
|
||||
// Allocate any available endpoint
|
||||
match ep_type {
|
||||
EndpointType::Isochronous => 8,
|
||||
EndpointType::Control => return Err(driver::EndpointAllocError),
|
||||
EndpointType::Interrupt | EndpointType::Bulk => {
|
||||
@ -759,6 +785,7 @@ impl Allocator {
|
||||
}
|
||||
ones + 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if self.used & (1 << alloc_index) != 0 {
|
||||
|
@ -153,6 +153,7 @@ impl<'d, T: Instance> Driver<'d, T> {
|
||||
fn alloc_endpoint<D: Dir>(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> {
|
||||
@ -169,12 +170,25 @@ impl<'d, T: Instance> Driver<'d, T> {
|
||||
Direction::In => &mut self.ep_in,
|
||||
};
|
||||
|
||||
let index = alloc.iter_mut().enumerate().find(|(i, ep)| {
|
||||
let index = if let Some(addr) = ep_addr {
|
||||
// Use the specified endpoint address
|
||||
let requested_index = addr.index();
|
||||
if requested_index == 0 || requested_index >= EP_COUNT {
|
||||
return Err(EndpointAllocError);
|
||||
}
|
||||
if alloc[requested_index].used {
|
||||
return Err(EndpointAllocError);
|
||||
}
|
||||
Some((requested_index, &mut alloc[requested_index]))
|
||||
} else {
|
||||
// Find any available endpoint
|
||||
alloc.iter_mut().enumerate().find(|(i, ep)| {
|
||||
if *i == 0 {
|
||||
return false; // reserved for control pipe
|
||||
}
|
||||
!ep.used
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let (index, ep) = index.ok_or(EndpointAllocError)?;
|
||||
assert!(!ep.used);
|
||||
@ -299,19 +313,21 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
|
||||
|
@ -231,19 +231,23 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> {
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, EndpointAllocError> {
|
||||
self.inner.alloc_endpoint_in(ep_type, max_packet_size, interval_ms)
|
||||
self.inner
|
||||
.alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, EndpointAllocError> {
|
||||
self.inner.alloc_endpoint_out(ep_type, max_packet_size, interval_ms)
|
||||
self.inner
|
||||
.alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
|
||||
|
@ -359,26 +359,19 @@ impl<'d, T: Instance> Driver<'d, T> {
|
||||
addr
|
||||
}
|
||||
|
||||
fn alloc_endpoint<D: Dir>(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> {
|
||||
trace!(
|
||||
"allocating type={:?} mps={:?} interval_ms={}, dir={:?}",
|
||||
ep_type,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
D::dir()
|
||||
);
|
||||
|
||||
let index = self.alloc.iter_mut().enumerate().find(|(i, ep)| {
|
||||
if *i == 0 && ep_type != EndpointType::Control {
|
||||
return false; // reserved for control pipe
|
||||
fn is_endpoint_available<D: Dir>(&self, index: usize, ep_type: EndpointType) -> bool {
|
||||
if index == 0 && ep_type != EndpointType::Control {
|
||||
return false; // EP0 is reserved for control
|
||||
}
|
||||
|
||||
let ep = match self.alloc.get(index) {
|
||||
Some(ep) => ep,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let used = ep.used_out || ep.used_in;
|
||||
if used && (ep.ep_type == EndpointType::Isochronous) {
|
||||
|
||||
if used && ep.ep_type == EndpointType::Isochronous {
|
||||
// Isochronous endpoints are always double-buffered.
|
||||
// Their corresponding endpoint/channel registers are forced to be unidirectional.
|
||||
// Do not reuse this index.
|
||||
@ -390,11 +383,36 @@ impl<'d, T: Instance> Driver<'d, T> {
|
||||
Direction::Out => ep.used_out,
|
||||
Direction::In => ep.used_in,
|
||||
};
|
||||
|
||||
!used || (ep.ep_type == ep_type && !used_dir)
|
||||
});
|
||||
}
|
||||
|
||||
fn alloc_endpoint<D: Dir>(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> {
|
||||
trace!(
|
||||
"allocating type={:?} mps={:?} interval_ms={}, dir={:?}",
|
||||
ep_type,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
D::dir()
|
||||
);
|
||||
|
||||
let index = if let Some(addr) = ep_addr {
|
||||
// Use the specified endpoint address
|
||||
self.is_endpoint_available::<D>(addr.index(), ep_type)
|
||||
.then_some(addr.index())
|
||||
} else {
|
||||
// Find any available endpoint
|
||||
(0..self.alloc.len()).find(|&i| self.is_endpoint_available::<D>(i, ep_type))
|
||||
};
|
||||
|
||||
let (index, ep) = match index {
|
||||
Some(x) => x,
|
||||
Some(i) => (i, &mut self.alloc[i]),
|
||||
None => return Err(EndpointAllocError),
|
||||
};
|
||||
|
||||
@ -479,27 +497,29 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
|
||||
let ep_out = self
|
||||
.alloc_endpoint(EndpointType::Control, control_max_packet_size, 0)
|
||||
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
|
||||
.unwrap();
|
||||
let ep_in = self
|
||||
.alloc_endpoint(EndpointType::Control, control_max_packet_size, 0)
|
||||
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
|
||||
.unwrap();
|
||||
assert_eq!(ep_out.info.addr.index(), 0);
|
||||
assert_eq!(ep_in.info.addr.index(), 0);
|
||||
|
@ -136,6 +136,7 @@ pub trait Driver<'a> {
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, EndpointAllocError>;
|
||||
@ -153,6 +154,7 @@ pub trait Driver<'a> {
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, EndpointAllocError>;
|
||||
|
@ -345,6 +345,7 @@ impl<'d, const MAX_EP_COUNT: usize> Driver<'d, MAX_EP_COUNT> {
|
||||
fn alloc_endpoint<D: Dir>(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Endpoint<'d, D>, EndpointAllocError> {
|
||||
@ -379,15 +380,31 @@ impl<'d, const MAX_EP_COUNT: usize> Driver<'d, MAX_EP_COUNT> {
|
||||
Direction::In => &mut self.ep_in[..self.instance.endpoint_count],
|
||||
};
|
||||
|
||||
// Find free endpoint slot
|
||||
let slot = eps.iter_mut().enumerate().find(|(i, ep)| {
|
||||
// Find endpoint slot
|
||||
let slot = if let Some(addr) = ep_addr {
|
||||
// Use the specified endpoint address
|
||||
let requested_index = addr.index();
|
||||
if requested_index >= self.instance.endpoint_count {
|
||||
return Err(EndpointAllocError);
|
||||
}
|
||||
if requested_index == 0 && ep_type != EndpointType::Control {
|
||||
return Err(EndpointAllocError); // EP0 is reserved for control
|
||||
}
|
||||
if eps[requested_index].is_some() {
|
||||
return Err(EndpointAllocError); // Already allocated
|
||||
}
|
||||
Some((requested_index, &mut eps[requested_index]))
|
||||
} else {
|
||||
// Find any free endpoint slot
|
||||
eps.iter_mut().enumerate().find(|(i, ep)| {
|
||||
if *i == 0 && ep_type != EndpointType::Control {
|
||||
// reserved for control pipe
|
||||
false
|
||||
} else {
|
||||
ep.is_none()
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let index = match slot {
|
||||
Some((index, ep)) => {
|
||||
@ -438,27 +455,29 @@ impl<'d, const MAX_EP_COUNT: usize> embassy_usb_driver::Driver<'d> for Driver<'d
|
||||
fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointIn, EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> Result<Self::EndpointOut, EndpointAllocError> {
|
||||
self.alloc_endpoint(ep_type, max_packet_size, interval_ms)
|
||||
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
}
|
||||
|
||||
fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
|
||||
let ep_out = self
|
||||
.alloc_endpoint(EndpointType::Control, control_max_packet_size, 0)
|
||||
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
|
||||
.unwrap();
|
||||
let ep_in = self
|
||||
.alloc_endpoint(EndpointType::Control, control_max_packet_size, 0)
|
||||
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
|
||||
.unwrap();
|
||||
assert_eq!(ep_out.info.addr.index(), 0);
|
||||
assert_eq!(ep_in.info.addr.index(), 0);
|
||||
|
@ -2,7 +2,7 @@ use heapless::Vec;
|
||||
|
||||
use crate::config::MAX_HANDLER_COUNT;
|
||||
use crate::descriptor::{BosWriter, DescriptorWriter, SynchronizationType, UsageType};
|
||||
use crate::driver::{Driver, Endpoint, EndpointInfo, EndpointType};
|
||||
use crate::driver::{Driver, Endpoint, EndpointAddress, EndpointInfo, EndpointType};
|
||||
use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter};
|
||||
use crate::types::{InterfaceNumber, StringIndex};
|
||||
use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
|
||||
@ -465,11 +465,17 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
/// Allocate an IN endpoint, without writing its descriptor.
|
||||
///
|
||||
/// Used for granular control over the order of endpoint and descriptor creation.
|
||||
pub fn alloc_endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn {
|
||||
pub fn alloc_endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> D::EndpointIn {
|
||||
let ep = self
|
||||
.builder
|
||||
.driver
|
||||
.alloc_endpoint_in(ep_type, max_packet_size, interval_ms)
|
||||
.alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
.expect("alloc_endpoint_in failed");
|
||||
|
||||
ep
|
||||
@ -478,13 +484,14 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
fn endpoint_in(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
synchronization_type: SynchronizationType,
|
||||
usage_type: UsageType,
|
||||
extra_fields: &[u8],
|
||||
) -> D::EndpointIn {
|
||||
let ep = self.alloc_endpoint_in(ep_type, max_packet_size, interval_ms);
|
||||
let ep = self.alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms);
|
||||
self.endpoint_descriptor(ep.info(), synchronization_type, usage_type, extra_fields);
|
||||
|
||||
ep
|
||||
@ -496,13 +503,14 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
pub fn alloc_endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> D::EndpointOut {
|
||||
let ep = self
|
||||
.builder
|
||||
.driver
|
||||
.alloc_endpoint_out(ep_type, max_packet_size, interval_ms)
|
||||
.alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms)
|
||||
.expect("alloc_endpoint_out failed");
|
||||
|
||||
ep
|
||||
@ -511,13 +519,14 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
fn endpoint_out(
|
||||
&mut self,
|
||||
ep_type: EndpointType,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
synchronization_type: SynchronizationType,
|
||||
usage_type: UsageType,
|
||||
extra_fields: &[u8],
|
||||
) -> D::EndpointOut {
|
||||
let ep = self.alloc_endpoint_out(ep_type, max_packet_size, interval_ms);
|
||||
let ep = self.alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms);
|
||||
self.endpoint_descriptor(ep.info(), synchronization_type, usage_type, extra_fields);
|
||||
|
||||
ep
|
||||
@ -527,9 +536,10 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
///
|
||||
/// Descriptors are written in the order builder functions are called. Note that some
|
||||
/// classes care about the order.
|
||||
pub fn endpoint_bulk_in(&mut self, max_packet_size: u16) -> D::EndpointIn {
|
||||
pub fn endpoint_bulk_in(&mut self, ep_addr: Option<EndpointAddress>, max_packet_size: u16) -> D::EndpointIn {
|
||||
self.endpoint_in(
|
||||
EndpointType::Bulk,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
0,
|
||||
SynchronizationType::NoSynchronization,
|
||||
@ -542,9 +552,10 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
///
|
||||
/// Descriptors are written in the order builder functions are called. Note that some
|
||||
/// classes care about the order.
|
||||
pub fn endpoint_bulk_out(&mut self, max_packet_size: u16) -> D::EndpointOut {
|
||||
pub fn endpoint_bulk_out(&mut self, ep_addr: Option<EndpointAddress>, max_packet_size: u16) -> D::EndpointOut {
|
||||
self.endpoint_out(
|
||||
EndpointType::Bulk,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
0,
|
||||
SynchronizationType::NoSynchronization,
|
||||
@ -557,9 +568,15 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
///
|
||||
/// Descriptors are written in the order builder functions are called. Note that some
|
||||
/// classes care about the order.
|
||||
pub fn endpoint_interrupt_in(&mut self, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn {
|
||||
pub fn endpoint_interrupt_in(
|
||||
&mut self,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> D::EndpointIn {
|
||||
self.endpoint_in(
|
||||
EndpointType::Interrupt,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
SynchronizationType::NoSynchronization,
|
||||
@ -569,9 +586,15 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
}
|
||||
|
||||
/// Allocate a INTERRUPT OUT endpoint and write its descriptor.
|
||||
pub fn endpoint_interrupt_out(&mut self, max_packet_size: u16, interval_ms: u8) -> D::EndpointOut {
|
||||
pub fn endpoint_interrupt_out(
|
||||
&mut self,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
) -> D::EndpointOut {
|
||||
self.endpoint_out(
|
||||
EndpointType::Interrupt,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
SynchronizationType::NoSynchronization,
|
||||
@ -586,6 +609,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
/// classes care about the order.
|
||||
pub fn endpoint_isochronous_in(
|
||||
&mut self,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
synchronization_type: SynchronizationType,
|
||||
@ -594,6 +618,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
) -> D::EndpointIn {
|
||||
self.endpoint_in(
|
||||
EndpointType::Isochronous,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
synchronization_type,
|
||||
@ -605,6 +630,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
/// Allocate a ISOCHRONOUS OUT endpoint and write its descriptor.
|
||||
pub fn endpoint_isochronous_out(
|
||||
&mut self,
|
||||
ep_addr: Option<EndpointAddress>,
|
||||
max_packet_size: u16,
|
||||
interval_ms: u8,
|
||||
synchronization_type: SynchronizationType,
|
||||
@ -613,6 +639,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
|
||||
) -> D::EndpointOut {
|
||||
self.endpoint_out(
|
||||
EndpointType::Isochronous,
|
||||
ep_addr,
|
||||
max_packet_size,
|
||||
interval_ms,
|
||||
synchronization_type,
|
||||
|
@ -254,14 +254,14 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
|
||||
],
|
||||
);
|
||||
|
||||
let comm_ep = alt.endpoint_interrupt_in(8, 255);
|
||||
let comm_ep = alt.endpoint_interrupt_in(None, 8, 255);
|
||||
|
||||
// Data interface
|
||||
let mut iface = func.interface();
|
||||
let data_if = iface.interface_number();
|
||||
let mut alt = iface.alt_setting(USB_CLASS_CDC_DATA, 0x00, CDC_PROTOCOL_NONE, None);
|
||||
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, max_packet_size);
|
||||
|
||||
drop(func);
|
||||
|
||||
|
@ -313,15 +313,15 @@ impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> {
|
||||
],
|
||||
);
|
||||
|
||||
let comm_ep = alt.endpoint_interrupt_in(8, 255);
|
||||
let comm_ep = alt.endpoint_interrupt_in(None, 8, 255);
|
||||
|
||||
// Data interface
|
||||
let mut iface = func.interface();
|
||||
let data_if = iface.interface_number();
|
||||
let _alt = iface.alt_setting(USB_CLASS_CDC_DATA, 0x00, CDC_PROTOCOL_NTB, None);
|
||||
let mut alt = iface.alt_setting(USB_CLASS_CDC_DATA, 0x00, CDC_PROTOCOL_NTB, None);
|
||||
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, max_packet_size);
|
||||
|
||||
drop(func);
|
||||
|
||||
|
@ -61,10 +61,10 @@ impl<'d, D: Driver<'d>> CmsisDapV2Class<'d, D> {
|
||||
));
|
||||
let mut interface = function.interface();
|
||||
let mut alt = interface.alt_setting(0xFF, 0, 0, Some(iface_string));
|
||||
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, max_packet_size);
|
||||
let trace_ep = if trace {
|
||||
Some(alt.endpoint_bulk_in(max_packet_size))
|
||||
Some(alt.endpoint_bulk_in(None, max_packet_size))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -133,9 +133,9 @@ fn build<'d, D: Driver<'d>>(
|
||||
],
|
||||
);
|
||||
|
||||
let ep_in = alt.endpoint_interrupt_in(config.max_packet_size, config.poll_ms);
|
||||
let ep_in = alt.endpoint_interrupt_in(None, config.max_packet_size, config.poll_ms);
|
||||
let ep_out = if with_out_endpoint {
|
||||
Some(alt.endpoint_interrupt_out(config.max_packet_size, config.poll_ms))
|
||||
Some(alt.endpoint_interrupt_out(None, config.max_packet_size, config.poll_ms))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -129,14 +129,14 @@ impl<'d, D: Driver<'d>> MidiClass<'d, D> {
|
||||
for i in 0..n_out_jacks {
|
||||
endpoint_data[2 + i as usize] = in_jack_id_emb(i);
|
||||
}
|
||||
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, max_packet_size);
|
||||
alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_out_jacks as usize]);
|
||||
|
||||
endpoint_data[1] = n_in_jacks;
|
||||
for i in 0..n_in_jacks {
|
||||
endpoint_data[2 + i as usize] = out_jack_id_emb(i);
|
||||
}
|
||||
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, max_packet_size);
|
||||
alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_in_jacks as usize]);
|
||||
|
||||
MidiClass { read_ep, write_ep }
|
||||
|
@ -268,9 +268,10 @@ impl<'d, D: Driver<'d>> Speaker<'d, D> {
|
||||
|
||||
alt.descriptor(CS_INTERFACE, &format_descriptor);
|
||||
|
||||
let streaming_endpoint = alt.alloc_endpoint_out(EndpointType::Isochronous, max_packet_size, 1);
|
||||
let streaming_endpoint = alt.alloc_endpoint_out(EndpointType::Isochronous, None, max_packet_size, 1);
|
||||
let feedback_endpoint = alt.alloc_endpoint_in(
|
||||
EndpointType::Isochronous,
|
||||
None,
|
||||
4, // Feedback packets are 24 bit (10.14 format).
|
||||
1,
|
||||
);
|
||||
|
@ -96,8 +96,8 @@ async fn main(_spawner: Spawner) {
|
||||
let mut function = builder.function(0xFF, 0, 0);
|
||||
let mut interface = function.interface();
|
||||
let mut alt = interface.alt_setting(0xFF, 0, 0, None);
|
||||
let mut read_ep = alt.endpoint_bulk_out(64);
|
||||
let mut write_ep = alt.endpoint_bulk_in(64);
|
||||
let mut read_ep = alt.endpoint_bulk_out(None, 64);
|
||||
let mut write_ep = alt.endpoint_bulk_in(None, 64);
|
||||
drop(function);
|
||||
|
||||
// Build the builder.
|
||||
|
@ -125,8 +125,8 @@ impl<'d, D: Driver<'d>> WebEndpoints<'d, D> {
|
||||
let mut iface = func.interface();
|
||||
let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None);
|
||||
|
||||
let write_ep = alt.endpoint_bulk_in(config.max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(config.max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, config.max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, config.max_packet_size);
|
||||
|
||||
WebEndpoints { write_ep, read_ep }
|
||||
}
|
||||
|
@ -125,8 +125,8 @@ impl<'d, D: Driver<'d>> WebEndpoints<'d, D> {
|
||||
let mut iface = func.interface();
|
||||
let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None);
|
||||
|
||||
let write_ep = alt.endpoint_bulk_in(config.max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(config.max_packet_size);
|
||||
let write_ep = alt.endpoint_bulk_in(None, config.max_packet_size);
|
||||
let read_ep = alt.endpoint_bulk_out(None, config.max_packet_size);
|
||||
|
||||
WebEndpoints { write_ep, read_ep }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user