aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-07-28 10:22:33 -0400
committerBrian Cully <bjc@kublai.com>2019-07-28 10:22:33 -0400
commitf39e0425a67277556db1c55547574b4205ed03e9 (patch)
tree50e09062edde2db6ec593b0580ffda0c98a037ca
parentb1ef816d00ad5fb6048007611c5b091e2540c306 (diff)
downloadsamd21-demo-f39e0425a67277556db1c55547574b4205ed03e9.tar.gz
samd21-demo-f39e0425a67277556db1c55547574b4205ed03e9.zip
Use TryFrom where possible, instead of panicking.
-rwxr-xr-xusbh/src/lib.rs2
-rw-r--r--usbh/src/pipe.rs12
-rw-r--r--usbh/src/usbproto.rs111
3 files changed, 62 insertions, 63 deletions
diff --git a/usbh/src/lib.rs b/usbh/src/lib.rs
index c4e2426..4bad707 100755
--- a/usbh/src/lib.rs
+++ b/usbh/src/lib.rs
@@ -374,7 +374,7 @@ where
match self.devices.next(self.millis) {
// TODO: new error for being out of devices.
- None => Err(PipeErr::Other),
+ None => Err(PipeErr::Other("out of devices")),
Some(device) => {
device.max_packet_size = desc.b_max_packet_size;
debug!("Setting address to {}.", device.addr);
diff --git a/usbh/src/pipe.rs b/usbh/src/pipe.rs
index 936aa23..0a8503b 100644
--- a/usbh/src/pipe.rs
+++ b/usbh/src/pipe.rs
@@ -41,8 +41,14 @@ pub(crate) enum PipeErr {
HWTimeout,
DataToggle,
SWTimeout,
- Other,
+ Other(&'static str),
}
+impl From<&'static str> for PipeErr {
+ fn from(v: &'static str) -> Self {
+ Self::Other(v)
+ }
+}
+
pub(crate) struct PipeTable {
tbl: [PipeDesc; MAX_PIPES],
}
@@ -135,7 +141,7 @@ impl Pipe<'_, '_> {
if let Some(b) = buf {
// TODO: data stage, has up to 5,000ms (in 500ms
// per-packet chunks) to complete. cf ยง9.2.6.4 of USB 2.0.
- match bm_request_type.direction() {
+ match bm_request_type.direction()? {
USBSetupDirection::DeviceToHost => {
trace!("buf0: {:?}", &b);
self.in_transfer(&b, NAK_LIMIT, millis)?;
@@ -159,7 +165,7 @@ impl Pipe<'_, '_> {
unsafe { w.multi_packet_size().bits(0) }
});
- let token = match bm_request_type.direction() {
+ let token = match bm_request_type.direction()? {
USBSetupDirection::DeviceToHost => USBToken::Out,
USBSetupDirection::HostToDevice => USBToken::In,
};
diff --git a/usbh/src/usbproto.rs b/usbh/src/usbproto.rs
index 690cb40..0b7a8eb 100644
--- a/usbh/src/usbproto.rs
+++ b/usbh/src/usbproto.rs
@@ -2,6 +2,8 @@
///
/// Everything in here is defined by the USB specification, and
/// hardware independent.
+use core::convert::TryFrom;
+use core::convert::TryInto;
// TODO: Put protocol section references in for types and
// documentation.
@@ -79,15 +81,14 @@ pub enum USBSetupDirection {
HostToDevice = 0x00,
DeviceToHost = 0x80,
}
-impl<T> From<T> for USBSetupDirection
-where
- T: Into<u8>,
-{
- fn from(v: T) -> Self {
- match v.into() {
- 0x00 => Self::HostToDevice,
- 0x80 => Self::DeviceToHost,
- _ => panic!("direction can only be 0x00 or 0x80"),
+impl TryFrom<u8> for USBSetupDirection {
+ type Error = &'static str;
+
+ fn try_from(v: u8) -> Result<Self, Self::Error> {
+ match v {
+ 0x00 => Ok(Self::HostToDevice),
+ 0x80 => Ok(Self::DeviceToHost),
+ _ => Err("direction can only be 0x00 or 0x80"),
}
}
}
@@ -98,16 +99,15 @@ pub enum USBSetupType {
Class = 0x20,
Vendor = 0x40,
}
-impl<T> From<T> for USBSetupType
-where
- T: Into<u8>,
-{
- fn from(v: T) -> Self {
- match v.into() {
- 0x00 => Self::Standard,
- 0x20 => Self::Class,
- 0x40 => Self::Vendor,
- _ => panic!("type can only be 0x00, 0x20, or 0x40"),
+impl TryFrom<u8> for USBSetupType {
+ type Error = &'static str;
+
+ fn try_from(v: u8) -> Result<Self, Self::Error> {
+ match v {
+ 0x00 => Ok(Self::Standard),
+ 0x20 => Ok(Self::Class),
+ 0x40 => Ok(Self::Vendor),
+ _ => Err("type can only be 0x00, 0x20, or 0x40"),
}
}
}
@@ -119,17 +119,16 @@ pub enum USBSetupRecipient {
Endpoint = 0x02,
Other = 0x03,
}
-impl<T> From<T> for USBSetupRecipient
-where
- T: Into<u8>,
-{
- fn from(v: T) -> Self {
- match v.into() {
- 0x00 => Self::Device,
- 0x01 => Self::Interface,
- 0x02 => Self::Endpoint,
- 0x03 => Self::Other,
- _ => panic!("recipient can only be between 0 and 3"),
+impl TryFrom<u8> for USBSetupRecipient {
+ type Error = &'static str;
+
+ fn try_from(v: u8) -> Result<Self, Self::Error> {
+ match v {
+ 0x00 => Ok(Self::Device),
+ 0x01 => Ok(Self::Interface),
+ 0x02 => Ok(Self::Endpoint),
+ 0x03 => Ok(Self::Other),
+ _ => Err("recipient can only be between 0 and 3"),
}
}
}
@@ -165,10 +164,10 @@ impl RequestType {
))
}
- pub fn recipient(&self) -> USBSetupRecipient {
+ pub fn recipient(&self) -> Result<USBSetupRecipient, &'static str> {
const POS: u8 = 0;
const MASK: u8 = 0x1f;
- (self.0 & (MASK << POS)).into()
+ (self.0 & (MASK << POS)).try_into()
}
pub fn set_recipient(&mut self, v: USBSetupRecipient) {
@@ -178,10 +177,10 @@ impl RequestType {
self.0 |= v as u8 & MASK;
}
- pub fn typ(&self) -> USBSetupType {
+ pub fn typ(&self) -> Result<USBSetupType, &'static str> {
const POS: u8 = 5;
const MASK: u8 = 0x3;
- (self.0 & (MASK << POS)).into()
+ (self.0 & (MASK << POS)).try_into()
}
pub fn set_typ(&mut self, v: USBSetupType) {
@@ -191,10 +190,10 @@ impl RequestType {
self.0 |= v as u8 & MASK;
}
- pub fn direction(&self) -> USBSetupDirection {
+ pub fn direction(&self) -> Result<USBSetupDirection, &'static str> {
const POS: u8 = 7;
const MASK: u8 = 0x1;
- (self.0 & (MASK << POS)).into()
+ (self.0 & (MASK << POS)).try_into()
}
pub fn set_direction(&mut self, v: USBSetupDirection) {
@@ -204,11 +203,6 @@ impl RequestType {
self.0 |= v as u8 & MASK;
}
}
-impl From<u8> for RequestType {
- fn from(v: u8) -> Self {
- Self(v)
- }
-}
impl From<(USBSetupDirection, USBSetupType, USBSetupRecipient)> for RequestType {
fn from(v: (USBSetupDirection, USBSetupType, USBSetupRecipient)) -> Self {
Self(v.0 as u8 | v.1 as u8 | v.2 as u8)
@@ -268,24 +262,23 @@ pub enum RequestCode {
SetInterface = 11,
SynchFrame = 12,
}
-impl<T> From<T> for RequestCode
-where
- T: Into<u8>,
-{
- fn from(v: T) -> Self {
- match v.into() {
- 0 => Self::GetStatus,
- 1 => Self::ClearFeature,
- 3 => Self::SetFeature,
- 5 => Self::SetAddress,
- 6 => Self::GetDescriptor,
- 7 => Self::SetDescriptor,
- 8 => Self::GetConfiguration,
- 9 => Self::SetConfiguration,
- 10 => Self::GetInterface,
- 11 => Self::SetInterface,
- 12 => Self::SynchFrame,
- _ => panic!("invalid request value"),
+impl TryFrom<u8> for RequestCode {
+ type Error = &'static str;
+
+ fn try_from(v: u8) -> Result<Self, Self::Error> {
+ match v {
+ 0 => Ok(Self::GetStatus),
+ 1 => Ok(Self::ClearFeature),
+ 3 => Ok(Self::SetFeature),
+ 5 => Ok(Self::SetAddress),
+ 6 => Ok(Self::GetDescriptor),
+ 7 => Ok(Self::SetDescriptor),
+ 8 => Ok(Self::GetConfiguration),
+ 9 => Ok(Self::SetConfiguration),
+ 10 => Ok(Self::GetInterface),
+ 11 => Ok(Self::SetInterface),
+ 12 => Ok(Self::SynchFrame),
+ _ => Err("invalid request value"),
}
}
}