diff options
| -rw-r--r-- | embassy-usb-dfu/src/application.rs | 21 | ||||
| -rw-r--r-- | embassy-usb-dfu/src/dfu.rs | 21 | ||||
| -rw-r--r-- | examples/boot/application/stm32wb-dfu/src/main.rs | 14 | ||||
| -rw-r--r-- | examples/boot/bootloader/stm32wb-dfu/src/main.rs | 14 |
4 files changed, 30 insertions, 40 deletions
diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs index 2646d100d..4b7b72073 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::{msos, Builder, Handler}; | 5 | use embassy_usb::{Builder, FunctionBuilder, 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,22 +130,13 @@ 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 | func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>), |
| 134 | ) { | 134 | ) { |
| 135 | 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 { | 136 | |
| 137 | // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. | 137 | // Here we give users the opportunity to add their own function level MSOS headers for instance. |
| 138 | // Otherwise users need to do this manually using a tool like Zadig. | 138 | // This is useful when DFU functionality is part of a composite USB device. |
| 139 | // | 139 | func_modifier(&mut func); |
| 140 | // Adding them here on the function level appears to only be needed for compositive devices. | ||
| 141 | // In addition to being on the function level, they should also be added to the device level. | ||
| 142 | // | ||
| 143 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 144 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 145 | "DeviceInterfaceGUIDs", | ||
| 146 | msos::PropertyData::RegMultiSz(winusb_guids), | ||
| 147 | )); | ||
| 148 | } | ||
| 149 | 140 | ||
| 150 | let mut iface = func.interface(); | 141 | let mut iface = func.interface(); |
| 151 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); | 142 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); |
diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs index 43a35637d..0f39d906b 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::{msos, Builder, Handler}; | 4 | use embassy_usb::{Builder, FunctionBuilder, 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,22 +186,13 @@ 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 | func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>), |
| 190 | ) { | 190 | ) { |
| 191 | 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 { | 192 | |
| 193 | // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. | 193 | // Here we give users the opportunity to add their own function level MSOS headers for instance. |
| 194 | // Otherwise users need to do this manually using a tool like Zadig. | 194 | // This is useful when DFU functionality is part of a composite USB device. |
| 195 | // | 195 | func_modifier(&mut func); |
| 196 | // Adding them here on the function level appears to only be needed for compositive devices. | ||
| 197 | // In addition to being on the function level, they should also be added to the device level. | ||
| 198 | // | ||
| 199 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 200 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 201 | "DeviceInterfaceGUIDs", | ||
| 202 | msos::PropertyData::RegMultiSz(winusb_guids), | ||
| 203 | )); | ||
| 204 | } | ||
| 205 | 196 | ||
| 206 | let mut iface = func.interface(); | 197 | let mut iface = func.interface(); |
| 207 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); | 198 | let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); |
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index 6236dfe52..4d6556597 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs | |||
| @@ -70,11 +70,15 @@ async fn main(_spawner: Spawner) { | |||
| 70 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | 70 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), |
| 71 | )); | 71 | )); |
| 72 | 72 | ||
| 73 | // For non-composite devices: | 73 | usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), |func| { |
| 74 | usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), None); | 74 | // You likely don't have to add these function level headers if your USB device is not composite |
| 75 | 75 | // (i.e. if your device does not expose another interface in addition to DFU) | |
| 76 | // Or for composite devices: | 76 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); |
| 77 | // usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), Some(DEVICE_INTERFACE_GUIDS)); | 77 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( |
| 78 | "DeviceInterfaceGUIDs", | ||
| 79 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | ||
| 80 | )); | ||
| 81 | }); | ||
| 78 | 82 | ||
| 79 | let mut dev = builder.build(); | 83 | let mut dev = builder.build(); |
| 80 | dev.run().await | 84 | dev.run().await |
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index 8cfd4daa7..fea6f4a0d 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs | |||
| @@ -78,11 +78,15 @@ fn main() -> ! { | |||
| 78 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | 78 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), |
| 79 | )); | 79 | )); |
| 80 | 80 | ||
| 81 | // For non-composite devices: | 81 | usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, |func| { |
| 82 | usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, None); | 82 | // You likely don't have to add these function level headers if your USB device is not composite |
| 83 | 83 | // (i.e. if your device does not expose another interface in addition to DFU) | |
| 84 | // Or for composite devices: | 84 | func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); |
| 85 | // usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, Some(DEVICE_INTERFACE_GUIDS)); | 85 | func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( |
| 86 | "DeviceInterfaceGUIDs", | ||
| 87 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | ||
| 88 | )); | ||
| 89 | }); | ||
| 86 | 90 | ||
| 87 | let mut dev = builder.build(); | 91 | let mut dev = builder.build(); |
| 88 | embassy_futures::block_on(dev.run()); | 92 | embassy_futures::block_on(dev.run()); |
