usbdriverusb-debuggingusb-descriptorusb-audio

UAC 2.0 Microphone USB Configuration Descriptor


I am really trying to understand the ADC2.0 spec to create a really simple USB UAC2.0 8 bit microphone. My device enumerates fine, but the driver doesn't like it (it says it cannot start).

Q1. How do you find out what issues the driver has with the configuration descriptor on Windows? I have followed the guides to get the Windows Network Monitor working, but that doesn't seem to provide much information on the actual driver issue.

Optional Q2. Can you seem to find any issues with my configuration descriptor? I would love to know what the issue is.

const uint8_t __attribute__((aligned(4))) Device_Configuration_Descriptor[127] =
{
    // Configuration Descriptor
    9,
    USB_DT_CONFIGURATION,
    127, 0, // Total length ////////////////////////////////////////////////////////////////////////////////////
    2, // No. Interfaces
    1, // Configuration value
    1, // iConfiguration - this configuration
    0b11000000, // bmAttributes - Powered by bus and Host
    50, // 100mA

    // IAD
    8, // Size of IAD
    USB_DT_IAD, // Descriptor type
    0, // bFirstInterface
    2, // The next two interfaces are in this IAD
    1, // Audio function class code
    0, // Audio function subclass undefined
    0x20, // IP_VERSION_02_00 protocol
    0, // Function string index - put in later

    // Interface 0 - Audio control - no end point because no functions
    9, // Interface descriptor class
    USB_DT_INTERFACE, // Descriptor type
    0, // Number of interface
    0, // Alternate setting number
    0, // No end points for audio control
    1, // Audio interface class code
    1, // Audio control interface sub class code
    0x20, // Audio control protocol
    0, // Interface string index

    // CS - AC Self Descriptor
    9, // Size of descriptor
    CS_INTERFACE, // CS interface descriptor type
    CS_AC_HEADER, // Header descriptor type
    0, 2, // bcdADC release - 2.0
    0x03, // bCategory - this device is a microphone
    46, 0, // Total AC descriptor length (this one plus the clock, terminal, unit descriptors) ////////////////////
    0, // No controls present

    // Clock Source Descriptor
    8, // Size
    CS_INTERFACE, // CS interface descriptor type
    CS_AC_CLOCK_SOURCE, // CS Clock source type
    2, // Unique clock ID
    0b110, // Synced to SOF, Internal variable clock
    0, // No clock controls
    0, // Assoc terminal is 0
    0, // No string index

    // Input terminal descriptor
    17, // Size
    CS_INTERFACE, // CS interface descriptor type
    CS_AC_INPUT_TERMINAL, // Input terminal type
    6, // ID
    0x01, 0x02, // Generic microphone ID
    0, // Associated output terminal
    2, // ID of connected clock terminal
    1, // No. of output channels
    0b100, 0, 0, 0, // Front centre location
    0, // No string for channel
    0, 0, // No controls
    0, // String index for input terminal

    // Output terminal descriptor
    12, // Size
    CS_INTERFACE, // CS interface descriptor type
    CS_AC_OUTPUT_TERMINAL, // Output terminal type
    7, // Output terminal ID
    0x01, 0x01, // USB streaming output type
    0, // No association
    6, // Signal source from IT 6
    2, // ID of clock
    0, 0, // No controls
    0, // No string

    // No AC endpoints to describe

    // Interface 1 - AS - AF0 - zero bandwidth
    9, // Interface descriptor class
    USB_DT_INTERFACE, // Descriptor type
    1, // Number of interface
    0, // Alternate setting number
    0, // No end points for audio control
    1, // Audio interface class code
    2, // Audio streaming interface sub class code
    0, // Audio control protocol
    0, // Interface string index

    // Interface 1 - AS - AF1 - streaming setting
    9, // Interface descriptor class
    USB_DT_INTERFACE, // Descriptor type
    1, // Number of interface
    1, // Alternate setting number
    1, // One end point for audio control
    1, // Audio interface class code
    2, // Audio streaming interface sub class code
    0, // Audio control protocol
    0, // Interface string index

    // AS AF1 Class Specific Interface
    16, // Size
    CS_INTERFACE, // CS interface descriptor type
    0x01, // AS General descriptor type
    7, // Linking to the output terminal
    0, // No controls
    1, // Format type 1
    0b10, 0, 0, 0, // PCM8 format type
    1, // No. of channels (mono)
    0b100, 0, 0, 0, // Front centre
    0, // No string

    // Type 1 Format descriptor type
    6, // Size
    CS_INTERFACE, // CS interface descriptor type
    0x02, // Format type descriptor
    1, // Format type 1
    1, // Audio subslot size
    8, // Use all 8 bits in the subslot

    // Standard endpoint descriptor
    7, // Size
    USB_DT_ENDPOINT, // Endpoint type
    0b10000001, // In endpoint, address 1
    0b00001101, // Data endpoint, synchronous, Isochronous
    48, 0,
    1, // Interval

    // CS Endpoint descriptor
    8, // Size
    CS_ENDPOINT, // Type
    1, // EP General
    0, // Max packet only = 0
    0, // No controls
    1, // Delay measured in ms
    20, 0, // 20ms delay before producing reliable clock source
};

Solution

  • You find out what issues the windows driver has with the device by reading all the documentation available on the driver you are trying to use.

    I have the fix. It turns out all that was needed to is to set the clock frequency control bits in the clock source descriptor. Which make sense because then how else can Windows 11 know the sampling frequency of the interface? After you send this Windows then asks for a range, then sets the frequency.

    Here is my entire attached configuration descriptor for a 16 bit PCM mono microphone channel, for a device whose clock is synced to the SOF packets.

    const uint8_t __attribute__((aligned(4))) Device_Configuration_Descriptor[127] =
    {
        // Configuration Descriptor
        9,
        USB_DT_CONFIGURATION,
        127, 0, // Total length
        2, // No. Interfaces
        0, // Configuration value
        0, // iConfiguration - this configuration
        0b10000000, // bmAttributes - Powered by bus and Host
        50, // 100mA
    
        // IAD
        8, // Size of IAD
        USB_DT_IAD, // Descriptor type
        0, // bFirstInterface
        2, // The next two interfaces are in this IAD
        1, // Audio function class code
        0, // Audio function subclass undefined
        0x20, // IP_VERSION_02_00 protocol
        0, // Function string index - put in later
    
        // Interface 0 - Audio control - no end point because no functions
        9, // Interface descriptor class
        USB_DT_INTERFACE, // Descriptor type
        0, // Number of interface
        0, // Alternate setting number
        0, // No end points for audio control
        1, // Audio interface class code
        1, // Audio control interface sub class code
        0x20, // Audio control protocol
        0, // Interface string index
    
        // CS - AC Self Descriptor
        9, // Size of descriptor
        CS_INTERFACE, // CS interface descriptor type
        CS_AC_HEADER, // Header descriptor type
        0, 2, // bcdADC release - 2.0
        0x03, // bCategory - this device is a microphone
        46, 0, // Total AC class descriptor length
        0, // Latency controls present
    
        // Clock Source Descriptor
        8, // Size
        CS_INTERFACE, // CS interface descriptor type
        CS_AC_CLOCK_SOURCE, // CS Clock source type
        2, // Unique clock ID
        0b110, // Synced to SOF, Internal variable clock
        0b11, // Clock freq control available
        0, // Assoc terminal is 0
        0, // No string index
    
        // Input terminal descriptor
        17, // Size
        CS_INTERFACE, // CS interface descriptor type
        CS_AC_INPUT_TERMINAL, // Input terminal type
        6, // ID
        0x01, 0x02, // Generic microphone ID
        0, // Associated output terminal
        2, // ID of connected clock terminal
        1, // No. of output channels
        0b1, 0, 0, 0, // Front left location
        0, // No string for channel
        0, 0, // Connector controls
        0, // String index for input terminal
    
        // Output terminal descriptor
        12, // Size
        CS_INTERFACE, // CS interface descriptor type
        CS_AC_OUTPUT_TERMINAL, // Output terminal type
        7, // Output terminal ID
        0x01, 0x01, // USB streaming output type
        0, // No association
        6, // Signal source from 6
        2, // ID of clock
        0, 0, // Connector controls
        0, // No string
    
        // No AC endpoints to describe
    
        // Interface 1 - AS - AF0 - zero bandwidth
        9, // Interface descriptor class
        USB_DT_INTERFACE, // Descriptor type
        1, // Number of interface
        0, // Alternate setting number
        0, // No end points for audio control
        1, // Audio interface class code
        2, // Audio streaming interface sub class code
        0x20, // Audio control protocol
        0, // Interface string index
    
        // Interface 1 - AS - AF1 - streaming setting
        9, // Interface descriptor class
        USB_DT_INTERFACE, // Descriptor type
        1, // Number of interface
        1, // Alternate setting number
        1, // One end point for audio control
        1, // Audio interface class code
        2, // Audio streaming interface sub class code
        0x20, // Audio control protocol
        0, // Interface string index
    
        // AS AF1 Class Specific Interface
        16, // Size
        CS_INTERFACE, // CS interface descriptor type
        0x01, // AS General descriptor type
        7, // Linking to the output terminal
        0, // All controls
        1, // Format type 1
        0b1, 0, 0, 0, // PCM format type
        1, // No. of channels (mono)
        1, 0, 0, 0, // Front left
        0, // No string
    
        // Type 1 Format descriptor type
        6, // Size
        CS_INTERFACE, // CS interface descriptor type
        0x02, // Format type descriptor
        1, // Format type 1
        2, // Audio subslot size
        16, // Use all 16 bits in the subslot
    
        // Standard endpoint descriptor
        7, // Size
        USB_DT_ENDPOINT, // Endpoint type
        0b10000001, // In endpoint, address 1
        0b1101, // Data endpoint, synchronous, Isochronous
        96, 0,
        1, // Interval
    
        // CS Endpoint descriptor
        8, // Size
        CS_ENDPOINT, // Type
        1, // EP General
        0, // Max packet only = 0
        0, // No controls
        0, // Delay measured in ms
        0, 0, // No delay before producing reliable clock source
    };