Setting up an asynchronous feedback channel for an USB endpoint

76 Views Asked by At

I'm trying to build a sound card in rust, and I've gotten stuck at trying to get synchronization over USB to work. I want to get an isochronous endpoint to work with an asynchronous synchronization channel. If I have understood it correctly, which I would appreciate corrections on, you should be able to have an isochronous OUT endpoint that has a sych address specified in its descriptor. This address should point to an interrupt IN endpoint, which you then can use to report back the current length of the buffer of samples.

I have been able to set up the two endpoints by modifying the usbd-audio rust crate and usb-device to allow for these fields in the descriptors. At the moment they look like this in Wireshark, where the first endpoint is the isochronous OUT endpoint at address 0x1, and the second endpoint is the interrupt IN endpoint at address 0x3.

Wireshark capture

But the host doesn't seem to ever send any requests to the interrupt endpoint. Does anyone have any experience with this, who knows what I'm missing?

Thanks for the help in advance.

How to reprocuce

At the moment I've been using a modified version of the following pull request to usb-device to extend the endpoint functionality. I've done further extensions to it to allow for specifying synchronization type in the endpoint description. You can check out my branch of it.

The main difference is that synchronization type can be defined when an endpoint is allocated.

alloc.alloc(
    None, 
    EndpointType::Isochronous, 
    Some(SyncType::Asynchronous),
    stream_config.ep_size, 
    1
)?;

Which is then used in theusbd-audio crate like this.

// Get the interrupt endpoints address
let interrupt_address: u8 = u8::from(self.interrupt.endpoint.address());

writer.endpoint_with_additional_data(&self.endpoint, [
    0x00,   // bRefresh
    interrupt_address // bSynchAddress
])?; 

// Class-specific Isoc. Audio Data Endpoint Descriptor
writer.write(
    0x25,
    &[
        // bDescriptorType: CS_ENDPOINT
        0x01, // bDescriptorSubtype: GENERAL
        // bmAttributes - MaxpacketsOnly: False (0), Reserved,
        // Pitch control: False (0), Sampling frequency
        // control: False (0)
        0b0_00000_0_0, // bmAttributes
        0x00, // bLockDelayUnits
        0x00, 0x00, // wLockDelay
    ],
)

Where I can explicitly specify a synch address and a refresh rate for the isochronous endpoint descriptor, and then the various values for the class-specific descriptor. The easiest way of testing it is by using my branch of usbd-audio.

0

There are 0 best solutions below