diff options
| author | Gerhard de Clercq <[email protected]> | 2025-05-12 15:51:19 +0200 |
|---|---|---|
| committer | Gerhard de Clercq <[email protected]> | 2025-05-12 15:55:11 +0200 |
| commit | 3c73b497909ce5bacd16d23e54928a7f66544e09 (patch) | |
| tree | c6f0937fb9e4a53cf69897a34bf069933c0d148e /embassy-usb-dfu/src | |
| parent | f9f20ae2174cb26d0f8926207d179041cfec2d2e (diff) | |
[embassy-usb-dfu] support function level WinUSB GUIDs
This commit makes it possible to provide function level msos GUIDs to usb_dfu. This helps to ensure that composite DFU devices automatically get assigned the WinUSB driver on Windows.
Diffstat (limited to 'embassy-usb-dfu/src')
| -rw-r--r-- | embassy-usb-dfu/src/application.rs | 16 | ||||
| -rw-r--r-- | embassy-usb-dfu/src/dfu.rs | 16 |
2 files changed, 30 insertions, 2 deletions
diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs index 6ad07a78c..52a7ca951 100644 --- a/embassy-usb-dfu/src/application.rs +++ b/embassy-usb-dfu/src/application.rs | |||
| @@ -2,7 +2,7 @@ use embassy_boot::BlockingFirmwareState; | |||
| 2 | use embassy_time::{Duration, Instant}; | 2 | use embassy_time::{Duration, Instant}; |
| 3 | use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; | 3 | use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; |
| 4 | use embassy_usb::driver::Driver; | 4 | use embassy_usb::driver::Driver; |
| 5 | use embassy_usb::{Builder, Handler}; | 5 | use embassy_usb::{msos, Builder, Handler}; |
| 6 | use embedded_storage::nor_flash::NorFlash; | 6 | use embedded_storage::nor_flash::NorFlash; |
| 7 | 7 | ||
| 8 | use crate::consts::{ | 8 | use crate::consts::{ |
| @@ -130,8 +130,22 @@ pub fn usb_dfu<'d, D: Driver<'d>, MARK: DfuMarker, RST: Reset>( | |||
| 130 | builder: &mut Builder<'d, D>, | 130 | builder: &mut Builder<'d, D>, |
| 131 | handler: &'d mut Control<MARK, RST>, | 131 | handler: &'d mut Control<MARK, RST>, |
| 132 | timeout: Duration, | 132 | timeout: Duration, |
| 133 | winusb_guids: Option<&'d [&str]>, | ||
| 133 | ) { | 134 | ) { |
| 134 | let mut func = builder.function(0x00, 0x00, 0x00); | 135 | let mut func = builder.function(0x00, 0x00, 0x00); |
| 136 | if let Some(winusb_guids) = winusb_guids { | ||
| 137 | // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. | ||
| 138 | // Otherwise users need to do this manually using a tool like Zadig. | ||
| 139 | // | ||
| 140 | // Adding them here on the function level appears to only work for compositive devices though. | ||
| 141 | // For non-composite devices they should be placed on the device level instead. | ||
| 142 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 143 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 144 | "DeviceInterfaceGUIDs", | ||
| 145 | msos::PropertyData::RegMultiSz(winusb_guids), | ||
| 146 | )); | ||
| 147 | } | ||
| 148 | |||
| 135 | let mut iface = func.interface(); | 149 | let mut iface = func.interface(); |
| 136 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); | 150 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); |
| 137 | let timeout = timeout.as_millis() as u16; | 151 | let timeout = timeout.as_millis() as u16; |
diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs index a98d6ab40..83feacaf8 100644 --- a/embassy-usb-dfu/src/dfu.rs +++ b/embassy-usb-dfu/src/dfu.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError}; | 1 | use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError}; |
| 2 | use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; | 2 | use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; |
| 3 | use embassy_usb::driver::Driver; | 3 | use embassy_usb::driver::Driver; |
| 4 | use embassy_usb::{Builder, Handler}; | 4 | use embassy_usb::{msos, Builder, Handler}; |
| 5 | use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind}; | 5 | use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind}; |
| 6 | 6 | ||
| 7 | use crate::consts::{ | 7 | use crate::consts::{ |
| @@ -186,8 +186,22 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha | |||
| 186 | pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>( | 186 | pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>( |
| 187 | builder: &mut Builder<'d, D>, | 187 | builder: &mut Builder<'d, D>, |
| 188 | handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>, | 188 | handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>, |
| 189 | winusb_guids: Option<&'d [&str]>, | ||
| 189 | ) { | 190 | ) { |
| 190 | let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU); | 191 | let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU); |
| 192 | if let Some(winusb_guids) = winusb_guids { | ||
| 193 | // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. | ||
| 194 | // Otherwise users need to do this manually using a tool like Zadig. | ||
| 195 | // | ||
| 196 | // Adding them here on the function level appears to only work for compositive devices though. | ||
| 197 | // For non-composite devices they should be placed on the device level instead. | ||
| 198 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 199 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 200 | "DeviceInterfaceGUIDs", | ||
| 201 | msos::PropertyData::RegMultiSz(winusb_guids), | ||
| 202 | )); | ||
| 203 | } | ||
| 204 | |||
| 191 | let mut iface = func.interface(); | 205 | let mut iface = func.interface(); |
| 192 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); | 206 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); |
| 193 | alt.descriptor( | 207 | alt.descriptor( |
