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
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
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
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
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
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
-Julian