Skip to content

Instantly share code, notes, and snippets.

@elfmimi
Last active January 1, 2025 13:09
Show Gist options
  • Save elfmimi/a52416d87c1b616cd9c7145a6e272fe6 to your computer and use it in GitHub Desktop.
Save elfmimi/a52416d87c1b616cd9c7145a6e272fe6 to your computer and use it in GitHub Desktop.
example of testing the behaviour of the nusb crate
[package]
name = "nusb-cmsis-dap"
version = "0.1.0"
authors = ["Ein Terakawa <[email protected]>"]
edition = "2021"
description = "nusb crate test"
# repository = "https://gist.github.com/elfmimi/a52416d87c1b616cd9c7145a6e272fe6"
# keywords = ["usb"]
# categories = ["command-line-utilities", "development-tools", "embedded"]
# license = "MIT OR Apache-2.0"
# readme = "README.md"
[dependencies]
nusb = "0.1.12"
# nusb = "0.2.0-beta"
log = { version = "0.4", features = ["std"] }
pretty_env_logger = "0.5"
async-io = "2"
futures-lite = { version = "2", default-features = false }
[[bin]]
path = "main.rs"
name = "nusb-cmsis-dap"
# [patch.crates-io]
# nusb = { path = "../nusb" }
// #![allow(unused)]
// #![allow(unused_imports)]
// use nusb::{DeviceInfo, InterfaceInfo, Speed, Device, Interface};
use nusb::transfer::RequestBuffer;
use futures_lite::FutureExt;
// use futures_lite::future;
use async_io::{block_on, Timer};
use std::time::Duration;
#[allow(unused_imports)]
use std::thread::sleep;
const VID_PID_LIST: [(u16, u16); 2] = [(0x0D28, 0x0204), (0x2E8A, 0x000C)];
fn main() {
pretty_env_logger::init();
log::trace!("initialized logger");
nusb_test();
println!("OK");
}
fn dump_buf(buf: &[u8]) {
let len = buf.len();
for i in 0..len {
print!("{:02X}", buf[i]);
if i % 16 == 15 || i == len - 1 {
println!();
} else if i % 16 == 7 {
print!(", ");
} else {
print!(", ");
}
}
}
fn nusb_test() -> () {
let dev_info = nusb::list_devices().unwrap()
.find(|dev| VID_PID_LIST.contains(&(dev.vendor_id(), dev.product_id())))
.expect("CMSIS-DAP probes not connected");
let mut iface_num = None;
for x in dev_info.interfaces() {
if x.class() == 0xFF && x.subclass() == 0 && x.protocol() == 0 {
if x.interface_string().expect("No interface string").contains("CMSIS-DAP") {
iface_num = Some(x.interface_number());
}
}
}
let iface_num = iface_num.expect("No interface found");
let dev = dev_info.open().expect("Device open failed");
let conf = dev.configurations().nth(0).unwrap();
let iface_group = conf.interfaces().find(|ig| ig.alt_settings().nth(0).unwrap().interface_number() == iface_num).unwrap();
let iface_alt_setting = iface_group.alt_settings().nth(0).unwrap();
let out_ep = iface_alt_setting.endpoints().nth(0).expect("No endpoint").address();
let in_ep = iface_alt_setting.endpoints().nth(1).expect("No endpoint").address();
let iface = dev.claim_interface(iface_num).expect("Claim interface failed");
let fut = async {
let comp = iface.bulk_in(in_ep, RequestBuffer::new(64)).await;
comp.data.len()
};
let _ = block_on( fut.or(async {
println!("Start Timeout");
Timer::after(Duration::from_millis(10)).await;
println!("End Timeout");
0
}));
// to wait completion of cancelled transfer
// sleep(Duration::from_millis(1));
let buf: [u8; 2] = [ 0, 0xF0 ]; // Info , Capabilities
let _ = block_on( async { iface.bulk_out(out_ep, buf.to_vec()).await } );
println!("bulk_out done");
let mut buf: [u8; 64] = [0; 64];
let n = block_on( async {
let comp = iface.bulk_in(in_ep, RequestBuffer::new(buf.len())).await;
comp.status.map_err(nusb::Error::other).unwrap();
let n = comp.data.len();
buf[..n].copy_from_slice(&comp.data);
n
} );
println!("recv {} bytes", n);
dump_buf(&buf[..n]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment