From 7896e8aba7d08b46700b370def152de2b03feaad Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 30 Apr 2024 09:59:06 +0200 Subject: [PATCH] rp: WebUSB example - add Windows compatibility --- examples/rp/src/bin/usb_webusb.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/rp/src/bin/usb_webusb.rs b/examples/rp/src/bin/usb_webusb.rs index 09f2c1cfd..e73938ac9 100644 --- a/examples/rp/src/bin/usb_webusb.rs +++ b/examples/rp/src/bin/usb_webusb.rs @@ -25,6 +25,7 @@ use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; use embassy_usb::class::web_usb::{Config as WebUsbConfig, State, Url, WebUsb}; use embassy_usb::driver::{Driver, Endpoint, EndpointIn, EndpointOut}; +use embassy_usb::msos::{self, windows_version}; use embassy_usb::{Builder, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -32,6 +33,9 @@ bind_interrupts!(struct Irqs { USBCTRL_IRQ => InterruptHandler; }); +// This is a randomly generated GUID to allow clients on Windows to find our device +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{AFB9A6FB-30BA-44BC-9232-806CFC875321}"]; + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); @@ -58,6 +62,7 @@ async fn main(_spawner: Spawner) { let mut config_descriptor = [0; 256]; let mut bos_descriptor = [0; 256]; let mut control_buf = [0; 64]; + let mut msos_descriptor = [0; 256]; let webusb_config = WebUsbConfig { max_packet_size: 64, @@ -73,10 +78,23 @@ async fn main(_spawner: Spawner) { config, &mut config_descriptor, &mut bos_descriptor, - &mut [], // no msos descriptors + &mut msos_descriptor, &mut control_buf, ); + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature, + // which causes it to use the built-in WinUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + // Create classes on the builder (WebUSB just needs some setup, but doesn't return anything) WebUsb::configure(&mut builder, &mut state, &webusb_config); // Create some USB bulk endpoints for testing.