aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-09-24 10:56:28 -0400
committerBrian Cully <bjc@kublai.com>2019-09-24 10:56:28 -0400
commitba1cd9f1b3cd3343dff4663ad1e717e345971827 (patch)
tree6c4f1a7069529276dc9de6116b62423adbda9adf
parentfcc6951c707144ba423b81e03bc2f34b6cfa7286 (diff)
downloadatsamd-usb-host-ba1cd9f1b3cd3343dff4663ad1e717e345971827.tar.gz
atsamd-usb-host-ba1cd9f1b3cd3343dff4663ad1e717e345971827.zip
Reset the USB host driver if an unrecoverable error is found.
-rw-r--r--src/lib.rs21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 423cb84..122c412 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -54,7 +54,7 @@ enum AttachedState {
enum SteadyState {
Configuring,
Running,
- Error,
+ ErrorUntil(usize),
}
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -67,6 +67,10 @@ enum TaskState {
use core::mem::{self, MaybeUninit};
use core::ptr;
+/// How long to wait after a permanent error before resetting the
+/// host.
+const ERROR_RESET_DELAY: usize = 200;
+
const MAX_DEVICES: usize = 4;
struct DeviceTable {
tbl: [Option<Device>; MAX_DEVICES],
@@ -360,7 +364,9 @@ where
Ok(_) => TaskState::Steady(SteadyState::Running),
Err(e) => {
warn!("Enumeration error: {:?}", e);
- TaskState::Steady(SteadyState::Error)
+ TaskState::Steady(SteadyState::ErrorUntil(
+ (self.millis)() + ERROR_RESET_DELAY,
+ ))
}
}
}
@@ -372,12 +378,21 @@ where
if let DriverError::Permanent(a, _) = e {
d.remove_device(a);
self.devices.remove(a);
+ self.task_state = TaskState::Steady(SteadyState::ErrorUntil(
+ (self.millis)() + ERROR_RESET_DELAY,
+ ))
}
}
}
}
- SteadyState::Error => {}
+ // TODO: this is too heavy-handed: resetting the whole
+ // device when only one may be a problem.
+ SteadyState::ErrorUntil(when) => {
+ if (self.millis)() >= when {
+ self.task_state = TaskState::Detached(DetachedState::Initialize);
+ }
+ }
}
}