usb: merge alloc_control_pipe and into_bus into start.

This prevents calling `alloc_control_pipe` twice at compile time, which was
always an error.
This commit is contained in:
Dario Nieuwenhuis 2022-05-10 16:53:42 +02:00
parent 02ae1138e1
commit 6af5f8eb2d
3 changed files with 27 additions and 49 deletions

View file

@ -147,7 +147,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
packet_size: u16, packet_size: u16,
interval: u8, interval: u8,
) -> Result<Self::EndpointIn, driver::EndpointAllocError> { ) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
let index = self.alloc_in.allocate(ep_type, packet_size, interval)?; let index = self.alloc_in.allocate(ep_type)?;
let ep_addr = EndpointAddress::from_parts(index, UsbDirection::In); let ep_addr = EndpointAddress::from_parts(index, UsbDirection::In);
Ok(Endpoint::new(EndpointInfo { Ok(Endpoint::new(EndpointInfo {
addr: ep_addr, addr: ep_addr,
@ -163,7 +163,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
packet_size: u16, packet_size: u16,
interval: u8, interval: u8,
) -> Result<Self::EndpointOut, driver::EndpointAllocError> { ) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
let index = self.alloc_out.allocate(ep_type, packet_size, interval)?; let index = self.alloc_out.allocate(ep_type)?;
let ep_addr = EndpointAddress::from_parts(index, UsbDirection::Out); let ep_addr = EndpointAddress::from_parts(index, UsbDirection::Out);
Ok(Endpoint::new(EndpointInfo { Ok(Endpoint::new(EndpointInfo {
addr: ep_addr, addr: ep_addr,
@ -173,24 +173,16 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
})) }))
} }
fn alloc_control_pipe( fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
&mut self, (
max_packet_size: u16,
) -> Result<Self::ControlPipe, driver::EndpointAllocError> {
self.alloc_in.used |= 0x01;
self.alloc_in.lens[0] = max_packet_size as u8;
self.alloc_out.used |= 0x01;
self.alloc_out.lens[0] = max_packet_size as u8;
Ok(ControlPipe {
_phantom: PhantomData,
max_packet_size,
})
}
fn into_bus(self) -> Self::Bus {
Bus { Bus {
phantom: PhantomData, phantom: PhantomData,
} },
ControlPipe {
_phantom: PhantomData,
max_packet_size: control_max_packet_size,
},
)
} }
} }
@ -791,24 +783,14 @@ fn dma_end() {
struct Allocator { struct Allocator {
used: u16, used: u16,
// Buffers can be up to 64 Bytes since this is a Full-Speed implementation.
lens: [u8; 9],
} }
impl Allocator { impl Allocator {
fn new() -> Self { fn new() -> Self {
Self { Self { used: 0 }
used: 0,
lens: [0; 9],
}
} }
fn allocate( fn allocate(&mut self, ep_type: EndpointType) -> Result<usize, driver::EndpointAllocError> {
&mut self,
ep_type: EndpointType,
max_packet_size: u16,
_interval: u8,
) -> Result<usize, driver::EndpointAllocError> {
// Endpoint addresses are fixed in hardware: // Endpoint addresses are fixed in hardware:
// - 0x80 / 0x00 - Control EP0 // - 0x80 / 0x00 - Control EP0
// - 0x81 / 0x01 - Bulk/Interrupt EP1 // - 0x81 / 0x01 - Bulk/Interrupt EP1
@ -840,7 +822,6 @@ impl Allocator {
} }
self.used |= 1 << alloc_index; self.used |= 1 << alloc_index;
self.lens[alloc_index] = max_packet_size as u8;
Ok(alloc_index) Ok(alloc_index)
} }

View file

@ -14,7 +14,7 @@ pub trait Driver<'a> {
/// Allocates an endpoint and specified endpoint parameters. This method is called by the device /// Allocates an endpoint and specified endpoint parameters. This method is called by the device
/// and class implementations to allocate endpoints, and can only be called before /// and class implementations to allocate endpoints, and can only be called before
/// [`enable`](UsbBus::enable) is called. /// [`start`](UsbBus::start) is called.
/// ///
/// # Arguments /// # Arguments
/// ///
@ -37,14 +37,15 @@ pub trait Driver<'a> {
interval: u8, interval: u8,
) -> Result<Self::EndpointIn, EndpointAllocError>; ) -> Result<Self::EndpointIn, EndpointAllocError>;
fn alloc_control_pipe( /// Start operation of the USB device.
&mut self, ///
max_packet_size: u16, /// This returns the `Bus` and `ControlPipe` instances that are used to operate
) -> Result<Self::ControlPipe, EndpointAllocError>; /// the USB device. Additionally, this makes all the previously allocated endpoints
/// start operating.
/// Enables and initializes the USB peripheral. Soon after enabling the device will be reset, so ///
/// there is no need to perform a USB reset in this method. /// This consumes the `Driver` instance, so it's no longer possible to allocate more
fn into_bus(self) -> Self::Bus; /// endpoints.
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe);
/// Indicates that `set_device_address` must be called before accepting the corresponding /// Indicates that `set_device_address` must be called before accepting the corresponding
/// control transfer, not after. /// control transfer, not after.

View file

@ -126,7 +126,7 @@ struct Inner<'d, D: Driver<'d>> {
impl<'d, D: Driver<'d>> UsbDevice<'d, D> { impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
pub(crate) fn build( pub(crate) fn build(
mut driver: D, driver: D,
config: Config<'d>, config: Config<'d>,
handler: Option<&'d dyn DeviceStateHandler>, handler: Option<&'d dyn DeviceStateHandler>,
device_descriptor: &'d [u8], device_descriptor: &'d [u8],
@ -135,13 +135,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
control_buf: &'d mut [u8], control_buf: &'d mut [u8],
) -> UsbDevice<'d, D> { ) -> UsbDevice<'d, D> {
let control = driver // Start the USB bus.
.alloc_control_pipe(config.max_packet_size_0 as u16)
.expect("failed to alloc control endpoint");
// Enable the USB bus.
// This prevent further allocation by consuming the driver. // This prevent further allocation by consuming the driver.
let bus = driver.into_bus(); let (bus, control) = driver.start(config.max_packet_size_0 as u16);
Self { Self {
control_buf, control_buf,