Back to engineering archive

Record 056 / Firmware and control

LUFA USB descriptor configuration repair

USB descriptor and LUFA configuration corrections for an Arduino Leonardo/WinAVR build.

Firmware module
LUFAUSB descriptorsEmbedded CBuild configuration

Firmware flow

Select the descriptor for a USB host request

Selected LUFA-derived descriptor callback from the corrected package.

The request type selects a descriptor family. String requests additionally select a numbered entry. Unrecognised requests leave the initial null address and NO_DESCRIPTOR result in place.

An explanation of a LUFA-derived callback in the corrected package, not a new USB framework, physical compatibility test or independent rebuild.

Read the implementation

Descriptors.c and LUFAconfig.h — selected LUFA-derived callback and configuration. Code is unchanged; the diagram explains its request handling.

LUFA Library — Copyright (C) Dean Camera, 2017. Source copyright, permission and notice.

uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
                                    const uint16_t wIndex,
                                    const void** const DescriptorAddress)
{
    const uint8_t DescriptorType = (wValue >> 8);
    const uint8_t DescriptorNumber = (wValue & 0xFF);

    const void* Address = NULL;
    uint16_t Size = NO_DESCRIPTOR;

    switch (DescriptorType)
    {
        case DTYPE_Device:
            Address = &DeviceDescriptor;
            Size    = sizeof(DeviceDescriptor);
            break;

        case DTYPE_Configuration:
            Address = &ConfigurationDescriptor;
            Size    = sizeof(ConfigurationDescriptor);
            break;

        case DTYPE_String:
            switch (DescriptorNumber)
            {
                case 0x00:
                    Address = &LanguageString;
                    Size    = pgm_read_byte(&LanguageString.Header.Size);
                    break;
                case 0x01:
                    Address = &ManufacturerString;
                    Size    = pgm_read_byte(&ManufacturerString.Header.Size);
                    break;
                case 0x02:
                    Address = &ProductString;
                    Size    = pgm_read_byte(&ProductString.Header.Size);
                    break;
                case 0x03:
                    Address = &SerialString;
                    Size    = pgm_read_byte(&SerialString.Header.Size);
                    break;
            }
            break;

        case HID_DTYPE_HID:
            Address = &ConfigurationDescriptor.HID_MouseHID;
            Size    = sizeof(USB_HID_Descriptor_HID_t);
            break;

        case HID_DTYPE_Report:
            Address = &MouseReport;
            Size    = sizeof(MouseReport);
            break;
    }

    *DescriptorAddress = Address;
    return Size;
}
#define USE_STATIC_OPTIONS                (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED)
#define USB_DEVICE_ONLY
#define FIXED_CONTROL_ENDPOINT_SIZE       8
#define FIXED_NUM_CONFIGURATIONS          1

Technical notes

Configuration and compilation repair

The work corrected descriptor and LUFA configuration files for an Arduino Leonardo/WinAVR build. The descriptor callback below is LUFA-derived; the contribution was configuration and compilation repair, rather than developing the USB framework.

Match the host request to a descriptor

The callback separates the descriptor type from its number. Device and configuration requests select fixed structures; string requests select one of four entries and read its length from program memory. HID and report requests select the corresponding mouse-interface data.

Keep the configuration explicit

The selected configuration enables device-only operation, fixes the control endpoint size at eight bytes and declares one configuration. Unknown descriptor requests retain a null address and NO_DESCRIPTOR. This source review did not rebuild the firmware or test a USB host connection.

Engineering archiveArchive record

Project enquiries

Discuss your project.

Tell us what you’re developing and where you need engineering support.

Discuss your project