Add basic device state handling for endpoints.

This commit is contained in:
alexmoon
2022-04-02 16:35:03 -04:00
committed by Dario Nieuwenhuis
parent 99f95a33c3
commit 2ce435dc34
5 changed files with 190 additions and 60 deletions

View File

@ -72,6 +72,9 @@ pub trait Bus {
/// Sets the device USB address to `addr`.
fn set_device_address(&mut self, addr: u8);
/// Sets the device configured state.
fn set_configured(&mut self, configured: bool);
/// Sets or clears the STALL condition for an endpoint. If the endpoint is an OUT endpoint, it
/// should be prepared to receive data again. Only used during control transfers.
fn set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool);
@ -105,6 +108,10 @@ pub trait Bus {
}
pub trait Endpoint {
type WaitEnabledFuture<'a>: Future<Output = ()> + 'a
where
Self: 'a;
/// Get the endpoint address
fn info(&self) -> &EndpointInfo;
@ -115,6 +122,9 @@ pub trait Endpoint {
/// Gets whether the STALL condition is set for an endpoint.
fn is_stalled(&self) -> bool;
/// Waits for the endpoint to be enabled.
fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_>;
// TODO enable/disable?
}
@ -212,6 +222,7 @@ pub enum WriteError {
/// class shouldn't provide more data than the `max_packet_size` it specified when allocating
/// the endpoint.
BufferOverflow,
Disabled,
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
@ -223,4 +234,5 @@ pub enum ReadError {
/// should use a buffer that is large enough for the `max_packet_size` it specified when
/// allocating the endpoint.
BufferOverflow,
Disabled,
}

View File

@ -162,18 +162,21 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
self.remote_wakeup_enabled = true;
self.control.accept(stage)
}
(Request::SET_ADDRESS, 1..=127) => {
self.pending_address = req.value as u8;
(Request::SET_ADDRESS, addr @ 1..=127) => {
self.pending_address = addr as u8;
self.bus.set_device_address(self.pending_address);
self.control.accept(stage)
}
(Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => {
self.device_state = UsbDeviceState::Configured;
self.bus.set_configured(true);
self.control.accept(stage)
}
(Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state {
UsbDeviceState::Default => self.control.accept(stage),
_ => {
self.device_state = UsbDeviceState::Addressed;
self.bus.set_configured(false);
self.control.accept(stage)
}
},