The DFU file is only half of the USB Device Firmware Upgrade class specification (release 1.1). The other half is the protocol a host uses to send the file’s firmware to a device: how the device announces DFU support, the requests the host sends, and the states and error codes the device reports. These values do not appear in the file, but a tool that writes or flashes DFU files works with them, so every code the specification defines is listed here.
Interface class codes
A device supports DFU by having an interface with these codes. In normal operation (run-time mode) the interface sits beside the device’s other interfaces; after a detach and USB reset the device enumerates again in DFU mode with only the DFU interface.
| Field | Value | Meaning |
|---|---|---|
bInterfaceClass | 0xFE | Application specific class. |
bInterfaceSubClass | 0x01 | Device Firmware Upgrade. |
bInterfaceProtocol | 0x01 | Run-time protocol: the device is running its application. |
bInterfaceProtocol | 0x02 | DFU mode protocol: the device is ready to receive or send firmware. |
In DFU mode each alternate setting of the interface can stand for a different memory
or part of the device; the DfuSe bAlternateSetting field picks one.
DFU functional descriptor
A 9-byte class-specific descriptor that follows the DFU interface descriptor, in both modes.
| Offset | Size | Name | Meaning |
|---|---|---|---|
0 | 1 | bLength | 9. |
1 | 1 | bDescriptorType | 0x21, DFU FUNCTIONAL. |
2 | 1 | bmAttributes | Capability bits; see below. |
3 | 2 | wDetachTimeOut | Longest time in milliseconds the device waits, after a DFU_DETACH, for the USB reset that starts DFU mode. |
5 | 2 | wTransferSize | Largest number of bytes the device accepts in one DFU_DNLOAD or sends in one DFU_UPLOAD. |
7 | 2 | bcdDFUVersion | Version of the DFU specification the device follows, in BCD. The specification gives no list of values. |
| Bit | Name | Meaning when set |
|---|---|---|
| 0 | bitCanDnload | The device can receive firmware (download). |
| 1 | bitCanUpload | The device can send its firmware back to the host (upload). |
| 2 | bitManifestationTolerant | The device can still talk on the bus after the manifestation phase (it goes back to dfuIDLE instead of needing a reset). |
| 3 | bitWillDetach | The device performs a bus detach-attach sequence itself when it receives DFU_DETACH; the host must not issue a USB reset. |
| 4–7 | — | Reserved, zero. |
Requests
Class requests sent to the DFU interface. bmRequestType is
0x21 (host to device) or 0xA1 (device to host), and
wIndex is the interface number.
bRequest | Name | Direction | wValue | wLength | Meaning |
|---|---|---|---|---|---|
0 | DFU_DETACH | to device | timeout (ms) | 0 | Run-time mode only: prepare to enter DFU mode at the next USB reset. |
1 | DFU_DNLOAD | to device | block number | length | Send one block of firmware. A zero-length DNLOAD marks the end of the firmware and starts manifestation. |
2 | DFU_UPLOAD | to host | 0 | length | Read one block of the device’s firmware. A block shorter than wLength (a short frame) ends the upload. |
3 | DFU_GETSTATUS | to host | 0 | 6 | Read the status record below. |
4 | DFU_CLRSTATUS | to device | 0 | 0 | Clear an error and go from dfuERROR back to dfuIDLE. |
5 | DFU_GETSTATE | to host | 0 | 1 | Read the current state, one byte, without changing it. |
6 | DFU_ABORT | to device | 0 | 0 | Abandon a download or upload and go back to dfuIDLE. |
DFU_GETSTATUS response
| Offset | Size | Name | Meaning |
|---|---|---|---|
0 | 1 | bStatus | Result of the last request; see status codes. |
1 | 3 | bwPollTimeout | Milliseconds the host must wait before the next DFU_GETSTATUS (for example while flash is erased), little-endian. |
4 | 1 | bState | The state the device will be in after this response; see states. |
5 | 1 | iString | Index of a string descriptor describing the status, or 0. |
States
| Value | Name | Meaning |
|---|---|---|
0 | appIDLE | Running its normal application. |
1 | appDETACH | Received DFU_DETACH; waiting for a USB reset to enter DFU mode. |
2 | dfuIDLE | In DFU mode, waiting for requests. |
3 | dfuDNLOAD-SYNC | Received a block; waiting for DFU_GETSTATUS. |
4 | dfuDNBUSY | Writing the block to memory. |
5 | dfuDNLOAD-IDLE | Block written; waiting for the next DFU_DNLOAD. |
6 | dfuMANIFEST-SYNC | Received the last (zero-length) block; waiting for DFU_GETSTATUS to start, or to report the end of, manifestation. |
7 | dfuMANIFEST | Manifestation in progress: the device is making the new firmware ready to run. |
8 | dfuMANIFEST-WAIT-RESET | Manifestation done on a device that is not manifestation-tolerant; waiting for a USB reset. |
9 | dfuUPLOAD-IDLE | An upload is in progress; waiting for the next DFU_UPLOAD. |
10 | dfuERROR | An error happened; waiting for DFU_CLRSTATUS. |
Status codes
| Value | Name | Meaning |
|---|---|---|
0x00 | OK | No error. |
0x01 | errTARGET | The file is not meant for this device. |
0x02 | errFILE | The file is for this device but fails a vendor-specific check. |
0x03 | errWRITE | The device cannot write memory. |
0x04 | errERASE | Erasing memory failed. |
0x05 | errCHECK_ERASED | The check that memory was erased failed. |
0x06 | errPROG | Programming memory failed. |
0x07 | errVERIFY | The programmed memory failed verification. |
0x08 | errADDRESS | Cannot program memory: an address was out of range. |
0x09 | errNOTDONE | A zero-length DFU_DNLOAD arrived but the device does not think it has all the data yet. |
0x0A | errFIRMWARE | The device’s firmware is corrupt; it cannot return to run-time operation. |
0x0B | errVENDOR | A vendor-specific error; iString describes it. |
0x0C | errUSBR | The device detected an unexpected USB reset. |
0x0D | errPOR | The device detected an unexpected power-on reset. |
0x0E | errUNKNOWN | Something went wrong, but the device does not know what. |
0x0F | errSTALLEDPKT | The device stalled an unexpected request. |
A typical download
- The host checks the file’s suffix against the device’s IDs.
- If the device is in run-time mode, the host sends DFU_DETACH and then resets the bus (or waits, if
bitWillDetachis set). The device comes back in DFU mode, in dfuIDLE. - The host sends the firmware, without the suffix, in DFU_DNLOAD blocks of at most
wTransferSizebytes, each with a block number (wBlockNum) that goes up by one per block and wraps from 65 535 to 0, calling DFU_GETSTATUS after each and waitingbwPollTimeoutwhile the device is busy. The suffix is never sent to the device. - A zero-length DFU_DNLOAD ends the transfer; the device manifests the new firmware and then either returns to dfuIDLE or waits for a reset.
Sources
- Universal Serial Bus Device Class Specification for Device Firmware Upgrade, version 1.1 – USB-IF, 2004: section 3 (requests, tables 3.1 and 3.2), section 4 (descriptors), section 6 (DFU_GETSTATUS, status and state tables)
- dfu.h – TinyUSB’s DFU class header, used to cross-check the request, state, status and attribute values