Jorge,
I created the USB Audio setup based off of the USB HID Mouse example. I included the state machine below that sets the control and streaming interfaces.
The device I'm streaming from has 6, 16-bit, 16kHz PCM audio channels.
I was under the impression that there should be one data packet each USB Full Speed frame of 1 ms, or 1000 transfers per second. However, you mentioned that there is instead one isochronous transfer per 125 us, or 8000 transfers per second. Can you explain why that is true?
Mirroring your calculation above: 16,000 kHz * 6 channels * 2 bytes (16-bit) = 192,000 bytes per second.
192,000 bytes / 8000 transfers per second = 24 bytes per transfer.
I'm still unable to explain why the received dataLength is 128 bytes and not 24 bytes as the above calculation shows.
My biggest problem is that 128 is not divisible by 6, so I don't know how to interpret the data into its separate channels.
typedef enum USBHostAudioRunState
{
USBHostAudioRunState_Idle = 0,
USBHostAudioRunState_SetControlInterface,
USBHostAudioRunState_WaitSetControlInterface,
USBHostAudioRunState_SetStreamingInterface,
USBHostAudioRunState_WaitSetStreamingInterface,
USBHostAudioRunState_ReceiveStream,
USBHostAudioRunState_WaitReceiveStream
} USBHostAudioRunState_t;
typedef struct USBHostAudioInstance
{
usb_host_configuration_handle configHandle;
usb_device_handle deviceHandle;
usb_host_class_handle classHandle;
usb_host_interface_handle streamingInterfaceHandle;
usb_host_interface_handle controlInterfaceHandle;
uint8_t deviceState;
uint8_t prevState;
uint8_t runState;
uint8_t runWaitState;
uint16_t maxPacketSize;
uint8_t *audioBuffer;
} USBHostAudioInstance_t;
static void _HostAudioStateManager(void *param)
{
usb_status_t status;
USBHostAudioInstance_t *audioInstance = (USBHostAudioInstance_t *)param;
if (audioInstance->deviceState != audioInstance->prevState)
{
audioInstance->prevState = audioInstance->deviceState;
switch (audioInstance->deviceState)
{
case kStatus_DEV_Idle:
break;
case kStatus_DEV_Attached:
audioInstance->runState = USBHostAudioRunState_SetControlInterface;
status = USB_HostAudioInit(audioInstance->deviceHandle, &audioInstance->classHandle);
if (status != kStatus_USB_Success)
{
DEBUG_USB("USB Host Audio class initialize failure\r\n");
ASSERT_FAILURE();
}
break;
case kStatus_DEV_Detached:
audioInstance->deviceState = kStatus_DEV_Idle;
audioInstance->runState = USBHostAudioRunState_Idle;
USB_HostAudioDeinit(audioInstance->deviceHandle,
audioInstance->classHandle);
audioInstance->classHandle = NULL;
DEBUG_USB("USB Audio device detached\r\n");
break;
default:
break;
}
}
switch (audioInstance->runState)
{
case USBHostAudioRunState_Idle:
break;
case USBHostAudioRunState_SetControlInterface:
audioInstance->runWaitState = USBHostAudioRunState_WaitSetControlInterface;
audioInstance->runState = USBHostAudioRunState_Idle;
status = USB_HostAudioControlSetInterface(audioInstance->classHandle,
audioInstance->controlInterfaceHandle,
0,
_HostAudioControlCallback,
audioInstance);
ASSERT(status == kStatus_USB_Success);
DEBUG_USB("Set Control Interface Complete\r\n");
break;
case USBHostAudioRunState_SetStreamingInterface:
audioInstance->runWaitState = USBHostAudioRunState_WaitSetStreamingInterface;
audioInstance->runState = USBHostAudioRunState_Idle;
status = USB_HostAudioStreamSetInterface(audioInstance->classHandle,
audioInstance->streamingInterfaceHandle,
1,
_HostAudioControlCallback,
audioInstance);
ASSERT(status == kStatus_USB_Success);
DEBUG_USB("Set Streaming Interface Complete\r\n");
break;
case USBHostAudioRunState_ReceiveStream:
audioInstance->runWaitState = USBHostAudioRunState_WaitReceiveStream;
audioInstance->runState = USBHostAudioRunState_Idle;
status = USB_HostAudioStreamRecv(audioInstance->classHandle,
audioInstance->audioBuffer,
AUDIO_BUFFER_SIZE,
_HostAudioInCallback,
audioInstance);
ASSERT(status == kStatus_USB_Success);
break;
default:
break;
}
}