commit - /dev/null
commit + b7e0bc374d935a50b7e60e741ba7c99efcf123dd
blob - /dev/null
blob + ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba (mode 644)
--- /dev/null
+++ .gitignore
+/target
blob - /dev/null
blob + 2e341f9de998c7131836438f524b1cc63195adbd (mode 644)
--- /dev/null
+++ Cargo.lock
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anyhow"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+
+[[package]]
+name = "cc"
+version = "1.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2"
+dependencies = [
+ "shlex",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.169"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+
+[[package]]
+name = "libusb1-sys"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da050ade7ac4ff1ba5379af847a10a10a8e284181e060105bf8d86960ce9ce0f"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+
+[[package]]
+name = "ppa6"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "rusb",
+]
+
+[[package]]
+name = "rusb"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab9f9ff05b63a786553a4c02943b74b34a988448671001e9a27e2f0565cc05a4"
+dependencies = [
+ "libc",
+ "libusb1-sys",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
blob - /dev/null
blob + da9c3648d53ff4cc6cfe7806fe8bc889b6ce54ce (mode 644)
--- /dev/null
+++ Cargo.toml
+[package]
+name = "ppa6"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+anyhow = "1.0.95"
+rusb = "0.9.4"
blob - /dev/null
blob + e950f4221ea673013612454faad769ce61e482a6 (mode 644)
--- /dev/null
+++ src/main.rs
+// Very helpful doc for USB: https://www.beyondlogic.org/usbnutshell/usb1.shtml
+use rusb::{Direction, TransferType, UsbContext};
+
+const VENDOR_ID: u16 = 0x09c5;
+const PRODUCT_ID: u16 = 0x0200;
+
+fn main() {
+ println!("libusb version: {:?}", rusb::version());
+ println!("Kernel supports detaching driver: {}", rusb::supports_detach_kernel_driver());
+
+
+ let ctx = rusb::Context::new().expect("cannot connect to libusb");
+
+ // Find Peripage A6
+ let dev = ctx
+ .devices()
+ .expect("cannot read list of devices")
+ .iter()
+ .find(|dev| {
+ let Ok(desc) = dev.device_descriptor() else {
+ eprintln!("cannot get device descriptor for Bus {dev:?}");
+ return false
+ };
+
+ desc.vendor_id() == VENDOR_ID && desc.product_id() == PRODUCT_ID
+ })
+ .expect("No Peripage A6 found")
+ ;
+
+ let handle = dev.open().expect("cannot open usb device");
+
+ let dd = dev.device_descriptor().unwrap();
+ println!("Device Descriptor = {dd:#?}");
+ assert_eq!(dd.vendor_id(), VENDOR_ID);
+ assert_eq!(dd.product_id(), PRODUCT_ID);
+ if let Ok(s) = handle.read_manufacturer_string_ascii(&dd) {
+ println!("Vendor: {s}");
+ }
+ if let Ok(s) = handle.read_product_string_ascii(&dd) {
+ println!("Product: {s}");
+ }
+ if let Ok(s) = handle.read_serial_number_string_ascii(&dd) {
+ println!("Serial: {s}");
+ }
+
+ assert_eq!(dd.num_configurations(), 1);
+ let cd = dev.config_descriptor(0).unwrap();
+ println!("Config Descriptor = {cd:#?}");
+
+ assert_eq!(cd.num_interfaces(), 1);
+ let int = cd.interfaces().next().unwrap();
+ let id = int.descriptors().next().unwrap();
+ println!("Interface Descriptor = {id:#?}");
+ if let Some(sid) = id.description_string_index() {
+ println!("Interface: {}", handle.read_string_descriptor_ascii(sid).unwrap());
+ }
+ println!("Is kernel driver attached: {:?}", handle.kernel_driver_active(0));
+
+ assert_eq!(id.class_code(), 7);
+ assert_eq!(id.sub_class_code(), 1);
+ assert_eq!(id.protocol_code(), 2);
+ assert_eq!(id.num_endpoints(), 2);
+
+ let mut epds = id.endpoint_descriptors();
+ let epd0 = epds.next().unwrap();
+ let epd1 = epds.next().unwrap();
+ println!("Endpoint Descriptor 0: {epd0:#?}");
+ println!("Endpoint Descriptor 1: {epd1:#?}");
+
+ assert_eq!(epd0.address(), 129); // IN (128) + 1
+ assert_eq!(epd0.direction(), Direction::In);
+ assert_eq!(epd0.transfer_type(), TransferType::Bulk);
+
+ assert_eq!(epd1.address(), 2); // OUT (0) + 2
+ assert_eq!(epd1.direction(), Direction::Out);
+ assert_eq!(epd1.transfer_type(), TransferType::Bulk);
+
+ handle.claim_interface(0).expect("failed to claim interface 0");
+ handle.release_interface(0).expect("failed to release interface 0");
+}