Hi,
I’m implementing DFU on my lastest device project. I have already implemented all the DFU mechanics on Linux but now I need to implement the host side logic on my application.
While in Linux I can access a device whenever I want, in Windows the same kind of freedom is not available so I have investigating the best option.
Since the device is an HID device and doesn’t need drivers I don’t want to install a driver for its DFU mode as well. However, in order to find the DFU device and communicate with it and I need to have it recognized by windows.
My first question is:
- Why doesn’t Windows recognizes my DFU as parte of a class? Since USB defines a device class specification for this special mode?
I’m not sure if something is wrong with the descriptor but this is what USBlyzer says regarding my DFU device:
Connection Status Device connected
Current Configuration 0
Speed Full (12 Mbit/s)
Device Address 1
Number Of Open Pipes 0
Device Descriptor SKIN HD (DFU Mode)
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 idVendor 2 226Eh
10 idProduct 2 0000h
12 bcdDevice 2 0100h 1.00
14 iManufacturer 1 01h “DISPLAX”
15 iProduct 1 02h “SKIN HD (DFU Mode)”
16 iSerialNumber 1 03h “123456789”
17 bNumConfigurations 1 01h
Configuration Descriptor 1
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 001Bh
4 bNumInterfaces 1 01h
5 bConfigurationValue 1 01h
6 iConfiguration 1 02h “SKIN HD (DFU Mode)”
7 bmAttributes 1 C0h Self Powered
4…0: Reserved …00000
5: Remote Wakeup …0… No
6: Self Powered .1… Yes
7: Reserved (set to one)
(bus-powered for 1.0) 1…
8 bMaxPower 1 32h 100 mA
Unrecognized Class-Specific Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h
2 7 09 FF 00 40 00 01 01
This last part doesn’t terminate like this on my device descriptor. I don’t know why it seems to have stopped here…
After some investigation I have discovered WinUSB and once again I would like to avoid a custom inf since there is the possibilite of using OS descriptors. But now i’m in a problem again. Since my descriptor is not being accepted, device enumeration and setups seems to be aborted and thus the device doesn’t get to the part where it is queried about its descriptor and never gets to GET_DESCRIPTOR with the low byte 0xEE.
So, my last two questions:
- Should my device be recognized as a DFU without any kind of problems by default by Windows?
- Is WinUSB and OS descriptor the best option here to achieve full Plug & Play “awesomeness”?
Thanks for your time
Regards,
Nuno Santos
[EDIT]
I had a problem with my descriptor and now the output of USBLyzer is this:
Connection Status Device connected
Current Configuration 0
Speed Full (12 Mbit/s)
Device Address 1
Number Of Open Pipes 0
Device Descriptor SKIN HD (DFU Mode)
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 idVendor 2 226Eh
10 idProduct 2 0000h
12 bcdDevice 2 0100h 1.00
14 iManufacturer 1 01h “DISPLAX”
15 iProduct 1 02h “SKIN HD (DFU Mode)”
16 iSerialNumber 1 03h “123456789”
17 bNumConfigurations 1 01h
Configuration Descriptor 1
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 001Bh
4 bNumInterfaces 1 01h
5 bConfigurationValue 1 01h
6 iConfiguration 1 02h “SKIN HD (DFU Mode)”
7 bmAttributes 1 C0h Self Powered
4…0: Reserved …00000
5: Remote Wakeup …0… No
6: Self Powered .1… Yes
7: Reserved (set to one)
(bus-powered for 1.0) 1…
8 bMaxPower 1 32h 100 mA
Interface Descriptor 0/0 Application-Specific, 0 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 00h
5 bInterfaceClass 1 FEh Application-Specific
6 bInterfaceSubClass 1 01h Device Firmware Upgrade
7 bInterfaceProtocol 1 02h DFU Mode
8 iInterface 1 06h
DFU Functional Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h DFU Functional
2 bmAttributes 1 09h
0: bitCanDnload …1 Yes
1: bitCanUpload …0. No
2: bitManifestationTolerant …0… No
3: bitWillDetach …1… Yes
7…4: Reserved 0000…
3 wDetachTimeOut 2 00FFh 255 ms
5 wTransferSize 2 1A40h 6720 bytes
7 bcdDFUVersion 2 0001h 0.01
However, the setup phase on the device is still not called…
xxxxx@imaginando.net wrote:
I had a problem with my descriptor and now the output of USBLyzer is this:
Connection Status Device connected
Current Configuration 0
Speed Full (12 Mbit/s)
Device Address 1
Number Of Open Pipes 0
…
However, the setup phase on the device is still not called…
What do you mean by that? The device has an address, so I have to
conclude that it was successfully enumerated. That is, the operating
system can see the device, and you have an entry in Device Manager. Is
that right? Is it grabbing your WinUSB INF file? Are you able to open
the device in your WinUSB application?
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Hi Tim,
Thanks for your reply.
In fact I haven’t tried yet to open the device with the WinUSB calls. I was trying to understand how could I make my device WinUSB compatible to avoid the usage of an extra .inf file.
I have been reading about OS Descriptors and trying to implement the necessary descriptors and custom device answers needed for Windows to classify my device a WinUSB device as described here:
http://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx#how_to_configure_a_winusb_device
http://msdn.microsoft.com/en-us/windows/hardware/gg463179.aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/dn385747.aspx
During that investigation process I went a bit deeper. Yes, you’re right. My device is configured. The thing is. I’m using an STM32F4 range chip to implement my device. The USB stack is provided by an STM lib which provides an easier implementation of the most basic operations. The software stack provides a structure of callbacks that are called at certain points of the enumeration process. I was being deceived because I was not having a call of the “Setup” callback, however, after inspection of the stack source code, I found the points in which the GET_DESCRIPTOR calls were being made.
In summary, I have defined in my device descriptor, the necessary STRING_DESCRIPTOR, for my device to be classified as an WinUSB.
The most strange thing is. In Windows 8 I cant get any GET_DESCRIPTOR with wValue=0x03EE
However, I have plugged the device to Windows 7 and I got a GET_DESCRITPOR request with wValue=0x03EE.
Even more strange is the fact that after trying again in Windows 8 and the in Windows 7 again, I hadn’t the wValue=0x03EE never again.
In summary. I want to classify my device as a WinUSB device to be able to communicate with it without having to install a separated .inf file. This will only be needed when the device is in DFU mode because in normal mode it will act as an HID device.
Sorry if my english is not the best.
With my best regards,
Nuno Santos
[EDIT]
After all, the second machine I have plugged the device is a Windows 8 machine as well.
I have tried with a third and on the first device plug to the machine, the request 0x03EE is always made. After that it doesn’t make the request anymore. Is there any kind of device caching done by Windows?
Regards,
Nuno
[EDIT]
We have managed to find a solution for this problem. We needed to implement custom USB handling to have the OS descriptors reported to Windows. We now have our device configured to use WinUSB driver automatically.
During this process we have faced some problems due to lack of documentation, specially regarding device enumeration info caching and extended OS descriptor properties. If we haven’t found some extra source code the web googling about this we would never found the specification of extended properties descriptors.
Thanks,
Regards,
Nuno
xxxxx@imaginando.net wrote:
After all, the second machine I have plugged the device is a Windows 8 machine as well.
I have tried with a third and on the first device plug to the machine, the request 0x03EE is always made. After that it doesn’t make the request anymore. Is there any kind of device caching done by Windows?
Sure there is. Think about the Device Manager flow here. When your
device is plugged in, Windows grabs the hardware ID (which is entirely
derived from the device descriptor – the VID and PID), and checks to
see if it has an entry in the Enum registry tree. If there isn’t one
(which would be the case on first plugin), then it goes through a long
list of possibilities to try to locate a driver. It will try the device
class, in several different ways, and then it will fetch the 0xEE string
descriptor. In your case, the presence of the 0xEE string descriptor is
enough to find a matching INF file, so Windows creates an Enum\USB entry
for your device and loads the driver.
The next time your device is plugged in, again Windows looks up the
hardware ID (VID and PID) in the Enum registry tree. This time, it
finds an entry. So, it can load your driver based entirely on that. It
doesn’t need to check the 0xEE descriptor again – it already has a driver.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
xxxxx@imaginando.net wrote:
In fact I haven’t tried yet to open the device with the WinUSB calls. I was trying to understand how could I make my device WinUSB compatible to avoid the usage of an extra .inf file.
…
In summary, I have defined in my device descriptor, the necessary STRING_DESCRIPTOR, for my device to be classified as an WinUSB.
…
In summary. I want to classify my device as a WinUSB device to be able to communicate with it without having to install a separated .inf file. This will only be needed when the device is in DFU mode because in normal mode it will act as an HID device.
Just one other thing. Remember that you will need to use two different
PIDs for your two different personalities. Because of the caching that
I mentioned in the other email, a single VID and PID will be associated
with one driver. If you need a different driver, then you need a
different PID.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.