2026-03-03 2:06 PM
For context, I am new to both USB programming and the STM products (and tools), so I apologize in advance for my ignorance.
I am working with an old, existing system, which utilized a USB connection to a processor/EEPROM to store information (a dongle). As some of the parts have gone end-of-life, we are looking to move to new hardware. The hope is to mimic the software running on the old hardware so that the new part will work with existing systems in the field, as well as new products. Our existing system runs on Linux with a custom driver communicating with the dongle, and from what I can tell has been coded up as a "vendor device" instead of a "class device".
Anyhow, the engineering department selected the STM32C071RBT6 as an appropriate part and have provided a prototype which I am using for development along with the following:
STM32CubeIDE v2.0.0
STM32CubeMX v6.16.1
STM32C0 series v1.4.0
To get started with STM, I've created a "custom HID" project following the guidance of several examples. So I'm using the USBX middleware. After getting everything up and running and stepping through the code, it seems that the fact that the dongle is configured as a "HID" based device is not compatible with a "Vendor Device". I can see the "Vendor request IN" on the USB analyzer, but the response is not what I'm expecting (one byte). (It's getting interpreted as a "HID command set idle")........ What I'm really after is to know if I'm heading in a sane direction.
Can the STM32C071RBT6/USBX/custom HID combination be made to work as a "vendor device"?
If so, is it reasonable to massage the "custom HID" project into a "vendor Device" one?
Is there some better combination of MCU/middleware to achieve this?
How do developers normally address existing systems that utilize "vendor devices"?
Any advise would be greatly appreciated.
Thanks,
NBC
2026-03-03 2:55 PM
Can you share the USB descriptors of the old device?
2026-03-04 8:09 AM
Here are the old device/configuration/interface descriptors. There does not seem to be anything for the endpoints.
//----------------------------------------------------------------------------
const device_descriptor DeviceDesc =
{
sizeof(device_descriptor), // Size of this Descriptor in Bytes
DT_DEVICE, // Descriptor Type (=1)
{0x10, 0x01}, // USB Spec Release Number in BCD = 1.10
0, // Device Class Code (none)
0, // Device Subclass Code (none)
0, // Device Protocol Code (none)
8, // Maximum Packet Size for EP0
{LO_BYTE(VENDOR_ID), HI_BYTE(VENDOR_ID)}, // Vendor ID
{LO_BYTE(DEVICE_ID), HI_BYTE(DEVICE_ID)}, // Product ID
{0x00, 0x01}, // Device Release Number in BCD = V01.00
1, // Index of String Desc for Manufacturer
2, // Index of String Desc for Product
0, // Index of String Desc for SerNo
1 // Number of possible Configurations
}; // end of DeviceDesc
//----------------------------------------------------------------------------
const configuration_descriptor ConfigDesc =
{
sizeof(configuration_descriptor), // Size of this Descriptor in Bytes
DT_CONFIGURATION, // Descriptor Type (=2)
{sizeof(configuration_descriptor) + sizeof(interface_descriptor),
//+ sizeof(endpoint_descriptor) + sizeof(endpoint_descriptor),
0x00}, // Total Length of Data for this Conf
1, // No of Interfaces supported by this Conf
1, // Designator Value for *this* Configuration
0, // Index of String Desc for this Conf
0x80, // not-Self-powered, no Remote-Wakeup
50 // Max. Power Consumption in this Conf (*2mA)
}; // end of ConfigDesc
//----------------------------------------------------------------------------
const interface_descriptor InterfaceDesc =
{
sizeof(interface_descriptor), // Size of this Descriptor in Bytes
DT_INTERFACE, // Descriptor Type (=4)
0, // Number of *this* Interface (0..)
0, // Alternative for this Interface (if any)
0, //2, // No of EPs used by this IF (excl. EP0)
0xff, // IF Class Code (0xff = Vendor specific)
0x01, // Interface Subclass Code
0xff, // IF Protocol Code (0xff = Vendor specific)
0 // Index of String Desc for this Interface
}; // end of InterfaceDesc
//----------------------------------------------------------------------------
2026-03-04 9:28 AM
So why not just use these descriptors instead of "custom HID"? The host OS assumes that a HID device has certain properties, that you should support. If not, the device has no reason to be HID.
2026-03-04 10:46 AM
I agree that there is no need for this device to be configured as a "custom HID" class, (or any other class for that matter), but the selection of a class seemed to be necessary to utilize the USBX middleware.
When I was starting out, I experimented with the mouse HID, and then the customize HID, and just stuck with the later. I couldn't figure out how to configure my project in STM32CubeMX to be a "Vendor Device" instead of a "Class Device" within USBX.
This is what that configuration looks like:
Do you know how to configure USBX to function as a "Vendor device"?
2026-03-04 10:59 AM
Try the DFU class.
2026-03-05 4:49 AM
Hi @NBC
Unfortunately, there is no direct reference to a vendor-specific device class template within USBX for STM32. I will share your request with our dedicated development team.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2026-03-05 8:21 AM
Does STM produce any other MCUs/middleware products that might work with USB/"vendor devices"..... something other than USBX?
2026-03-05 8:28 AM - edited 2026-03-05 8:30 AM
You should be fine. The old descriptor(s) can certainly be applied to the STM32C0 series. You just need to make sure you have code for the desired endpoints and EP0 reporting, if any.
Edit: There may be a classic core example that can be applied to the C0 and this would free you from the USBX baggage.
2026-03-06 1:14 AM
Hi @NBC
You can use this repository for classic core middleware for C0. Otherwise, I assume this DPUMP class can be useful in your case.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.