Skip to content

Commit f7dc178

Browse files
authored
Update nusb to 0.2 (probe-rs#3562)
1 parent 2d852ec commit f7dc178

File tree

19 files changed

+591
-355
lines changed

19 files changed

+591
-355
lines changed

Cargo.lock

Lines changed: 217 additions & 157 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Updated nusb dependency to version 0.2.0

probe-rs/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ exclude = ["tests/"]
2222
[features]
2323
default = ["builtin-targets", "cmsisdap_v1"]
2424

25+
2526
# Enable all built in targets.
2627
builtin-targets = ["dep:bincode", "dep:serde_yaml", "dep:probe-rs-target"]
2728
cmsisdap_v1 = ["dep:hidapi"]
@@ -51,7 +52,7 @@ object = { version = "0.37", default-features = false, features = [
5152
"read_core",
5253
"std",
5354
] }
54-
nusb = "0.1.12"
55+
nusb = "0.2.1"
5556
futures-lite = { version = "2", default-features = false }
5657
scroll = "0.13"
5758
serialport = { version = "4.7.0", default-features = false, features = [

probe-rs/src/probe/ch347usbjtag/protocol.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::time::Duration;
22

33
use bitvec::vec::BitVec;
4-
use nusb::{DeviceInfo, Interface};
4+
use nusb::{DeviceInfo, Interface, MaybeFuture};
55

66
use crate::probe::{
77
self, DebugProbeError, DebugProbeInfo, DebugProbeSelector, ProbeCreationError,
@@ -83,13 +83,18 @@ impl Ch347UsbJtagDevice {
8383
pub(crate) fn new_from_selector(
8484
selector: &DebugProbeSelector,
8585
) -> Result<Self, ProbeCreationError> {
86-
let device = nusb::list_devices()
87-
.map_err(ProbeCreationError::Usb)?
86+
let devices = nusb::list_devices()
87+
.wait()
88+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
89+
let device = devices
8890
.filter(is_ch34x_device)
8991
.find(|device| selector.matches(device))
9092
.ok_or(ProbeCreationError::NotFound)?;
9193

92-
let device_handle = device.open().map_err(probe::ProbeCreationError::Usb)?;
94+
let device_handle = device
95+
.open()
96+
.wait()
97+
.map_err(|e| probe::ProbeCreationError::Usb(e.into()))?;
9398

9499
let config = device_handle
95100
.configurations()
@@ -118,9 +123,9 @@ impl Ch347UsbJtagDevice {
118123
// ch347t default interface number is 2
119124
let interface = device_handle
120125
.claim_interface(CH347F_INTERFACE_NUM)
121-
.or(device_handle
122-
.claim_interface(CH347T_INTERFACE_NUM)
123-
.map_err(ProbeCreationError::Usb))?;
126+
.wait()
127+
.or(device_handle.claim_interface(CH347T_INTERFACE_NUM).wait())
128+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
124129

125130
// set 15MHz speed, and check pack mode
126131
let mut obuf = [0xD0, 0x06, 0x00, 0x00, 0x07, 0x30, 0x30, 0x30, 0x30];
@@ -281,21 +286,23 @@ impl Ch347UsbJtagDevice {
281286
}
282287

283288
pub(super) fn list_ch347usbjtag_devices() -> Vec<DebugProbeInfo> {
284-
let Ok(devices) = nusb::list_devices() else {
285-
return vec![];
286-
};
287-
288-
devices
289-
.filter(is_ch34x_device)
290-
.map(|device| {
291-
DebugProbeInfo::new(
292-
"CH347 USB Jtag".to_string(),
293-
device.vendor_id(),
294-
device.product_id(),
295-
device.serial_number().map(Into::into),
296-
&Ch347UsbJtagFactory,
297-
None,
298-
)
299-
})
300-
.collect()
289+
match nusb::list_devices().wait() {
290+
Ok(devices) => devices
291+
.filter(is_ch34x_device)
292+
.map(|device| {
293+
DebugProbeInfo::new(
294+
"CH347 USB Jtag".to_string(),
295+
device.vendor_id(),
296+
device.product_id(),
297+
device.serial_number().map(Into::into),
298+
&Ch347UsbJtagFactory,
299+
None,
300+
)
301+
})
302+
.collect(),
303+
Err(e) => {
304+
tracing::warn!("error listing CH347 devices: {e}");
305+
vec![]
306+
}
307+
}
301308
}

probe-rs/src/probe/cmsisdap/tools.rs

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use crate::probe::{
55
};
66
#[cfg(feature = "cmsisdap_v1")]
77
use hidapi::HidApi;
8-
use nusb::{
9-
DeviceInfo,
10-
transfer::{Direction, EndpointType},
11-
};
8+
use nusb::{DeviceInfo, MaybeFuture, descriptors::TransferType, transfer::Direction};
129

1310
const USB_CLASS_HID: u8 = 0x03;
1411

@@ -22,12 +19,12 @@ pub fn list_cmsisdap_devices() -> Vec<DebugProbeInfo> {
2219
tracing::debug!("Searching for CMSIS-DAP probes using nusb");
2320

2421
#[cfg_attr(not(feature = "cmsisdap_v1"), expect(unused_mut))]
25-
let mut probes = match nusb::list_devices() {
22+
let mut probes = match nusb::list_devices().wait() {
2623
Ok(devices) => devices
2724
.filter_map(|device| get_cmsisdap_info(&device))
2825
.collect(),
2926
Err(e) => {
30-
tracing::warn!("error listing devices with nusb: {:?}", e);
27+
tracing::warn!("error listing devices with nusb: {e}");
3128
vec![]
3229
}
3330
};
@@ -157,8 +154,17 @@ pub fn open_v2_device(
157154
let vid = device_info.vendor_id();
158155
let pid = device_info.product_id();
159156

160-
let Some(device) = device_info.open().ok() else {
161-
return Ok(None);
157+
let device = match device_info.open().wait() {
158+
Ok(device) => device,
159+
Err(e) => {
160+
tracing::debug!(
161+
vendor_id = %format!("{vid:04x}"),
162+
product_id = %format!("{pid:04x}"),
163+
error = %e,
164+
"failed to open device for CMSIS-DAP v2"
165+
);
166+
return Ok(None);
167+
}
162168
};
163169

164170
// Go through interfaces to try and find a v2 interface.
@@ -193,28 +199,28 @@ pub fn open_v2_device(
193199
let eps: Vec<_> = i_desc.endpoints().collect();
194200

195201
// Check the first endpoint is bulk out
196-
if eps[0].transfer_type() != EndpointType::Bulk || eps[0].direction() != Direction::Out
202+
if eps[0].transfer_type() != TransferType::Bulk || eps[0].direction() != Direction::Out
197203
{
198204
continue;
199205
}
200206

201207
// Check the second endpoint is bulk in
202-
if eps[1].transfer_type() != EndpointType::Bulk || eps[1].direction() != Direction::In {
208+
if eps[1].transfer_type() != TransferType::Bulk || eps[1].direction() != Direction::In {
203209
continue;
204210
}
205211

206212
// Detect a third bulk EP which will be for SWO streaming
207213
let mut swo_ep = None;
208214

209215
if eps.len() > 2
210-
&& eps[2].transfer_type() == EndpointType::Bulk
216+
&& eps[2].transfer_type() == TransferType::Bulk
211217
&& eps[2].direction() == Direction::In
212218
{
213219
swo_ep = Some((eps[2].address(), eps[2].max_packet_size()));
214220
}
215221

216222
// Attempt to claim this interface
217-
match device.claim_interface(interface.interface_number()) {
223+
match device.claim_interface(interface.interface_number()).wait() {
218224
Ok(handle) => {
219225
tracing::debug!("Opening {:04x}:{:04x} in CMSIS-DAPv2 mode", vid, pid);
220226
reject_probe_by_version(
@@ -230,7 +236,14 @@ pub fn open_v2_device(
230236
max_packet_size: eps[1].max_packet_size(),
231237
}));
232238
}
233-
Err(_) => continue,
239+
Err(e) => {
240+
tracing::debug!(
241+
interface = interface.interface_number(),
242+
error = %e,
243+
"failed to claim interface"
244+
);
245+
continue;
246+
}
234247
}
235248
}
236249
}
@@ -290,25 +303,28 @@ pub fn open_device_from_selector(
290303
// Try using nusb to open a v2 device. This might fail if
291304
// the device does not support v2 operation or due to driver
292305
// or permission issues with opening bulk devices.
293-
if let Ok(devices) = nusb::list_devices() {
294-
for device in devices {
295-
tracing::trace!("Trying device {:?}", device);
296-
297-
if selector.matches(&device) {
298-
hid_device_info = get_cmsisdap_info(&device);
299-
300-
if hid_device_info.is_some() {
301-
// If the VID, PID, and potentially SN all match,
302-
// and the device is a valid CMSIS-DAP probe,
303-
// attempt to open the device in v2 mode.
304-
if let Some(device) = open_v2_device(&device)? {
305-
return Ok(device);
306+
match nusb::list_devices().wait() {
307+
Ok(devices) => {
308+
for device in devices {
309+
tracing::trace!("Trying device {:?}", device);
310+
311+
if selector.matches(&device) {
312+
hid_device_info = get_cmsisdap_info(&device);
313+
314+
if hid_device_info.is_some() {
315+
// If the VID, PID, and potentially SN all match,
316+
// and the device is a valid CMSIS-DAP probe,
317+
// attempt to open the device in v2 mode.
318+
if let Some(device) = open_v2_device(&device)? {
319+
return Ok(device);
320+
}
306321
}
307322
}
308323
}
309324
}
310-
} else {
311-
tracing::debug!("No devices matched using nusb");
325+
Err(e) => {
326+
tracing::debug!("No devices matched using nusb: {e}");
327+
}
312328
}
313329

314330
#[cfg(not(feature = "cmsisdap_v1"))]

probe-rs/src/probe/espusbjtag/protocol.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use bitvec::prelude::*;
2-
use nusb::{
3-
DeviceInfo,
4-
transfer::{Direction, EndpointType},
5-
};
2+
use nusb::{DeviceInfo, MaybeFuture, descriptors::TransferType, transfer::Direction};
63
use std::{
74
fmt::Debug,
85
time::{Duration, Instant},
@@ -86,13 +83,18 @@ impl Debug for ProtocolHandler {
8683

8784
impl ProtocolHandler {
8885
pub fn new_from_selector(selector: &DebugProbeSelector) -> Result<Self, ProbeCreationError> {
89-
let device = nusb::list_devices()
90-
.map_err(ProbeCreationError::Usb)?
86+
let devices = nusb::list_devices()
87+
.wait()
88+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
89+
let device = devices
9190
.filter(is_espjtag_device)
9291
.find(|device| selector.matches(device))
9392
.ok_or(ProbeCreationError::NotFound)?;
9493

95-
let device_handle = device.open().map_err(ProbeCreationError::Usb)?;
94+
let device_handle = device
95+
.open()
96+
.wait()
97+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
9698

9799
tracing::debug!("Aquired handle for probe");
98100

@@ -124,7 +126,7 @@ impl ProtocolHandler {
124126
for endpoint in descriptor.endpoints() {
125127
let address = endpoint.address();
126128
tracing::trace!("Endpoint {address:#04x}");
127-
if endpoint.transfer_type() != EndpointType::Bulk {
129+
if endpoint.transfer_type() != TransferType::Bulk {
128130
tracing::debug!("Skipping endpoint {address:#04x}");
129131
continue;
130132
}
@@ -152,7 +154,8 @@ impl ProtocolHandler {
152154

153155
let iface = device_handle
154156
.claim_interface(interface_number)
155-
.map_err(ProbeCreationError::Usb)?;
157+
.wait()
158+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
156159

157160
let start = Instant::now();
158161
let buffer = loop {
@@ -163,7 +166,8 @@ impl ProtocolHandler {
163166
0,
164167
USB_TIMEOUT,
165168
)
166-
.map_err(ProbeCreationError::Usb)?;
169+
.wait()
170+
.map_err(|e| ProbeCreationError::Usb(e.into()))?;
167171
if !buffer.is_empty() {
168172
break buffer;
169173
}
@@ -533,21 +537,23 @@ pub(super) fn is_espjtag_device(device: &DeviceInfo) -> bool {
533537

534538
#[tracing::instrument(skip_all)]
535539
pub(super) fn list_espjtag_devices() -> Vec<DebugProbeInfo> {
536-
let Ok(devices) = nusb::list_devices() else {
537-
return vec![];
538-
};
539-
540-
devices
541-
.filter(is_espjtag_device)
542-
.map(|device| {
543-
DebugProbeInfo::new(
544-
"ESP JTAG".to_string(),
545-
device.vendor_id(),
546-
device.product_id(),
547-
device.serial_number().map(Into::into),
548-
&EspUsbJtagFactory,
549-
None,
550-
)
551-
})
552-
.collect()
540+
match nusb::list_devices().wait() {
541+
Ok(devices) => devices
542+
.filter(is_espjtag_device)
543+
.map(|device| {
544+
DebugProbeInfo::new(
545+
"ESP JTAG".to_string(),
546+
device.vendor_id(),
547+
device.product_id(),
548+
device.serial_number().map(Into::into),
549+
&EspUsbJtagFactory,
550+
None,
551+
)
552+
})
553+
.collect(),
554+
Err(e) => {
555+
tracing::warn!("error listing ESP USB JTAG devices: {e}");
556+
vec![]
557+
}
558+
}
553559
}

probe-rs/src/probe/ftdi/ftdaye/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use nusb::descriptors::ActiveConfigurationError;
1+
use nusb::ActiveConfigurationError;
22

33
use crate::probe::{ProbeError, ftdi::ftdaye::ChipType};
44

@@ -10,7 +10,7 @@ pub enum FtdiError {
1010
/// operation. It may indicate that the USB device was unplugged, that another application or an
1111
/// operating system driver is currently using it, or that the current user does not have
1212
/// permission to access it.
13-
Usb(#[from] nusb::Error),
13+
Usb(#[from] std::io::Error),
1414

1515
#[error("Unsupported chip type: {0:?}")]
1616
/// The connected device is not supported by the driver.

0 commit comments

Comments
 (0)