USB Host Audio Stream Receive Data Corruption

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB Host Audio Stream Receive Data Corruption

37,127 Views
amwilhite
Contributor III

Description of problem

The audio data received when operating the NXP RT1050 as a USB Host with the Audio class does not represent the audio data spoken into a connected USB microphone device.

This issue exists not with just a single microphone or device, as I have tested three different types of USB microphones. I have independently tested the microphones with a PC to confirm they work correctly.

The data corruption has been confirmed by taking traces of the USB bus and comparing the data received on the RT1050 with the data seen on the bus.

Prior Requisite Details

I fixed a bug in the USB stack that misreports the received data length. The details of that problem and solution can be found in the USB Host Audio Stream Receive Data Length Misreporting thread.

Setup Details

My RT1050 is setup as a USB Audio Host. 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.

I'm able to receive audio data from a connected Full-Speed USB microphone by repeatedly calling USB_HostAudioStreamRecv.

Test Setup and Results

I have results from two different ways of using the USBHostAudioStreamRecv function that both result in receiving unexpected audio data. In these tests, I'm speaking into the microphone and collecting three seconds of audio data into a RAM buffer on the RT1050. At the same time, I'm collecting a trace of the USB communication using a Teledyne Advisor T3 USB Analyzer.

/* USB Audio Buffer */

USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t _AudioBuffer[AUDIO_BUFFER_SIZE];

/* audioInstance->audioBuffer points to _AudioBuffer */

status = USB_HostAudioStreamRecv(audioInstance->classHandle,
                  audioInstance->audioBuffer,
            AUDIO_BUFFER_SIZE,
            _HostAudioInCallback,
            audioInstance);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here are descriptions of the two modes of operation. The audio bin files are 16-bit, 16kHz PCM audio, which can be played using Audacity.

Mode 1: More than one packet (greater than 34 bytes) is requested for transfer at a time

USB Trace of Audio: microphone_4k_read_usb_trace.bin.zip

Received data on RT1050 read from RAM buffer: microphone_4k_read_ram_buffer.bin.zip

a) AUDIO_BUFFER_SIZE = 34
b) The received audio’s speech is audible, but there is significant noise
c) In this mode, the audio data on the bus is equivalent to the audio data of the source (microphone)
d) Comparing the received data to the source data, bytes are rearranged and values are different

Mode 2: Exactly one packet (34 bytes) is requested for transfer at a time

USB Trace of Audio: microphone_34_read_usb_trace.bin.zip

Received data on RT1050 read from RAM buffer: microphone_34_read_ram_buffer.bin.zip

a) AUDIO_BUFFER_SIZE = 4096

b) The received audio does not resemble speech
c) The audio data recorded on the bus does not match the audio data of the source (microphone)!
d) One isochronous transaction occurs every 3ms, instead of the expected 1ms (Full Speed)
e) It seems there’s a delay in the stack that is preventing the reads from happening fast enough

Code and Operation Description

Below are snippets of my software that implement the USB Audio Host, which I based off of the USB HID mouse example.

There are two tasks: one that calls the USB_HostEhciTaskFunction, and another that manages the USB application state. The application state task (_MicrophoneApplicationTask) blocks on a FreeRTOS Event Group bit, which is set in _HostAudioControlCallback and _HostAudioInCallback. This allows the _MicrophoneApplicationTask to immediately react to events and handle any state changes.

/*! @brief USB host audio instance structure */
typedef struct USBHostAudioInstance
{
    usb_host_configuration_handle configHandle; /*!< the audio configuration handle */
    usb_device_handle deviceHandle;             /*!< the audio device handle */
    usb_host_class_handle classHandle;          /*!< the audio class handle */
    usb_host_interface_handle streamingInterfaceHandle;  /*!< the audio streaming interface handle */
    usb_host_interface_handle controlInterfaceHandle;    /*!< the audio control interface handle */
    uint8_t deviceState;                        /*!< device attach/detach status */
    uint8_t prevState;                          /*!< device attach/detach previous status */
    uint8_t runState;                           /*!< audio application run status */
    uint8_t runWaitState;   /*!< audio application wait status, go to next run status when the wait status success */
    uint16_t maxPacketSize; /*!< Interrupt in max packet size */
    uint8_t *audioBuffer;   /*!< use to receive data */
} USBHostAudioInstance_t;


/*! @brief host app run status */
typedef enum USBHostAudioRunState
{
    USBHostAudioRunState_Idle = 0,                      /*!< idle */
    USBHostAudioRunState_SetControlInterface,           /*!< execute set interface code */
    USBHostAudioRunState_WaitSetControlInterface,       /*!< wait set interface done */
    USBHostAudioRunState_SetStreamingInterface,         /*!< execute set interface code */
    USBHostAudioRunState_WaitSetStreamingInterface,     /*!< wait set interface done */
    USBHostAudioRunState_ReceiveStream,                 /*!< set interface is done, start streaming */
    USBHostAudioRunState_WaitReceiveStream              /*!< wait for streaming callback */
} USBHostAudioRunState_t;


static void _HostAudioControlCallback(
 void *param,
 uint8_t *data,
 uint32_t dataLength,
 usb_status_t status)
{
    UNUSED_PARAMETER(data);
    UNUSED_PARAMETER(dataLength);
    UNUSED_PARAMETER(status);

    USBHostAudioInstance_t *audioInstance = (USBHostAudioInstance_t *)param;

    if (audioInstance->runWaitState == USBHostAudioRunState_WaitSetControlInterface)
    {
        audioInstance->runState = USBHostAudioRunState_SetStreamingInterface;
    }
    else if (audioInstance->runWaitState == USBHostAudioRunState_WaitSetStreamingInterface)
    {
        audioInstance->runState = USBHostAudioRunState_GetSamplingFrequency;
    }
    else if (audioInstance->runWaitState == USBHostAudioRunState_WaitGetSamplingFrequency)
    {
        audioInstance->runState = USBHostAudioRunState_ReceiveStream;
    }
    else
    {
     DEBUG_USB("%s: Unhandled runWaitState\r\n", __func__);
    }

     xEventGroupSetBits(_USBEventGroup,    /* The event group being updated. */
                        BIT_0);            /* The bits being set. */
}

static void _HostAudioInCallback(
 void *param,
 uint8_t *data,
 uint32_t dataLength,
 usb_status_t status)
{
    USBHostAudioInstance_t *audioInstance = (USBHostAudioInstance_t *)param;

 if (audioInstance->deviceState == kStatus_DEV_Attached)
 {
  if (status == kStatus_USB_Success)
  {
   //DEBUG_USB("%s: Successfully received %u bytes\r\n", __func__, dataLength);

   VoiceProcessor_ReceivedDataCallback(data, dataLength);

   if (audioInstance->runWaitState == USBHostAudioRunState_WaitReceiveStream)
   {
       audioInstance->runState = USBHostAudioRunState_ReceiveStream;
   }
   else
   {
       /* unhandled condition */
       ASSERT_FAILURE();
   }
  }
  else
  {
      ASSERT_FAILURE();
   DEBUG_USB("%s: Receive unsuccessful\r\n", __func__);
  }
 }
 else
 {
     ASSERT_FAILURE();
  DEBUG_USB("%s: Device not attached\r\n", __func__);
 }

    xEventGroupSetBits(_USBEventGroup,    /* The event group being updated. */
                       BIT_0);            /* The bits being set. */
}


/***************************************************************************//**
    USB Host Task

    \param[in] param - Task input parameter
*//****************************************************************************/
static void _USBHostTask(void *param)
{
    while (1)
    {
        USB_HostEhciTaskFunction(param);
    }
}

/***************************************************************************//**
    USB Host Application Task

    \param[in] param - Task input parameter
*//****************************************************************************/
static void _MicrophoneApplicationTask(void *param)
{
    EventBits_t uxBits;

    while (1)
    {
        uxBits = xEventGroupWaitBits(_USBEventGroup,   /* The event group being tested. */
                                     BIT_USBEvent, /* The bits within the event group to wait for. */
                                     pdTRUE,        /* Cleared bits before returning. */
                                     pdFALSE,       /* Don't wait for both bits, either bit will do. */
                                     portMAX_DELAY);/* Wait forever. */

        _HostAudioStateManager(param);
    }
}

/***************************************************************************//**
    Task to handle the current device state

 \param[in] param - the device instance

*//****************************************************************************/
static void _HostAudioStateManager(void *param)
{
 usb_status_t status;
    USBHostAudioInstance_t *audioInstance = (USBHostAudioInstance_t *)param;

    /* Process device state changes (process once for each state) */

    if (audioInstance->deviceState != audioInstance->prevState)
    {
        audioInstance->prevState = audioInstance->deviceState;
        switch (audioInstance->deviceState)
        {
            case kStatus_DEV_Idle:
                break;

            /* Device is attached and enumeration is done */
            case kStatus_DEV_Attached:
             DEBUG_USB("Mic device attached\r\n");

                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;

            /* Device is detached */
            case kStatus_DEV_Detached:
                audioInstance->deviceState = kStatus_DEV_Idle;
                audioInstance->runState = USBHostAudioRunState_Idle;

                /* Audio class de-initialization */
                USB_HostAudioDeinit(audioInstance->deviceHandle,
                                  audioInstance->classHandle);

                audioInstance->classHandle = NULL;
                DEBUG_USB("USB Audio device detached\r\n");
                break;

            default:
                break;
        }
    }

    /* Process the run state */

    switch (audioInstance->runState)
    {
        case USBHostAudioRunState_Idle:
            break;

        /* Set the audio control interface */
        case USBHostAudioRunState_SetControlInterface:
            audioInstance->runWaitState = USBHostAudioRunState_WaitSetControlInterface;
            audioInstance->runState = USBHostAudioRunState_Idle;

   status = USB_HostAudioControlSetInterface(audioInstance->classHandle,
               audioInstance->controlInterfaceHandle,
               DEVICE_CONTROL_ALTERNATE_SETTING,
               _HostAudioControlCallback,
               audioInstance);
   ASSERT(status == kStatus_USB_Success);

   DEBUG_USB("Set Control Interface Complete\r\n");
            break;

        /* Set the audio streaming interface */
        case USBHostAudioRunState_SetStreamingInterface:
   audioInstance->runWaitState = USBHostAudioRunState_WaitSetStreamingInterface;
   audioInstance->runState = USBHostAudioRunState_Idle;

   status = USB_HostAudioStreamSetInterface(audioInstance->classHandle,
              audioInstance->streamingInterfaceHandle,
              DEVICE_MIC_ALTERNATE_SETTING,
              _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;

            uint32_t maxPacketSize = USB_HostAudioPacketSize(audioInstance->classHandle,
                                                             USB_ENDPOINT_ISOCHRONOUS,
                                                             USB_IN);

            ASSERT(AUDIO_BUFFER_SIZE >= maxPacketSize);

            status = USB_HostAudioStreamRecv(audioInstance->classHandle,
                  audioInstance->audioBuffer,
            AUDIO_BUFFER_SIZE,
            _HostAudioInCallback,
            audioInstance);

         ASSERT(status == kStatus_USB_Success);
            break;
        default:
            break;
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

fangfang

Labels (1)
35 Replies

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hi Austin,

I get the feedback as the below:

"we are trying to reproduce this issue by a USB MIC+SPERKER DEVICE, default code can't reproduce the issue. Would you please the  HOST AUDIO MIC code for your demo?"

Best regards

0 Kudos
Reply

33,216 Views
amwilhite
Contributor III

I have attached the USB Host Audio project that can be used to reproduce the issue on the NXP IMXRT1050 EVK-B evaluation board. The project is setup to use the default evaluation board Hyperflash configuration. Connector J9 is the USB Host port.

Note that this application is setup to recognize the ReSpeaker v2 Mic Array by default, but parameters for a different USB device such as VID, PID, and interface numbers can be set using defines such as DEVICE_VENDOR_ID, DEVICE_PRODUCT_ID, etc. found in host_audio.c.

0 Kudos
Reply

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

 Got. I will provide the process for it.

0 Kudos
Reply

33,216 Views
amwilhite
Contributor III

Hi fangfang,

Are any updates available for this?

Thanks

0 Kudos
Reply

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

 Unfortunately, I can't get the feedback now. Sorry for the inconvenience may cause.

0 Kudos
Reply

33,216 Views
amwilhite
Contributor III

Hi fangfang‌,

Do you know when a progress update may be available?

Thanks

0 Kudos
Reply

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

 I get the update information today as the below: 


  • In fact, I failed to reproduce this issue on my side so far.

    As we have a demo: usb_device_composite_hid_audio_unified, in which there is a MIC.

    If customer can reproduce this issue based on this demo, then share the code to us, that would be much useful in this case.

    Best Regards

0 Kudos
Reply

33,216 Views
amwilhite
Contributor III

Hi fangfang‌,

I've attached an updated version of the USB Host Audio project that can be used to reproduce the issue on an evaluation board.

 

The update includes a large buffer (_audioPlaybackBuffer in host_audio.c) for collecting received audio data. Once the buffer is full, all of the audio data that has been received by the USB Audio Host can be viewed or exported to a binary file.

The audio software Audacity can be used to play the binary file as audio (File -> Import -> Raw Data...).

Thank you

0 Kudos
Reply

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

 Thanks. Got it.

0 Kudos
Reply

33,216 Views
amwilhite
Contributor III

Hi fangfang

 

Great. Do you know when a progress update may be available?

 

Thanks

0 Kudos
Reply

33,216 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

In order to reproduce the issue ,would you please provide  how to test the USB device?

Have a nice day.

Best regards

0 Kudos
Reply

33,211 Views
amwilhite
Contributor III

NXP RT1050 USB Audio Host System.png

binary-file-audio-format.PNG

0 Kudos
Reply

33,211 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

Thanks for your information and I will forward to it. I get the feedback as the below:

Now I can run the customer code, but no proper device to make the test.

What I can think of is to use our usb_device_audio_generator demo as a MIC.

But customer code does not work in this case.

 

Is it possible to ask customer to test usb_device_audio_generator demo ?

If this issue can be seen on usb_device_audio_generator demo, we can analysis.

Please let me know if have the issue for the usb_device_audio_generator demo. Thanks.

Best Regards

0 Kudos
Reply

33,211 Views
amwilhite
Contributor III

Hi fangfang‌,

The USB microphone devices we have connected to the USB Audio Host have been operating as USB Full Speed devices. However, the usb_device_audio_generator demo application operates as a USB High Speed device. I have tried to configure the  usb_device_audio_generator demo application to operate as a USB Full Speed device, but I have not had success in changing it from High Speed to Full Speed.

Rather than using the usb_device_audio_generator demo as a USB microphone device, can I instead send you a USB microphone device that you can use to reproduce the USB Audio Host problem?

Thank you

0 Kudos
Reply

33,211 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

Thanks for your information. When you use "the usb_device_audio_generator demo application operates as a USB High Speed device for the other USB device " there is any an issue?

0 Kudos
Reply

33,211 Views
amwilhite
Contributor III

Hi fangfang‌,

I was able to reproduce the USB Audio Host problem when using the usb_device_audio_generator demo as the USB device that is connected to the host.

Please find the attached projects for the USB Audio Host and USB Audio Device that can be used to observe the issue that is present in the USB Audio Host. The data received by the USB Host does not match the data that is supplied by the USB device.

Description of Attachments

evkbimxrt1050_dev_audio_generator_freertos_mic_full_speed.zip

I have modified the usb_device_audio_generator so that it runs as a full-speed device rather than the default high-speed. This application is attached.

evk-usb-audio-host-audio-generator-params.zip

I have updated the evk-usb-audio-host project I provided previously so that it recognizes the usb_device_audio_generator device. This application is attached.

3ms_between_packets.png

A segment of a USB Bus trace that shows the 3ms time between consecutive isochronous transfers. This is a problem.

audio_generator_supplied_data.bin

The audio data array that is embedded in the code of the usb_device_audio_generator demo. This file is useful for performing binary comparisons.

audio_gen_8_read_bus.bin

The audio data observed on the USB Bus as it is transferred from the USB device to the USB Host. Note that this data is NOT equivalent to the data supplied by the USB device. This is a problem.

audio_gen_8_read_raw_buffer.bin

The audio data received on the USB Host. Note that this data is NOT equivalent to the data supplied by the USB device. This is a problem.

0 Kudos
Reply

33,211 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello,

I will forward it . Have a nice day.

0 Kudos
Reply

33,211 Views
amwilhite
Contributor III

Hi fangfang

Great! Are any updates available for this?

Thank you

0 Kudos
Reply

33,211 Views
fangfang
NXP TechSupport
NXP TechSupport

Hello

Updated information:

Please check the second parameter of _ReceivedDataCallback, this parameter should be set as AUDIO_BUFFER_SIZE, and in your code this parameter's value is transferSofar.

0 Kudos
Reply

33,211 Views
amwilhite
Contributor III

Hi fangfang‌,

I assume you were able to reproduce the issue with the provided applications for the USB Host and the USB Device and observe the fact that the audio received by the USB Host does not match the audio present on the USB Device.

Regarding the suspicion of the timing of the USB_HostAudioStreamRecv calls, note that I reported in my very first reply to the original post that there is no significant delay between _HostAudioCallbackIn being called and the subsequent calling of USB_HostAudioStreamRecv. To prove this, I had instrumented the code with GPIO output toggling between those two time points. I have attached an image that illustrates those results. How did you come up with the _HostAudioInCallback taking more than 1ms to complete?

The waveforms correspond to the following:

Yellow:

GPIO_PinWrite(GPIO1, 26, 1);
_ReceivedDataCallback(data, dataLength);
GPIO_PinWrite(GPIO1, 26, 0);

The _ReceivedDataCallback executes in 1us or less (see the yellow spike just left of the blue transition from low to high).

Blue:

GPIO_PinWrite(GPIO1, 27, 1);
status = USB_HostAudioStreamRecv(audioInstance->classHandle,
                                 audioInstance->audioBuffer,
                                 AUDIO_BUFFER_SIZE,
                                 _HostAudioInCallback,
                                 audioInstance);
GPIO_PinWrite(GPIO1, 27, 0);‍‍‍‍‍‍‍

The delay between _HostAudioInCallback (just before _ReceivedDataCallback is called) and the beginning of USB_HostAudioStreamRecv is less than 5us.

The USB_HostAudioStreamRecv function call executes in less than 55us.

pastedImage_5.png

I am also not following your second suggestion regarding checking the second parameter of _ReceivedDataCallback. The problem I am reporting is not related to the reported length of the data that is received. Please see the thread USB Host Audio Stream Receive Data Length Misreporting where I have illustrated the solution to that separate problem.

_ReceivedDataCallback is called with the parameters data and dataLength by the _HostAudioInCallback function.

_HostAudioInCallback is called by the unmodified NXP driver function _USB_HostAudioStreamIsoInPipeCallback with the parameters transfer->transferBuffer and transfer->transferSofar in the data and dataLength positions, respectively.

 

With the example applications I have provided to you, please prove that your suggestions solve the problem and provide the modified USB Audio Host example that operates correctly.

0 Kudos
Reply