From 326bc98bd225a8ec65093e5881e29c57e66fb1cd Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 7 Nov 2023 02:34:14 +0000 Subject: [PATCH] Update stm32 usb_raw example to use MSOS descriptors for WinUSB --- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f4/src/bin/usb_ethernet.rs | 1 + examples/stm32f4/src/bin/usb_raw.rs | 21 +++++++++++++++++++++ examples/stm32f4/src/bin/usb_serial.rs | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index fca18203..bcf37371 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } -embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } defmt = "0.3" diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 7c0644ae..45dcf56a 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -94,6 +94,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], + &mut [], &mut make_static!([0; 128])[..], ); diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index 8d4e6c7d..689aea4f 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -56,10 +56,16 @@ use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use embassy_usb::msos::{self, windows_version}; use embassy_usb::types::InterfaceNumber; use embassy_usb::{Builder, Handler}; use {defmt_rtt as _, panic_probe as _}; +// Randomly generated UUID because Windows requires you provide one to use WinUSB. +// In principle WinUSB-using software could find this device (or a specific interface +// on it) by its GUID instead of using the VID/PID, but in practice that seems unhelpful. +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; + bind_interrupts!(struct Irqs { OTG_FS => usb_otg::InterruptHandler; }); @@ -114,6 +120,7 @@ async fn main(_spawner: Spawner) { let mut device_descriptor = [0; 256]; let mut config_descriptor = [0; 256]; let mut bos_descriptor = [0; 256]; + let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; let mut handler = ControlHandler { @@ -126,9 +133,23 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &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), + )); + // Add a vendor-specific function (class 0xFF), and corresponding interface, // that uses our custom handler. let mut function = builder.function(0xFF, 0, 0); diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 004ff038..3ab9a6c5 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -77,6 +77,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], &mut control_buf, );