XUD: Interrupt endpoint fires one time only

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
julian
New User
Posts: 2
Joined: Thu Aug 27, 2015 4:23 pm

XUD: Interrupt endpoint fires one time only

Post by julian »

Hi,

I am extending the USB Audio 2.0 Firmware to make use of the the optional interrupt endpoint for informing the host about changes in the devices volume by user-interaction with the hardware.
For this I enabled the interrupt endpoint, which by default is only enabled for SPDIF_RX or ADAT_RX enabled setups, which I don't have.
Listing the descriptors the endpoint looks like this:

Code: Select all

      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0006  1x 6 bytes
        bInterval               8
The alsa usb audio driver detects the endpoint and sets it up properly, which results in an incoming USB packet requesting for the next interrupt:

Code: Select all

Frame 2845376: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface 0
    Interface id: 0 (usbmon1)
    Encapsulation type: USB packets with Linux header and padding (115)
    Arrival Time: Aug 27, 2015 17:09:22.208912000 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1440688162.208912000 seconds
    [Time delta from previous captured frame: 0.000021000 seconds]
    [Time delta from previous displayed frame: 2.093103000 seconds]
    [Time since reference or first frame: 2112.910262000 seconds]
    Frame Number: 2845376
    Frame Length: 64 bytes (512 bits)
    Capture Length: 64 bytes (512 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    URB id: 0xffff8803df41af00
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x83, Direction: IN
        1... .... = Direction: IN (1)
        .000 0011 = Endpoint value: 3
    Device: 47
    URB bus id: 1
    Device setup request: not relevant ('-')
    Data: not present ('<')
    URB sec: 1440688162
    URB usec: 208912
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 6
    Data length [bytes]: 0
    [Response in: 2864225]
    [bInterfaceClass: Audio (0x01)]
    Unused Setup Header
    Interval: 128
    Start frame: 0
    Copy of Transfer Flags: 0x00000200
    Number of ISO descriptors: 0
Now I can change the volume on my device which causes an a SetReady_In on the endpoint interrupt and generates a USB packet immediately:

Code: Select all

Frame 2864225: 70 bytes on wire (560 bits), 70 bytes captured (560 bits) on interface 0
    Interface id: 0 (usbmon1)
    Encapsulation type: USB packets with Linux header and padding (115)
    Arrival Time: Aug 27, 2015 17:09:25.340713000 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1440688165.340713000 seconds
    [Time delta from previous captured frame: 0.000764000 seconds]
    [Time delta from previous displayed frame: 3.131801000 seconds]
    [Time since reference or first frame: 2116.042063000 seconds]
    Frame Number: 2864225
    Frame Length: 70 bytes (560 bits)
    Capture Length: 70 bytes (560 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    URB id: 0xffff8803df41af00
    URB type: URB_COMPLETE ('C')
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x83, Direction: IN
        1... .... = Direction: IN (1)
        .000 0011 = Endpoint value: 3
    Device: 47
    URB bus id: 1
    Device setup request: not relevant ('-')
    Data: present (0)
    URB sec: 1440688165
    URB usec: 340713
    URB status: Success (0)
    URB length [bytes]: 6
    Data length [bytes]: 6
    [Request in: 2845376]
    [Time from request: 3.131801000 seconds]
    [bInterfaceClass: Audio (0x01)]
    Unused Setup Header
    Interval: 128
    Start frame: 0
    Copy of Transfer Flags: 0x00000200
    Number of ISO descriptors: 0
The host driver receives it, decodes it properly and sends a new request for the next interrupt:

Code: Select all

Frame 2864226: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface 0
    Interface id: 0 (usbmon1)
    Encapsulation type: USB packets with Linux header and padding (115)
    Arrival Time: Aug 27, 2015 17:09:25.340793000 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1440688165.340793000 seconds
    [Time delta from previous captured frame: 0.000080000 seconds]
    [Time delta from previous displayed frame: 0.000080000 seconds]
    [Time since reference or first frame: 2116.042143000 seconds]
    Frame Number: 2864226
    Frame Length: 64 bytes (512 bits)
    Capture Length: 64 bytes (512 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    URB id: 0xffff8803df41af00
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x83, Direction: IN
        1... .... = Direction: IN (1)
        .000 0011 = Endpoint value: 3
    Device: 47
    URB bus id: 1
    Device setup request: not relevant ('-')
    Data: not present ('<')
    URB sec: 1440688165
    URB usec: 340793
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 6
    Data length [bytes]: 0
    [bInterfaceClass: Audio (0x01)]
    Unused Setup Header
    Interval: 128
    Start frame: 0
    Copy of Transfer Flags: 0x00000200
    Number of ISO descriptors: 0
From there on no further communication on the interrupt endpoint can be seen in wireshark. Although the application on the xcore does successfully run through the XUD_SetReady_In->XUD_SetData_Select cycle each time the volume is changed. So it looks to me as if XUD_SetData_Select would return false positives.

The actual code for this landed in usb_buffer.xc, buffer(), to which I added a new channel on which the volume changes are reported from the audio io core. So the select block contains this:

Code: Select all

#ifdef USB_VENDOR_VOLUME_BUTTONS
            case inuint_byref(c_vol_int, u_tmp):
                chkct(c_vol_int, XS1_CT_END);

                printf("volume interrupt requested\n");
                /* Check if we have interrupt pending.
                 * Note, this his means we can loose interrupts... */
                if(!g_intFlag)
                {
                    printf("volume interrupt generated\n");
                    g_intFlag = 1;

                    g_intData[3] = FU_VOLUME_CONTROL;
                    g_intData[2] = 0;
                    g_intData[5] = FU_USBOUT;
                    g_intData[4] = INTERFACE_NUMBER_AUDIO_CONTROL;

                    XUD_SetReady_In(ep_int, g_intData, 6);
                }
                break;
#endif


#if defined(SPDIF_RX) || defined(ADAT_RX) || defined(USB_VENDOR_VOLUME_BUTTONS)
            /* Interrupt EP data sent, clear flag */
            case XUD_SetData_Select(c_ep_int, ep_int, result):
            {
                printf("volume interrupt cleared: %d\n", result);
                g_intFlag = 0;
                break;
            }
#endif
Of course all the initialisation for ep_int is also activated for USB_VENDOR_VOLUME_BUTTONS now - otherwise it wouldn't work at all I presume.
Each time I change the volume the debug log clearly states it would have generated an interrupt properly and sent it to the host:

Code: Select all

Rotary delta: -1
Set volume to -22528 for channel 0
volume interrupt requested
volume interrupt generated
volume interrupt cleared: 0
Rotary delta: -1
Set volume to -22784 for channel 0
volume interrupt requested
volume interrupt generated
volume interrupt cleared: 0
But it never generates an actual USB packet anymore which I could see on the host. Does anybody have any ideas what might cause this behaviour or how to trace it further?

-Julian


julian
New User
Posts: 2
Joined: Thu Aug 27, 2015 4:23 pm

Post by julian »

Sometimes it helps to write about issues... I missed to adapt epTypeTableIn properly. The endpoint works as expected now.