Skip to content

Commit fbf903e

Browse files
authored
Merge pull request #142 from rust-embedded-community/feature/usb-tracing
Adding USB tracing, fixing further enumeration issues
2 parents 232decb + 610aded commit fbf903e

File tree

6 files changed

+129
-28
lines changed

6 files changed

+129
-28
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Added
11+
* A new `log` feature can be enabled to provide logging and tracing information about the USB
12+
interface.
13+
1014
### Changed
1115
* Invalid LangIDs will default to `EN_US`
16+
* Changed handling of EP0 state to eliminate unexpected issues with device enumeration
1217

1318
## [0.3.1] - 2023-11-15
1419

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ defmt = { version = "0.3", optional = true }
1414
portable-atomic = { version = "1.2.0", default-features = false }
1515
num_enum = { version = "0.7.1", default-features = false }
1616
heapless = "0.8"
17+
log = { version = "0.4", default-features = false, optional = true}
1718

1819
[dev-dependencies]
1920
rusb = "0.9.1"
@@ -23,6 +24,9 @@ rand = "0.8.5"
2324
# Use a 256 byte buffer for control transfers instead of 128.
2425
control-buffer-256 = []
2526

27+
# Enable logging and tracing via the `log` crate
28+
log = ["dep:log"]
29+
2630
# Use larger endpoint buffers for highspeed operation (default fullspeed)
2731
#
2832
# Note: usb-device doesn't truly support high speed enumeration yet, so setting this will make

src/control_pipe.rs

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,26 @@ impl<B: UsbBus> ControlPipe<'_, B> {
6363
}
6464

6565
pub fn reset(&mut self) {
66+
usb_trace!("Control pipe reset");
6667
self.state = ControlState::Idle;
6768
}
6869

6970
pub fn handle_setup(&mut self) -> Option<Request> {
7071
let count = match self.ep_out.read(&mut self.buf[..]) {
71-
Ok(count) => count,
72+
Ok(count) => {
73+
usb_trace!("Read {} bytes on EP0-OUT: {:?}", count, &self.buf[..count]);
74+
count
75+
}
7276
Err(UsbError::WouldBlock) => return None,
7377
Err(_) => {
74-
self.set_error();
7578
return None;
7679
}
7780
};
7881

7982
let req = match Request::parse(&self.buf[0..count]) {
8083
Ok(req) => req,
8184
Err(_) => {
82-
// Failed to parse SETUP packet
83-
self.set_error();
85+
// Failed to parse SETUP packet. We are supposed to silently ignore this.
8486
return None;
8587
}
8688
};
@@ -89,6 +91,8 @@ impl<B: UsbBus> ControlPipe<'_, B> {
8991
// a stalled state.
9092
self.ep_out.unstall();
9193

94+
usb_debug!("EP0 request received: {:?}", req);
95+
9296
/*sprintln!("SETUP {:?} {:?} {:?} req:{} val:{} idx:{} len:{} {:?}",
9397
req.direction, req.request_type, req.recipient,
9498
req.request, req.value, req.index, req.length,
@@ -102,7 +106,6 @@ impl<B: UsbBus> ControlPipe<'_, B> {
102106

103107
if req.length as usize > self.buf.len() {
104108
// Data stage won't fit in buffer
105-
self.set_error();
106109
return None;
107110
}
108111

@@ -141,9 +144,15 @@ impl<B: UsbBus> ControlPipe<'_, B> {
141144
}
142145
};
143146

147+
usb_trace!(
148+
"Read {} bytes on EP0-OUT: {:?}",
149+
count,
150+
&self.buf[i..(i + count)]
151+
);
144152
self.i += count;
145153

146154
if self.i >= self.len {
155+
usb_debug!("Request OUT complete: {:?}", req);
147156
self.state = ControlState::CompleteOut;
148157
return Some(req);
149158
}
@@ -154,11 +163,19 @@ impl<B: UsbBus> ControlPipe<'_, B> {
154163
| ControlState::DataInLast
155164
| ControlState::DataInZlp
156165
| ControlState::StatusOut => {
166+
usb_debug!(
167+
"Control transfer completed. Current state: {:?}",
168+
self.state
169+
);
157170
let _ = self.ep_out.read(&mut []);
158171
self.state = ControlState::Idle;
159172
}
160173
_ => {
161174
// Discard the packet
175+
usb_debug!(
176+
"Discarding EP0 data due to unexpected state. Current state: {:?}",
177+
self.state
178+
);
162179
let _ = self.ep_out.read(&mut []);
163180

164181
// Unexpected OUT packet
@@ -181,6 +198,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
181198
return false;
182199
}
183200

201+
usb_trace!("wrote EP0: ZLP");
184202
self.state = ControlState::DataInLast;
185203
}
186204
ControlState::DataInLast => {
@@ -197,8 +215,9 @@ impl<B: UsbBus> ControlPipe<'_, B> {
197215
// IN-complete status. Just ignore this indication.
198216
}
199217
_ => {
200-
// Unexpected IN packet
201-
self.set_error();
218+
// If we get IN-COMPLETE indications in unexpected states, it's generally because
219+
// of control flow in previous phases updating after our packet was successfully
220+
// sent. Ignore these indications if they don't drive any further behavior.
202221
}
203222
};
204223

@@ -213,9 +232,14 @@ impl<B: UsbBus> ControlPipe<'_, B> {
213232
Ok(c) => c,
214233
// There isn't much we can do if the write fails, except to wait for another poll or for
215234
// the host to resend the request.
216-
Err(_) => return,
235+
Err(_err) => {
236+
usb_debug!("Failed to write EP0: {:?}", _err);
237+
return;
238+
}
217239
};
218240

241+
usb_trace!("wrote EP0: {:?}", &buffer[self.i..(self.i + count)]);
242+
219243
self.i += count;
220244

221245
if self.i >= self.len {
@@ -232,7 +256,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
232256
pub fn accept_out(&mut self) -> Result<()> {
233257
match self.state {
234258
ControlState::CompleteOut => {}
235-
_ => return Err(UsbError::InvalidState),
259+
_ => {
260+
usb_debug!("Cannot ACK, invalid state: {:?}", self.state);
261+
return Err(UsbError::InvalidState);
262+
}
236263
};
237264

238265
let _ = self.ep_in.write(&[]);
@@ -243,7 +270,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
243270
pub fn accept_in(&mut self, f: impl FnOnce(&mut [u8]) -> Result<usize>) -> Result<()> {
244271
let req = match self.state {
245272
ControlState::CompleteIn(req) => req,
246-
_ => return Err(UsbError::InvalidState),
273+
_ => {
274+
usb_debug!("EP0-IN cannot ACK, invalid state: {:?}", self.state);
275+
return Err(UsbError::InvalidState);
276+
}
247277
};
248278

249279
let len = f(&mut self.buf[..])?;
@@ -259,7 +289,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
259289
pub fn accept_in_static(&mut self, data: &'static [u8]) -> Result<()> {
260290
let req = match self.state {
261291
ControlState::CompleteIn(req) => req,
262-
_ => return Err(UsbError::InvalidState),
292+
_ => {
293+
usb_debug!("EP0-IN cannot ACK, invalid state: {:?}", self.state);
294+
return Err(UsbError::InvalidState);
295+
}
263296
};
264297

265298
self.static_in_buf = Some(data);
@@ -277,6 +310,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
277310
}
278311

279312
pub fn reject(&mut self) -> Result<()> {
313+
usb_debug!("EP0 transfer rejected");
280314
if !self.waiting_for_response() {
281315
return Err(UsbError::InvalidState);
282316
}
@@ -286,6 +320,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
286320
}
287321

288322
fn set_error(&mut self) {
323+
usb_debug!("EP0 stalled - error");
289324
self.state = ControlState::Error;
290325
self.ep_out.stall();
291326
self.ep_in.stall();

0 commit comments

Comments
 (0)