diff --git a/advanced/common/usb/src/lib.rs b/advanced/common/usb/src/lib.rs index 4b8ff2e..466e09a 100644 --- a/advanced/common/usb/src/lib.rs +++ b/advanced/common/usb/src/lib.rs @@ -6,6 +6,9 @@ use core::num::NonZeroU8; +/// Device address assigned by the host; will be in the range 1..=127 +pub type Address = NonZeroU8; + /// Standard USB request #[derive(Clone, Copy, Debug, PartialEq)] pub enum Request { @@ -22,7 +25,7 @@ pub enum Request { // see section 9.4.6 of the USB specification SetAddress { /// New device address, in the range `1..=127` - address: Option, + address: Option
, }, /// SET_CONFIGURATION @@ -101,8 +104,6 @@ pub enum Descriptor { // there are even more descriptor types but we don't need to support them } -/// Device address assigned by the host; will be in the range 1..=127 -pub type Address = NonZeroU8; /// The state of the USB device #[derive(Clone, Copy, Debug, PartialEq)] pub enum DeviceState { @@ -122,6 +123,7 @@ pub enum DeviceState { #[cfg(test)] mod tests { + #[cfg(TODO)] use core::num::NonZeroU8; use crate::{Descriptor, Request}; diff --git a/advanced/firmware/src/bin/usb-2-solution.rs b/advanced/firmware/src/bin/usb-2-solution.rs index c49d430..9132adc 100644 --- a/advanced/firmware/src/bin/usb-2-solution.rs +++ b/advanced/firmware/src/bin/usb-2-solution.rs @@ -6,7 +6,7 @@ use dk::{ usbd::{self, Event}, }; use panic_log as _; // panic handler -use usb::{Descriptor, Request, DeviceState}; +use usb::{Address, Descriptor, DeviceState, Request}; #[rtic::app(device = dk)] const APP: () = { @@ -67,35 +67,35 @@ fn on_event(usbd: &USBD, state: &mut DeviceState, event: Event) { wvalue ); - // todo handle less indentedly? - if let Ok(request) = Request::parse(bmrequesttype, brequest, wvalue, windex, wlength) { - match request { - Request::GetDescriptor { descriptor, length } - if descriptor == Descriptor::Device => - { - log::info!("GET_DESCRIPTOR Device [length={}]", length); + let request = Request::parse(bmrequesttype, brequest, wvalue, windex, wlength) + .expect("Error parsing request"); + match request { + Request::GetDescriptor { descriptor, length } + if descriptor == Descriptor::Device => + { + log::info!("GET_DESCRIPTOR Device [length={}]", length); - log::info!("Goal reached; move to the next section"); - dk::exit() - } - Request::SetAddress { address } => { - log::info!("SETUP: device state is {:?}", state); - - // todo hide this in a helper? - // todo check for state configured -> err - if let Some(address) = address { - log::info!("SETUP: assigning address {}", address); - *state = DeviceState::Address(address); - } else { - log::info!("SETUP: address was None; assigning Default"); - *state = DeviceState::Default; - } - } - _ => unreachable!(), // we don't handle any other Requests + log::info!("Goal reached; move to the next section"); + dk::exit() } - } else { - unreachable!() // don't care about this for now + Request::SetAddress { address } => set_device_address(state, address), + _ => unreachable!(), // we don't handle any other Requests } } } } + +fn set_device_address(state: &mut DeviceState, address: Option
) { + match state { + DeviceState::Default | DeviceState::Address(..) => { + if let Some(address) = address { + log::info!("SETUP: assigning device address {}", address); + *state = DeviceState::Address(address); + } else { + log::info!("SETUP: address was None; assigning Default"); + *state = DeviceState::Default; + } + } + DeviceState::Configured { .. } => panic!(), // unspecified behavior + } +}