Custom HID&DFU

General description

The HID (human interface device) class primarily consists of devices that are used by humans to control the operation of computer systems. Typical examples of HID class devices are standard mouse devices, keyboards, Bluetooth adaptors etc.

HID Input/Output reports can be exchanged both over the interrupt endpoint, and over the default endpoint (Get_/Set_Report requests).
The custom HID demo is a simple HID demo provided with a small PC applet to give an example of how to create a customized HID based on the native Windows HID driver. It consists of simple data exchanges between the STM32 evaluation board and the PC Host
using two interrupt pipes (IN and OUT).

通用的HID模板实现了功能请求处理,允许用户向设备发送控制命令。这个命令是通过端点0发送,并且必须被视为一个set_report请求。

The custom HID demo implements feature request handling, which allows the user to send a control commands to the device. This command is sent through endpoint 0, and must be treated as a set_report request.

For more details on the HID device class, please refer to the “Device Class Definition for HID 1.11” available from the usb.org website.
The data exchanged is related to LED commands, push-button state reports and ADC conversion values.

Descriptor topology
The custom HID topology is based on two interrupt pipes used to handle the data transfer
for seven different reports. The following chart shows the custom HID topology。
Custom HID&DFU

Mass storage protocol

6.3.1 Bulk-only transfer (BOT)
The BOT protocol uses only bulk pipes to transfer commands, status and data (no interrupt or control pipes). The default pipe (pipe 0, or in other words, Endpoint 0) is only used to clear the bulk pipe status (clear STALL status) and to issue the two class-specific requests:
Mass Storage reset and Get Max LUN。

Command transfer
To send a command, the host uses a specific format called command block wrapper (CBW).
The CBW is a 31-byte length packet. Table 12 shows the different fields of a CBW.

Custom HID&DFU

dCBWSignature: 43425355 : USBC (in little Endian)
dCBWTag: The host specifies this field for each command. The device should return the same dCBWTag in the associated status.
dCBWDataTransferLength: total number of bytes to transfer (expected by the host).
bmCBWFlags: This field is used to specify the direction of the data transfer (if any).The bits of this field are defined as follows:
– Bit 7: Direction bit:
0: Data Out transfer (host to device).
1: Data In transfer (device to host).
Note: The device ignores this bit if the dCBWDataTransferLength field is cleared to zero.
– Bits 6:0: reserved (cleared to zero).
bCBWLUN: concerned Logical Unit number.
bCBWCBLength: this field specify the length (in bytes) of the command CBWCB.
CBWCB: the command block to be executed by the device.

Status transfer
To inform the host about the status of each received command, the device uses the command status wrapper (CSW). Table 13 shows the different fields of a CSW.
Custom HID&DFU
dCSWSignature: 53425355 USBS (little Endian).
dCSWTag: the device sets this field to the received value of dCBWTag in the concerned CBW.
dCSWDataResidue: the difference between the expected data (the value of the dCBWDataTransferLength field of the concerned CBW) and the real value of the data received or sent by the device.
bCSWStatus: the status of the concerned command. This field can assume one of the three non-reserved values shown in Table 14.
Custom HID&DFU
Data transfer
The data transfer phase is specified by the dCBWDataTransferLength and bmCBWFlags ofthe correspondent CBW. The host attempts to transfer the exact number of bytes to or from the device.
The diagram shown in Figure 8 shows the state machine of a BOT transfer.
Custom HID&DFU

Device firmware upgrade

10.1 General description
This part of the document presents the implementation of a device firmware upgrade (DFU) capability in the STM32 microcontroller. It follows the DFU class specification defined by the USB Implementers Forum for reprogramming an application through USB. The DFU
principle is particularly well suited to USB applications that need to be reprogrammed in the field:
The same USB connector can be used for both the standard operating mode and the reprogramming process.

This operation is made possible by the IAP capability featured by most of the STMicroelectronics USB Flash microcontrollers, which allows a Flash MCU to be reprogrammed by any communication channel.

The DFU process, like any other IAP process, is based on the execution of firmware located in one small part of the Flash memory and that manages the erase and program operations of the others Flash memory modules depending on the device capabilities: it could be the main program/Code Flash, data Flash/EEPROM or any other memory connected to the microcontroller even a serial Flash (Through SPI or I2C etc.).

10.2 DFU extension protocol
10.2.1 Introduction
The DFU class uses the USB as a communication channel between the microcontroller and the programming tool, generally a PC host. The DFU class specification states that, all the commands, status and data exchanges have to be performed through Control Endpoint 0. The command set, as well as the basic protocol are also defined, but the higher level protocol (Data format, error message etc.) remain vendor-specific. This means that the DFU class does not define the format of the data transferred (.s19, .hex, pure binary etc.).
Because it is impractical for a device to concurrently perform both DFU operations and its normal runtime activities, those normal activities must cease for the duration of the DFU operations. Doing so means that the device must change its operating mode; that is, a
printer is not a printer while it is undergoing a firmware upgrade; it is a Flash/Memory programmer. However, a device that supports DFU is not capable of changing its mode of operation on its own volition. External (human or host operating system) intervention is required.
10.2.2 Phases
There are four distinct phases required to accomplish a firmware upgrade:
1. Enumeration
The device informs the host of its capabilities. A DFU class-interface descriptor and associated functional descriptor embedded within the device’s normal run-time descriptors serve this purpose and provide a target for class-specific requests over the control pipe.
2. DFU enumeration
The host and the device agree to initiate a firmware upgrade. The host issues a USB reset to the device, and the device then exports a second set of descriptors in preparation for the Transfer phase. This deactivates the run-time device drivers associated with the device and allows the DFU driver to reprogram the device’s firmware unhindered by any other communications traffic targeting the device.
3. Transfer
The host transfers the firmware image to the device. The parameters specified in the functional descriptor are used to ensure correct block sizes and timing for programming the non-volatile memories. Status requests are employed to maintain synchronization
between the host and the device.
4. Manifestation
Once the device reports to the host that it has completed the reprogramming operations, the host issues a USB reset to the device. The device re-enumerates and executes the upgraded firmware.

To ensure that only the DFU driver is loaded, it is considered necessary to change the id-Product field of the device when it enumerates the DFU descriptor set. This ensures that the DFU driver will be loaded in cases where the operating system simply matches the vendor ID and product ID to a specific driver.
Custom HID&DFU

10.3 DFU mode selection
The host should be able to enumerate a device with DFU capability in two ways:
● As a single device with only DFU capability
● As a composite device: HID, Mass storage, or any functional class, and with DFU capability.
During the enumeration phase, the device exposes two distinct and independent descriptor sets, each one at the appropriate time:
● Run-time descriptor set: shown when the device performs normal operations
● DFU mode descriptor set: shown when host and device agree to perform DFU operations

10.3.1 Run-time descriptor set
During normal run-time operation, the device exposes its normal set of descriptors plus two additional descriptors:
● Run-time DFU interface descriptor
● Run-time DFU functional descriptor
Note: The number of interfaces in each configuration descriptor that supports the DFU must be incremented by one to accommodate the addition of the DFU interface descriptor.

10.3.2 DFU mode descriptor set
After the host and the device agree to perform DFU operations, the host re-enumerates the
device. At this time the device exports the descriptor set shown below:
● DFU Mode Device descriptor
● DFU Mode Configuration descriptor
● DFU Mode Interface descriptor
● DFU Mode Functional descriptor: identical to the Run-Time DFU Functional descriptor
DFU mode device descriptor
This descriptor is only present in the DFU mode descriptor set.
Custom HID&DFU

DFU mode configuration descriptor
This descriptor is identical to the standard configuration descriptor described in the USB specification version 1.0, with the exception that the bInterfaceNum field must contain the value 0x01.

DFU mode interface descriptor
This is the descriptor for the only interface available when operating in DFU mode.Therefore, the value of the bInterfaceNumber field is always zero.
Custom HID&DFU

There is an STMicroelectronics implementation for Alternate settings with a corresponding string descriptor set, which is not specified by the standard DFU specification in Section 10.2.3: Requests.

Alternate settings have to be used to access additional memory segments and other memories (Flash memory, RAM, EEPROM) which may or may not be physically implemented in the CPU memory mapping, such as external serial SPI Flash memory or
external NOR/NAND Flash memory.

In this case, each alternate setting employs a string descriptor to indicate the target memory
segment as shown below:
@Target Memory Name/Start Address/Sector(1)_Count*Sector(1)_Size
Sector(1)_Type,Sector(2)_Count*Sector(2)_SizeSector(2)_Type,…
…,Sector(n)_Count*Sector(n)_SizeSector(n)_Type
Another example, for STM32 Flash microcontroller, is shown below:
@Internal Flash /0x08000000/12*001 Ka,116*001 Kg” in case of
STM3210B-EVAL board.
@Internal Flash /0x08000000/6*002 Ka,250*002 Kg” in case of
STM3210E-EVAL board.
@Internal Flash /0x08000000/48*256 Ka,464*256 Kg” in case of
STM32L152-EVAL board.
@Internal Flash /0x08000000/48*256 Ka,1488*256 Kg” in case of
STM32L152D-EVAL board.
@Internal Flash /0x08000000/12*001 Ka,116*001 Kg” in case of
STM32373C-EVAL and STM32303C-EVAL boards.
Each Alternate setting string descriptor must follow this memory mapping so that the PC
Host Software can decode the right mapping for the selected device:
● @: To detect that this is a special mapping descriptor (to avoid decoding standard
descriptor)
● /: for separator between zones
● Maximum 8 digits per address starting by “0x”
● /: for separator between zones
● Maximum of 2 digits for the number of sectors
● *: For separator between number of sectors and sector size
● Maximum 3 digits for sector size between 0 and 999
● 1 digit for the sector size multiplier. Valid entries are: B (byte), K (Kilo), M (Mega)
● 1 digit for the sector type as follows:
– a (0x41): Readable
– b (0x42): Erasable
– c (0x43): Readable and Erasabled (0x44): Writeable
– e (0x45): Readable and Writeable
– f (0x46): Erasable and Writeable
– g (0x47): Readable, Erasable and Writeable
Note: If the target memory is not contiguous, the user can add the new sectors to be decoded just
after a slash”/” as shown in the following example:
“@Flash /0xF000/1*4Ka/0xE000/1*4Kg/0x8000/2*24Kg”

DFU functional descriptor
This descriptor is identical for both the runtime and the DFU mode descriptor sets.
Custom HID&DFU

10.4 Reconfiguration phase
Once the operator has identified the device and supplied the filename, the host and the device must negotiate to perform the upgrade.
1. The host issues a DFU_DETACH request to Control Endpoint EP0.
2. The host issues a USB reset to the device. This USB reset is not possible on some PC Host OS versions. To bypass this issue, the USB reset is performed by the MCU depending on the corresponding implementation.
3. The device enumerates with the DFU Mode descriptor set, as described above.
Note: Some Device application may not be using USB in their run-time mode such as a Motor control application or security system, and USB may be used only for memory upgrade. Those devices are called non-USB application in the scope of this document and the above sequences are not applicable.
Non-USB applications have to carry out the right procedure to enter the DFU mode. This can be done simply by plugging the USB cable or by jumping to the DFU firmware code while performing an USB reset so that the device would enumerate with the DFU descriptor set.
10.5 Transfer phase
The transfer phase begins after the device has processed the USB reset and exported the DFU Mode descriptor set. Both downloads and uploads of firmware can take place during this phase. This transfer phase consists of a succession of DFU requests according to the state diagram described in the following sections.
10.5.1 Requests
A number of DFU class-specific requests are needed to accomplish the upgrade/upload operations. Table 30 summarizes these requests.

Custom HID&DFU

10.5.2 Special command/protocol descriptions
In order to support all features (Address decoding and Memory block to erase, etc.) of the DFU Extension implementation from STMicroelectronics, a few format rules are added to the DFU_DNLOAD request. They are defined as shown in Table 31.
Custom HID&DFU

This new custom DFU implements only three supported basic commands:
● Get commands
Byte0 = 0x00, then no additional bytes.
The next DFU_UPLOAD request with wBlockNum = 0 should give the supported commands.The maximum size of the supported commands buffer is 256 bytes, and the buffer must support the following commands:
– 0x00 (Get Commands)
– 0x21 (Set Address Pointer)
– 0x41 (Erase Sector containing address)
● Set Address Pointer
Byte0 = 0x21, then 4 bytes containing the address Pointer from which the Blocks will be downloaded or uploaded starting from the next DFU_DNLOAD or DFU_UPLOAD request with wBlockNum >1.
● Erase Sector containing address
Byte0 = 0x41, then 4 bytes containing a valid address contained in a memory sector to be erased and as already exported by the string descriptors of the Alternate settings.
Note: wBlockNum = 1 for both DFU_DNLOAD and DFU_UPLOAD requests, is reserved for future use by STMicroelectronics.

10.5.3 DFU state diagram
Figure 21 summarizes the DFU interface states and the transitions between them. The events that rigger state transitions can be thought of as arriving on multiple “input tapes” as in the classic Turing machine concept.
Custom HID&DFU

Note: The state transition diagram shown in Figure 21 is almost the same as that defined in the DFU Class specification (Fig A1 page 28), with the exception of the new transition from state 2 to state 6, which is additional and may or not be implemented in the device firmware.

10.5.4 Downloading and uploading
The host slices the firmware image file into N pieces and sends them to the device by means of control-write operations in the default endpoint (Endpoint 0).
The maximum number of bytes that the device can accept per control-write transaction is specified in the wTransferSize field of the DFU Functional Descriptor.
There are several possible download mechanisms depending on the MCU device memory mapping and the Type of the memory (that is Readable, Erasable, Writeable or a combination).
The most generic mechanism is described below, where we have a readable, erasable and writeable sector of memory:
● In addition to the data collected after the enumeration phase about the whole memory mapping, the device capabilities etc., the Host starts to send a GetCommands command in order to know additional device capabilities and which commands are supported by the DFU implementation.
● The host sends an Erase Sector Containing Address command using a DFU_DNLOAD request with wBlockNum = 0 and wLength = 5. At this stage, the device erases the memory block where the address sent by the host is located. After the erase operation,the DFU firmware is able to write application data into the erased block.
● The host begins by sending the Set Address Pointer command using a DFU_DNLOAD request with wBlockNum = 0 and wLength = 5. This address pointer is saved in the device RAM as an Absolute Offset.
● The host continues to send the N pieces to the device by means of DFU_DNLOAD requests with wBlockNum starting from 2 and with the maximum number of bytes that the device can accept per control-write transaction specified in the wTransferSizefield of the DFU Functional Descriptor.
So the last data written into the memory will be located at device address:
Absolute Offset + (wBlockNum – 2) × wTransferSize + wLength, where
wBlockNum and wLength are the parameters of the last DFU_DNLOAD request.
If the Host wants to upload the memory data for verification, or to retrieve and archive a device firmware, by definition the reverse of a Download is performed:
1. The host begins by sending a Set Address Pointer command using a DFU_DNLOAD request with wBlockNum = 0 and wLength = 5. This address pointer is saved in the device RAM as an Absolute Offset.
2. The host continues to send N DFU_UPLOAD requests with wBlockNum starting from 2 and with the maximum number of bytes that the device can accept per control-write transaction specified in the wTransferSize field of the DFU Functional Descriptor ifbitCanAccelerate = 0. If bitCanAccelerate = 1 in the DFU Functional Descriptor, the value in the wTransferSize field is fixed to 0x4096 bytes.
So the last data retrieved from the memory will be located at device address:
Absolute Offset + (wBlockNum – 2) × wTransferSize + wLength, where
wBlockNum and wLength are the parameters of the last DFU_UPLOAD request.

10.5.5 Manifestation phase
After the transfer phase completes, the device is ready to execute the new firmware. This is achieved by performing a USB reset to re-enumerate the device in normal run-time operation

10.6 STM32 DFU implementation
10.6.1 Supported memories
For the STM32 the DFU implementation supports the following memories:
● Internal Flash memory: the first pages are reserved for the DFU (read-only pages)
and the remaining pages can be programmed by the DFU (application zone):
– For the STM3210B-EVAL, STM32373C-EVAL and STM32303C-EVAL boards, the
first 12 pages are read-only, and the remaining 116 pages are in the application
zone.
– For the STM3210E-EVAL board, the first 6 pages are read-only, and the remaining
250 pages are in the application zone.
– For the STM32L152-EVAL board, the first 48 pages are read-only, and the
remaining 464 pages are in the application zone.
– For the STM32L152D-EVAL board, the first 48 pages are read-only, and the
remaining 1488 pages are in the application zone.
● External serial Flash memory (M25P64): consists of 128 sectors of 64 Kbytes each.
● NOR Flash memory (M29W128): consists of 256 blocks of 64 Kbytes each. This
memory is supported only by the STM3210E-EVAL board.
Note: *To create a DFU image for the internal Flash memory select the Alternate Setting 00 in the DFU file Manager.
To create a DFU image for the external serial Flash memory, select the Alternate Setting 01in the DFU file Manager.
To create a DFU image for the NORFlash memory, select the Alternate Setting 02 in the DFU file Manager.*

10.6.2 DFU mode entry mechanism
For the STM32 the DFU mode is entered after an MCU reset if:
● The DFU mode is forced by the user: the user presses the key push-button (or joystick Up push-button for STM32L152-EVAL board) after a reset.
● There is no correct code available in the application area: before jumping to the
application code, the DFU code tests if there is a correct top-of-stack address in the first address in the application area of the internal Flash memory (for the STM32 the first application address is 0x0800 3000). This is done by reading the value of the first application address and verifying if the MSB half-word is equal to 0x2000 (base address of the RAM area in the STM32).

Custom HID&DFU

Creating a DFU image
Two steps are needed to create a DFU image:
1. Create a binary image from one of the available USB demo projects by adjusting the Flash memory base to 0x0800 3000 and by setting the vector table at the top of the Flash memory space 0x0800 3000.
2. Using the DFU file manager provided with the DFU demo package, generate the DFU file by setting target ID to 0 (internal Flash) and the start address to 0x0800 3000.