diff options
author | Brian Cully <bjc@kublai.com> | 2019-09-24 10:56:28 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-09-24 10:56:28 -0400 |
commit | ba1cd9f1b3cd3343dff4663ad1e717e345971827 (patch) | |
tree | 6c4f1a7069529276dc9de6116b62423adbda9adf | |
parent | fcc6951c707144ba423b81e03bc2f34b6cfa7286 (diff) | |
download | atsamd-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.rs | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -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); + } + } } } |