Build in a new Unpowered state

Replaces the sub-state of representing being being available. Power states also now set enable/disable directly too, which simplifies code.
This commit is contained in:
huntc 2022-07-08 15:30:15 +10:00
parent 4a8f117f25
commit 8d71a358c8

View File

@ -30,6 +30,9 @@ use crate::driver::ControlPipe;
#[derive(PartialEq, Eq, Copy, Clone, Debug)] #[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum UsbDeviceState { pub enum UsbDeviceState {
/// The USB device has no power.
Unpowered,
/// The USB device is disabled. /// The USB device is disabled.
Disabled, Disabled,
@ -114,7 +117,6 @@ struct Inner<'d, D: Driver<'d>> {
device_state: UsbDeviceState, device_state: UsbDeviceState,
suspended: bool, suspended: bool,
power_available: bool,
remote_wakeup_enabled: bool, remote_wakeup_enabled: bool,
self_powered: bool, self_powered: bool,
@ -155,9 +157,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
config_descriptor, config_descriptor,
bos_descriptor, bos_descriptor,
device_state: UsbDeviceState::Disabled, device_state: UsbDeviceState::Unpowered,
suspended: false, suspended: false,
power_available: false,
remote_wakeup_enabled: false, remote_wakeup_enabled: false,
self_powered: false, self_powered: false,
address: 0, address: 0,
@ -187,25 +188,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
/// before calling any other `UsbDevice` methods to fully reset the /// before calling any other `UsbDevice` methods to fully reset the
/// peripheral. /// peripheral.
pub async fn run_until_suspend(&mut self) -> () { pub async fn run_until_suspend(&mut self) -> () {
while !self.inner.power_available { while !self.inner.suspended {
let evt = self.inner.bus.poll().await;
self.inner.handle_bus_event(evt);
}
if self.inner.device_state == UsbDeviceState::Disabled {
self.inner.bus.enable().await;
self.inner.device_state = UsbDeviceState::Default;
if let Some(h) = &self.inner.handler {
h.enabled(true);
}
}
while !self.inner.suspended && self.inner.power_available {
let control_fut = self.control.setup(); let control_fut = self.control.setup();
let bus_fut = self.inner.bus.poll(); let bus_fut = self.inner.bus.poll();
match select(bus_fut, control_fut).await { match select(bus_fut, control_fut).await {
Either::First(evt) => self.inner.handle_bus_event(evt), Either::First(evt) => self.inner.handle_bus_event(evt).await,
Either::Second(req) => self.handle_control(req).await, Either::Second(req) => self.handle_control(req).await,
} }
} }
@ -229,9 +216,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
/// ///
/// This future is cancel-safe. /// This future is cancel-safe.
pub async fn wait_resume(&mut self) { pub async fn wait_resume(&mut self) {
while self.inner.suspended || !self.inner.power_available { while self.inner.suspended {
let evt = self.inner.bus.poll().await; let evt = self.inner.bus.poll().await;
self.inner.handle_bus_event(evt); self.inner.handle_bus_event(evt).await;
} }
} }
@ -348,7 +335,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
} }
impl<'d, D: Driver<'d>> Inner<'d, D> { impl<'d, D: Driver<'d>> Inner<'d, D> {
fn handle_bus_event(&mut self, evt: Event) { async fn handle_bus_event(&mut self, evt: Event) {
match evt { match evt {
Event::Reset => { Event::Reset => {
trace!("usb: reset"); trace!("usb: reset");
@ -385,11 +372,21 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
} }
Event::PowerDetected => { Event::PowerDetected => {
trace!("usb: power detected"); trace!("usb: power detected");
self.power_available = true; self.bus.enable().await;
self.device_state = UsbDeviceState::Default;
if let Some(h) = &self.handler {
h.enabled(true);
}
} }
Event::PowerRemoved => { Event::PowerRemoved => {
trace!("usb: power removed"); trace!("usb: power removed");
self.power_available = false; self.bus.disable().await;
self.device_state = UsbDeviceState::Unpowered;
if let Some(h) = &self.handler {
h.enabled(false);
}
} }
} }
} }