I recently got a hold of an xCore-200 eXplorekit and have been developing a USB-based system with the device. I'm starting with trying to get the device to appear as a USB microphone so it can generate audio tones to the computer. I have code based on the xud usb lib examples and the device specification from the USB Audio standard PDF.
When I plug in the device, I do not get desirable results. Windows says the device descriptor request failed. Thus, I put in a lot of debug printf() statements both in my code and the xud library. I traced down to the USB_StandardRequests, and found that we are in fact correctly routing the device request (which windows is sending on the order of once per second), but that the relevant call to the XUD_DoGetRequest function within USB_StandardRequests is failing with an error. The relevant code is:
Code: Select all
else if(devDescLength_hs != 0)
{
/* Return high-speed device descriptor, if no FS desc, send the HS desc */
/* Do get request (send descriptor then 0 length status stage) */
printf("Do the high-speed usb\n");
return XUD_DoGetRequest(ep_out, ep_in, devDesc_hs, devDescLength_hs, sp.wLength);
}
Here is my main program:
Code: Select all
XUD_Result_t ControlInterfaceClassRequests(XUD_ep ep_out, XUD_ep ep_in, USB_SetupPacket_t sp)
{
unsigned int buffer[32];
printf("Ignore control %x\n", sp.bRequest);
//return XUD_RES_OKAY;
if (sp.bRequest == 0x21)
return XUD_DoGetRequest(ep_out, ep_in, (buffer, unsigned char[]), 7, sp.wLength);
return XUD_DoSetRequestStatus(ep_in);
}
void EndPoint0(chanend chan_ep0_out, chanend chan_ep0_in)
{
printf("Starting\n");
USB_SetupPacket_t sp;
unsigned bmRequestType;
XUD_BusSpeed_t usbBusSpeed;
XUD_ep ep0_out = XUD_InitEp(chan_ep0_out, XUD_EPTYPE_CTL | XUD_STATUS_ENABLE);
XUD_ep ep0_in = XUD_InitEp(chan_ep0_in, XUD_EPTYPE_CTL | XUD_STATUS_ENABLE);
printf("Started!\n");
while(1)
{
// Returns XUD_RES_OKAY on success, XUD_RES_RST for USB reset
XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, sp);
if (result == XUD_RES_OKAY) {
result = XUD_RES_ERR;
bmRequestType = (sp.bmRequestType.Direction<<7) |
(sp.bmRequestType.Type<<5) |
(sp.bmRequestType.Recipient);
printf("Setup packet: %u - %u - %u - %u - %u\n", bmRequestType, USB_BMREQ_H2D_CLASS_INT,
USB_BMREQ_D2H_CLASS_INT, USB_BMREQ_H2D_STANDARD_DEV, USB_BMREQ_D2H_STANDARD_DEV);
printf("Setup packet request = %u, index = %u, len = %u, value = %u\n",
sp.bRequest, sp.wIndex, sp.wLength, sp.wValue);
if ((bmRequestType == USB_BMREQ_H2D_STANDARD_DEV)
&& (sp.bRequest == USB_SET_ADDRESS)) {
// Host has set device address, value contained in sp.wValue
}
switch(bmRequestType) {
/* Direction: Device-to-host and Host-to-device
* Type: Class
* Recipient: Interface
*/
case USB_BMREQ_H2D_CLASS_INT:
case USB_BMREQ_D2H_CLASS_INT:
/* Inspect for CDC Communications Class interface num */
if(sp.wIndex == 0) {
/* Returns XUD_RES_OKAY if handled,
* XUD_RES_ERR if not handled,
* XUD_RES_RST for bus reset */
result = ControlInterfaceClassRequests(ep0_out, ep0_in, sp);
}
break;
}
}
if (result == XUD_RES_ERR) {
/* Returns XUD_RES_OKAY if handled okay,
* XUD_RES_ERR if request was not handled (STALLed),
* XUD_RES_RST for USB Reset */
printf("Do standard\n");
unsafe {
result = USB_StandardRequests(ep0_out, ep0_in, devDesc,
sizeof(devDesc), cfgDesc, sizeof(cfgDesc),
null, 0, null, 0, stringDescriptors,
sizeof(stringDescriptors)/sizeof(stringDescriptors[0]),
sp, usbBusSpeed);
}
printf("Result = %d\n", result);
}
if (result == XUD_RES_RST) {
usbBusSpeed = XUD_ResetEndpoint(ep0_out, ep0_in);
}
}
}
#define CHANNELS_OUT 2
#define CHANNELS_IN 2
void microphone_channel(chanend c_ep1, chanend c_ep2) {
char buffer[] = {0, 0, 0, 0};
int counter = 0;
int state = 0;
XUD_ep c_ep = XUD_InitEp(c_ep1, XUD_EPTYPE_ISO);
XUD_ep c_epo = XUD_InitEp(c_ep2, XUD_EPTYPE_ISO);
//while (1) {
// XUD_SetBuffer(c_ep, buffer, 4) < 0;
//}
}
int main(void) {
chan c_ep_out[CHANNELS_OUT], c_ep_in[CHANNELS_IN];
par {
on USB_TILE: xud(c_ep_out, CHANNELS_OUT, c_ep_in, CHANNELS_IN,
null, XUD_SPEED_HS, XUD_PWR_SELF);
on USB_TILE: EndPoint0(c_ep_out[0], c_ep_in[0]);
on USB_TILE: microphone_channel(c_ep_out[1], c_ep_in[1]);
}
return 0;
}
Here is the descriptors:
Code: Select all
/* Definition of Descriptors */
/* USB Device Descriptor */
static unsigned char devDesc[] =
{
0x12, /* 0 bLength */
USB_DESCTYPE_DEVICE, /* 1 bdescriptorType - Device*/
0x00, /* 2 bcdUSB version */
0x01, /* 3 bcdUSB version */
0x00, /* 4 bDeviceClass - USB CDC Class */
0x00, /* 5 bDeviceSubClass - Specified by interface */
0x00, /* 6 bDeviceProtocol - Specified by interface */
0x08, /* 7 bMaxPacketSize for EP0 - max = 64*/
(VENDOR_ID & 0xFF), /* 8 idVendor */
(VENDOR_ID >> 8), /* 9 idVendor */
(PRODUCT_ID & 0xFF), /* 10 idProduct */
(PRODUCT_ID >> 8), /* 11 idProduct */
(BCD_DEVICE & 0xFF), /* 12 bcdDevice */
(BCD_DEVICE >> 8), /* 13 bcdDevice */
0x01, /* 14 iManufacturer - index of string*/
0x02, /* 15 iProduct - index of string*/
0x03, /* 16 iSerialNumber - index of string*/
0x01 /* 17 bNumConfigurations */
};
/* USB Configuration Descriptor */
static unsigned char cfgDesc[0x64] = {
0x09, /* 0 bLength */
USB_DESCTYPE_CONFIGURATION, /* 1 bDescriptortype - Configuration*/
0x64, 0x00, /* 2 wTotalLength */
0x02, /* 4 bNumInterfaces */
0x01, /* 5 bConfigurationValue */
0x00, /* 6 iConfiguration - index of string */
0x80, /* 7 bmAttributes - Bus powered */
0xFF, /* 8 bMaxPower - 1000mA */
/* Audio Control interface */
0x09, /* 0 bLength */
0x04, /* 1 bDescriptorType - Interface */
0x00, /* 2 bInterfaceNumber - Interface 0 */
0x00, /* 3 bAlternateSetting */
0x00, /* 4 bNumEndpoints */
0x01, /* 5 bInterfaceClass */
0x01, /* 6 bInterfaceSubClass */
0x00, /* 7 bInterfaceProtocol */
0x00, /* 8 iInterface - No string descriptor */
/* Header Functional descriptor */
0x09, /* 0 bLength */
0x24, /* 1 bDescriptortype, CS_INTERFACE */
0x01, /* 2 bDescriptorsubtype, HEADER */
0x00, 0x01, /* 3 bcdADC */
0x1E, 0x00, /* 5 wTotalLength */
0x01, /* 7 number of streaming interfaces */
0x01, /* 8 AudioStreaming interface 1 */
/* Input Terminal descriptor */
0x0C, /* 0 bLength */
0x24, /* 1 bDescriptortype, CS_INTERFACE */
0x02, /* 2 bDescriptorsubtype, INPUT_TERMINAL */
0x01, /* 3 bTerminalID */
0x01, 0x02, /* 4 wTerminalType (microphone) */
0x00, /* 6 bAssocTerminal */
0x01, /* 7 bNbrChannels */
0x00, 0x00, /* 8 wChannelConfig */
0x00, /* 10 iChannelNames */
0x00, /* 10 iTerminal */
/* Output Terminal descriptor */
0x09, /* 0 bLength */
0x24, /* 1 bDescriptortype, CS_INTERFACE */
0x03, /* 2 OUTPUT_TERMINAL */
0x02, /* 3 bTerminalID */
0x01, 0x01, /* 4 wTerminalType (usb streaming) */
0x00, /* 6 bAssocTerminal */
0x01, /* 7 bSourceID */
0x00, /* 8 iTerminal */
/* Standard AS Interface Descriptor (OFF) */
0x09, /* 0 bLength */
0x04, /* 1 bDescriptortype, INTERFACE */
0x01, /* 2 bInterfaceNumber */
0x00, /* 3 bAnternateSetting */
0x00, /* 4 bNumEndpoints */
0x01, /* 5 bInterfaceClass (AUDIO) */
0x02, /* 6 bInterfaceSubclass (AUDIO_STREAMING) */
0x00, /* 7 bInterface */
0x00, /* 8 bNumEndpoints */
/* Standard AS Interface Descriptor (ON) */
0x09, /* 0 bLength */
0x04, /* 1 bDescriptortype, INTERFACE */
0x01, /* 2 bInterfaceNumber */
0x01, /* 3 bAnternateSetting */
0x01, /* 4 bNumEndpoints */
0x01, /* 5 bInterfaceClass (AUDIO) */
0x02, /* 6 bInterfaceSubclass (AUDIO_STREAMING) */
0x00, /* 7 bInterface */
0x00, /* 8 bNumEndpoints */
/* Class-specific AS General Interface */
0x07, /* 0 bLength */
0x24, /* 1 bDescriptorType, CS_INTERFACE */
0x01, /* 2 bDescriptorSubtype, GENERAL */
0x02, /* 3 bTerminalLink */
0x01, /* 4 bDelay */
0x01, 0x00, /* 5 wFormatTag */
/* Type I Format Type */
0x0B, /* 0 bLength */
0x24, /* 1 bDescriptorType, CS_INTERFACE */
0x02, /* 2 bDescriptorSubtype, FORMAT_TYPE */
0x01, /* 3 bFormatType, FORMAT_TYPE_I */
0x01, /* 4 bNbrChannels */
0x02, /* 5 bSubFrameSize */
0x10, /* 6 bBitResolution */
0x01, /* 7 bSamFreqType */
0x40, 0x1f, 0x00, /* 8 tSamFreq */
/* USB Microphone Standard Endpoint Descriptor */
0x09, /* 0 bLength */
0x05, /* 1 bDescriptorType, ENDPOINT */
0x81, /* 2 bEndpointAddress, IN ENDPOINT 1 */
0x01, /* 3 bmAttributes */
0x10, 0x00, /* 4 wMaxPacketSize */
0x01, /* 6 bInterval */
0x00, /* 7 bRefresh */
0x00, /* 8 bSynchAddress */
/* Class-specific Audio Data Endpoint Descriptor */
0x07, /* 0 bLength */
0x25, /* 1 bDescriptorType, CS_ENDPOINT */
0x01, /* 2 bDescriptorSubtype, GENERAL */
0x00, /* 3 bmAttributes */
0x00, /* 4 bLockDelayUnits */
0x00, 0x00, /* 5 wLockDelay */
};
unsafe{
/* String table - unsafe as accessed via shared memory */
static char * unsafe stringDescriptors[]=
{
"\x09\x04", /* Language ID string (US English) */
"Test Co", /* iManufacturer */
"Test Audio Board", /* iProduct */
"0123456789" /* iSerialNumber */
"Config", /* iConfiguration string */
};
}
Thanks!