Hi Guy,
I am using the USB Audio Device Class, I have the interface descriptors set up as follows:
0 - Control
1 - ISO Audio Streaming IN
2 - ISO Audio Streaming Out
The device is recognised but there is an issue with interface 2 where the endpoints have not been initialised.
Looking at the code in USB_DeviceAudioStreamEndpointsInit() in usb_device_audio.c we see:
usb_status_t USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t *audioHandle)
{
usb_device_interface_list_t *interfaceList;
usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL;
usb_status_t error = kStatus_USB_Error;
/* Check the configuration is valid or not. */
if (!audioHandle->configuration)
{
return error;
}
/* Check the configuration is valid or not. */
if (audioHandle->configuration > audioHandle->configStruct->classInfomation->configurations)
{
return error;
}
if (NULL == audioHandle->configStruct->classInfomation->interfaceList)
{
return error;
}
/* Get the interface list of the new configuration. */
interfaceList = &audioHandle->configStruct->classInfomation->interfaceList[audioHandle->configuration - 1];
/* Find stream interface by using the alternate setting of the interface. */
for (int count = 0U; count < interfaceList->count; count++)
{
if ((USB_DEVICE_CONFIG_AUDIO_CLASS_CODE == interfaceList->interfaces[count].classCode) &&
(USB_DEVICE_AUDIO_STREAM_SUBCLASS == interfaceList->interfaces[count].subclassCode))
{
for (int index = 0; index < interfaceList->interfaces[count].count; index++)
{
if (interfaceList->interfaces[count].interface[index].alternateSetting == audioHandle->streamAlternate)
{
interface = &interfaceList->interfaces[count].interface[index];
break;
}
}
audioHandle->streamInterfaceNumber = interfaceList->interfaces[count].interfaceNumber;
break;
}
}
if (!interface)
{
return error;
}
/* Keep new stream interface handle. */
audioHandle->streamInterfaceHandle = interface;
/* Initialize the endpoints of the new interface. */
for (int count = 0U; count < interface->endpointList.count; count++)
{
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
epInitStruct.zlt = 0U;
epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
if ((USB_ENDPOINT_ISOCHRONOUS == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) &&
(USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
{
epCallback.callbackFn = USB_DeviceAudioIsochronousIn;
}
else
{
epCallback.callbackFn = USB_DeviceAudioIsochronousOut;
}
epCallback.callbackParam = audioHandle;
error = USB_DeviceInitEndpoint(audioHandle->handle, &epInitStruct, &epCallback);
}
return error;
}
The code is only initialising the endpoints of the first audio streaming interface it finds.
Does the Audio Class only support one Audio Streaming interface?
Cheers
Andy
Hi Andy,
Could you tell us which MCU are you using?
Thanks in advance!
Best Regards,
Carlos Mendoza
Technical Support Engineer
Hi Carlos,
I have some more info:
I bodged USB_DeviceAudioStreamEndpointsInit() to correctly initialise the endpoints and now I have audio streaming to the 1050 and echoed back to the host so it looks like the audio device class can work in this way.
The main issue is that only one interface is stored away in audioHandle-streamInterfareHandle and this is used for de-init and halt. So a proper fix would require multiple streamInterfaceHandles to be stored in audioHandle.
Cheers
Andy
Hi Andy
may be useful to check AN4665 How to Use Freescale USB Stack to Implement Audio Class Device
http://cache.freescale.com/files/32bit/doc/app_note/AN4665.pdf
Best regards
igor
Hi Igor,
Thanks for the info, the freescale API used in the link is different to the Usb Audio Device code.
I just re-coded the Usb Audio Device code to make it work in the end, there wasn't much that needed changing. It might be worth NXP fixing up the code though as the "Control/Iso In/Iso Out" way of doing things is fairly standard.
Thanks
Andy
Hi Carlos,
Thanks for the reply.
The board is a iMXRT1050-EVKB
Andy