I'm working on uploading to Digispark board. It uses micronucleus bootloader and I can see uploader code. I've modified it a bit to see interfaces and endpoints count:

    nucleus->device = usb_open(dev);

    // added by me - start
    int interfaces, endpoints, j;
    struct usb_interface_descriptor *interface = NULL;

    interfaces = dev->config->bNumInterfaces;
    fprintf(stderr, "Found interfaces: %i\n", interfaces);

    interface = &(dev->config->interface[0].altsetting[0]);
    fprintf(stderr, "Endpoints: %i\n", interface->bNumEndpoints);
    // added by me - end

    // get nucleus info
    unsigned char buffer[4];
    int res = usb_control_msg(nucleus->device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT);

I wonder how it's working because interface #0 has no endpoints:

$./micronucleus --type intel-hex /tmp/Start.ino.hex 
> Please plug in the device ... 
> Press CTRL+C to terminate the program.
Found interfaces: 1
Endpoints: 0
> Device is found!
connecting: 40% complete
> Device has firmware version 1.6
> Available space for user applications: 6012 bytes
> Suggested sleep time between sending pages: 8ms
> Whole page count: 94  page size: 64
> Erase function sleep duration: 752ms
parsing: 60% complete
> Erasing the memory ...
erasing: 80% complete
> Starting to upload ...
writing: 100% complete
>> Micronucleus done. Thank you!

Usually I expect interface to have 2 endpoints (in & out from usb.h):

#define USB_ENDPOINT_IN         0x80
#define USB_ENDPOINT_OUT        0x00

How is usb_control_msg(nucleus->device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT); working without endpoint?

  • 3
    \$\begingroup\$ Endpoint 0 is special; every USB device in every interface configuration must support EP0OUT to receive control messages from the host and EP0IN to provide status responses to the host. The usb control message cited above is addressing EP0IN because it has the USB_ENDPOINT_IN flag with channel 0 implicit. Most likely this device is using a custom, vendor-specific message to communicate, similar to Cypress EZ-USB devices. \$\endgroup\$
    – MarkU
    Commented Aug 23, 2017 at 20:51
  • \$\begingroup\$ you're right. Here is more detailed answer arduino.stackexchange.com/a/44026/8327 \$\endgroup\$
    – 4ntoine
    Commented Aug 24, 2017 at 5:19
  • \$\begingroup\$ @Null: Is there a tag which should be used for USB Communications Device Class? \$\endgroup\$
    – Ben Voigt
    Commented Nov 10, 2021 at 21:47
  • \$\begingroup\$ @BenVoigt Not that I'm aware of. \$\endgroup\$
    – Null
    Commented Nov 10, 2021 at 21:49

1 Answer 1


There is default endpoint 0 present on each device. It is bidirectional. It is active right after you connect the device to USB, even before any configuration is set.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.