Skip to content

A Rust USB library which works on both native and WASM targets

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

G2-Games/cross-usb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cross USB

Lib.rs Version docs.rs

A USB library which works seamlessly across most native and WASM targets.


Note

Web USB only works in Chromium based browsers for now.

Note

Web USB has certain interaction requirements in browsers, along with requiring a Secure context. Please read more about this on the mdn web docs

Important

When compiling this crate on a WASM target, you must use either the rustflags RUSTFLAGS=--cfg=web_sys_unstable_apis or by passing the argument in a .cargo/config.toml file. Read more here: https://rustwasm.github.io/wasm-bindgen/web-sys/unstable-apis.html

Dependencies

For native USB, the crate utilizies nusb, a pure rust library similar to the very popular libusb. If you don't need WASM support, just using nusb is the way to go!

For WASM, this crate utilizes web-sys which gives access to browser API calls, and in this case is used to interact with WebUSB.

Example

To learn about how USB communciations work, check out USB in a NutShell.

use cross_usb::prelude::*;
use cross_usb::usb::{Recipient, ControlType, ControlIn};
use cross_usb::device_filter;

// Obtain a device descriptor using a DeviceFilter,
// in this case with its VendorID and ProductID
let filters = vec![
    device_filter!{vendor_id: 0x054c, product_id: 0x00c9}
];
let dev_descriptor = cross_usb::get_device(filters).await.expect("Failed to find device");

// Open the device that the descriptor is describing
let dev = dev_descriptor.open().await.expect("Failed to open device");

// Obtain an interface of the device
let interface = dev.open_interface(0).await.expect("Failed to open interface");

// Send a Control transfer to the device, obtaining
// the result and storing it in `result`
let result = interface.control_in(ControlIn {
        control_type: ControlType::Vendor,
        recipient: Recipient::Interface,
        request: 0x01,
        value: 0,
        index: 0,
        length: 4,
    })
    .await
    .expect("Sending control transfer failed");

Check out the documentation as well!

TODO

  • Add choice for native backend between libusb wrapper and pure rust nusb
  • Allow platform-specific operations if the user requires them
  • Hot plug support... requires either using libusb as an optional backend or for nusb to implement it