aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-10-08 09:45:07 -0400
committerBrian Cully <bjc@kublai.com>2019-10-08 09:45:07 -0400
commit06ad88383540690c8ead08ac4bddd84585aeeb8c (patch)
tree0a3ed22dd1d3a0148cb21b11c3ff223de568d855
parent22cda6d6b362e47fcd5e1f8589297b43fdcb8204 (diff)
downloadatsamd-usb-host-06ad88383540690c8ead08ac4bddd84585aeeb8c.tar.gz
atsamd-usb-host-06ad88383540690c8ead08ac4bddd84585aeeb8c.zip
More messing around with data toggle error handling.
I will not pretend that I know this to be correct, but it seems to work.
-rw-r--r--src/pipe.rs90
1 files changed, 39 insertions, 51 deletions
diff --git a/src/pipe.rs b/src/pipe.rs
index 8b10dc5..fcba86c 100644
--- a/src/pipe.rs
+++ b/src/pipe.rs
@@ -326,57 +326,6 @@ impl Pipe<'_, '_> {
Ok(bytes_sent)
}
- fn dtgl(&mut self, ep: &mut dyn Endpoint, token: PToken) {
- // TODO: this makes no sense to me, and docs are unclear. If
- // the status bit is set, set it again? if it's clear then
- // clear it? This is what I get for having to work from
- // Arduino sources.
- warn!(
- "tok: {:?}, dtgl: {}, i: {}, o: {}",
- token,
- self.regs.status.read().dtgl().bit(),
- ep.in_toggle(),
- ep.out_toggle(),
- );
-
- let toggle = match token {
- PToken::In => {
- let t = !ep.in_toggle();
- ep.set_in_toggle(t);
- t
- }
-
- PToken::Out => {
- let t = !ep.out_toggle();
- ep.set_out_toggle(t);
- t
- }
-
- PToken::Setup => false,
-
- _ => !self.regs.status.read().dtgl().bit_is_set(),
- };
-
- if toggle {
- self.dtgl_set();
- } else {
- self.dtgl_clear();
- }
- }
-
- fn dtgl_set(&mut self) {
- self.regs.statusset.write(|w| w.dtgl().set_bit());
- }
-
- fn dtgl_clear(&mut self) {
- self.regs.statusclr.write(|w| unsafe {
- // FIXME: need to patch the SVD for
- // PSTATUSCLR.DTGL at bit0. No? This is in the SVD, but
- // not the rust output.
- w.bits(1)
- });
- }
-
// This is the only function that calls `millis`. If we can make
// this just take the current timestamp, we can make this
// non-blocking.
@@ -548,7 +497,46 @@ impl Pipe<'_, '_> {
}
}
+ fn dtgl(&mut self, ep: &mut dyn Endpoint, token: PToken) {
+ // TODO: this makes no sense to me, and docs are unclear. If
+ // the status bit is set, set it again? if it's clear then
+ // clear it? This is what I get for having to work from
+ // Arduino sources.
+ warn!(
+ "tok: {:?}, dtgl: {}, i: {}, o: {}",
+ token,
+ self.regs.status.read().dtgl().bit(),
+ ep.in_toggle(),
+ ep.out_toggle(),
+ );
+
+ // I'm not sure how this is supposed to work, according to the
+ // data sheet, but after much trial and error, this is what
+ // seems to work.
+ let toggle = self.regs.status.read().dtgl().bit_is_set();
+ if token == PToken::In {
+ ep.set_in_toggle(toggle);
+ } else if token == PToken::Out {
+ ep.set_out_toggle(toggle);
}
+ if toggle {
+ self.dtgl_set();
+ } else {
+ self.dtgl_clear();
+ }
+ }
+
+ fn dtgl_set(&mut self) {
+ self.regs.statusset.write(|w| w.dtgl().set_bit());
+ }
+
+ fn dtgl_clear(&mut self) {
+ self.regs.statusclr.write(|w| unsafe {
+ // FIXME: need to patch the SVD for
+ // PSTATUSCLR.DTGL at bit0. No? This is in the SVD, but
+ // not the rust output.
+ w.bits(1)
+ });
}
fn log_regs(&self) {