aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-10 18:59:42 -0400
committerBrian Cully <bjc@kublai.com>2019-08-10 18:59:42 -0400
commite5cff55c1dc5a9862ce4e78e3af816bbc5e1550b (patch)
tree44842175008c0183a46259240addfb623bd13cec
parent0a8c0daa9f48093682a3197ad24d37c16dc32c99 (diff)
downloadatsamd-usb-host-e5cff55c1dc5a9862ce4e78e3af816bbc5e1550b.tar.gz
atsamd-usb-host-e5cff55c1dc5a9862ce4e78e3af816bbc5e1550b.zip
Use ring buffer for USB events.
Get rid of the static mut that can drop intermediate events and cause innumerable race conditions.
-rw-r--r--src/lib.rs80
1 files changed, 24 insertions, 56 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 2c1cf5f..93a3993 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -38,9 +38,6 @@ const SETTLE_DELAY: usize = 205; // Delay in sec/1024
// Ring buffer for sharing events from interrupt context.
static mut EVENTS: Events = Events::new(Event::Error);
-// FIXME: this is just for testing. The enum needs to be
-// thread-safe if this is the way we're going.
-static mut LATEST_EVENT: Event = Event::Detached;
#[derive(Clone, Copy, Debug, PartialEq)]
enum DetachedState {
@@ -243,33 +240,30 @@ where
}
pub fn task(&mut self, drivers: &mut [&mut dyn Driver]) {
- static mut LAST_EVENT: Event = Event::Error;
- unsafe {
- if LAST_EVENT != LATEST_EVENT {
- trace!("new event: {:?}", LATEST_EVENT);
- }
- }
-
static mut LAST_TASK_STATE: TaskState = TaskState::Detached(DetachedState::Illegal);
- self.task_state = match unsafe { LATEST_EVENT } {
- Event::Error => TaskState::Detached(DetachedState::Illegal),
- Event::Detached => {
- if let TaskState::Detached(_) = self.task_state {
- self.task_state
- } else {
- TaskState::Detached(DetachedState::Initialize)
+
+ if let Some(event) = self.events.shift() {
+ trace!("Found event: {:?}", event);
+ self.task_state = match event {
+ Event::Error => TaskState::Detached(DetachedState::Illegal),
+ Event::Detached => {
+ if let TaskState::Detached(_) = self.task_state {
+ self.task_state
+ } else {
+ TaskState::Detached(DetachedState::Initialize)
+ }
}
- }
- Event::Attached => {
- if let TaskState::Detached(_) = self.task_state {
- TaskState::Attached(AttachedState::WaitForSettle(
- (self.millis)() + SETTLE_DELAY,
- ))
- } else {
- self.task_state
+ Event::Attached => {
+ if let TaskState::Detached(_) = self.task_state {
+ TaskState::Attached(AttachedState::WaitForSettle(
+ (self.millis)() + SETTLE_DELAY,
+ ))
+ } else {
+ self.task_state
+ }
}
- }
- };
+ };
+ }
static mut LAST_CBITS: u16 = 0;
static mut LAST_FLAGS: u16 = 0;
@@ -290,34 +284,9 @@ where
LAST_TASK_STATE = self.task_state
};
- if let Some(_event) = self.events.shift() {
- // trace!("Found event: {:?}", event);
- // self.task_state = match event {
- // Event::None => TaskState::Detached(DetachedState::Illegal),
- // Event::Detached => {
- // if let TaskState::Detached(_) = self.task_state {
- // self.task_state
- // } else {
- // TaskState::Detached(DetachedState::Initialize)
- // }
- // }
- // Event::Attached => {
- // if let TaskState::Detached(_) = self.task_state {
- // self.delay = self.millis() + SETTLE_DELAY;
- // TaskState::Attached(AttachedState::WaitForSettle)
- // } else {
- // self.task_state
- // }
- // }
- // };
- }
-
self.fsm(drivers);
-
- unsafe {
- LAST_EVENT = LATEST_EVENT;
- }
}
+
fn fsm(&mut self, drivers: &mut [&mut dyn Driver]) {
// respond to events from interrupt.
match self.task_state {
@@ -514,9 +483,8 @@ pub fn handler(usbp: usize, events: &mut EventWriter) {
trace!("USB - {:x}", flags.bits());
let mut unshift_event = |e: Event| {
- unsafe { LATEST_EVENT = e };
- if let Err(_) = events.unshift(e) {
- error!("Couldn't write USB event to queue.");
+ if let Err(e) = events.unshift(e) {
+ error!("Couldn't write USB event to queue: {:?}", e);
}
};