usb asynchronous

usb asynchronous transfers,

- Asynchronous: the sampling clock is generated on the device side.

For Asynchronous Sink (output) device, like a speaker, the device has to notify to host on its sampling clock, to synchronize the host. For this purpose, a feedback endpoint (isoc IN) is associated to the isoc OUT endpoint of the audio stream

Here is an outline of the feedback endpoint of Async Sink.

/media/uploads/mbed2f/feedback.jpg

/* Endpoint - Standard Descriptor */
  AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
  USB_ENDPOINT_OUT(3),                  /* bEndpointAddress */
  //USB_ENDPOINT_TYPE_ISOCHRONOUS,        /* bmAttributes */
  0x05,                    // <----- USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS
  WBVAL(64),                            /* wMaxPacketSize */ // <----- WBVAL(66)
  0x04,                                 /* bInterval */      // <----- 0x01 (every 1ms)
  0x00,                                 /* bRefresh */
  0x00,                                 /* bSynchAddress */  // <----- 0x83 (IN 3)

/* Endpoint - Audio Streaming */
  AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
  AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
  AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
  0x00,                                 /* bmAttributes */
  0x00,                                 /* bLockDelayUnits */ // <----- 0x02 (Decoded PCM samples)
  WBVAL(0x0000),                        /* wLockDelay */

/* Endpoint - Standard Descriptor */                       // <-------- additional feedback EP
  AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
  USB_ENDPOINT_IN(3),                   /* bEndpointAddress */
  USB_ENDPOINT_TYPE_ISOCHRONOUS,        /* bmAttributes */
  WBVAL(3),                             /* wMaxPacketSize */
  0x01,                                 /* bInterval */
  0x01,                                 /* bRefresh, every 2ms */
  0x00,                                 /* bSynchAddress */

/* Terminator */
  0                                     /* bLength */
};

/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,          /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE,    /* bDescriptorType */
  WBVAL(                                /* wTotalLength */
    USB_CONFIGUARTION_DESC_SIZE         +
    USB_INTERFACE_DESC_SIZE             +
    AUDIO_CONTROL_INTERFACE_DESC_SZ(1)  +
    AUDIO_INPUT_TERMINAL_DESC_SIZE      +
    AUDIO_FEATURE_UNIT_DESC_SZ(1,1)     +
    AUDIO_OUTPUT_TERMINAL_DESC_SIZE     +
    USB_INTERFACE_DESC_SIZE             +
    USB_INTERFACE_DESC_SIZE             +
    AUDIO_STREAMING_INTERFACE_DESC_SIZE +
    AUDIO_FORMAT_TYPE_I_DESC_SZ(1)      +
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE   +
    AUDIO_STREAMING_ENDPOINT_DESC_SIZE  +              // <----------
    AUDIO_STANDARD_ENDPOINT_DESC_SIZE                  // <----------
  ),

The feedback endpoint is supplied with the frequency ratio (master sampling / SOF frequency) in 10.10 fixed-point format on 3 bytes (left-justified, ie. 10.14 format).

- At USB_SOF_Event() (usbuser.c), - - read this timer count. - - Calculate this value

#include "LPC17xx.h" //for LPC_TIM1->TCR;

uint32_t last_timer_count;

#if USB_SOF_EVENT
void USB_SOF_Event (void) {
uint32_t current_timer_count;
  uint32_t feedback_value;
  uint32_t pclk;
                                                // feedback
  current_timer_count = LPC_TIM1->TCR;                   // capture current SOF timing on the Timer1
  if ( USB_AltSetting[1] == 1 ) {               // When interface 1 / alt 1 is enabled,
                                                // calculate master/SOF frequency ratio in 10.10 (10.14) format
    feedback_value = ((current_timer_count - last_timer_count) << 14) / (pclk/DATA_FREQ);
                                                // and send it to the feedback IN EP
    USB_WriteEP( 0x83, (uint8_t *)&feedback_value, 3 );
  }
  last_timer_count = current_timer_count;       // update the last SOF timing
#if USB_DMA == 0


/* Setup Timer1 for rate feedback */
  
  LPC_SC->PCONP |= 1 << 2;     // Power on Timer'
  LPC_TIM1->TCR = 1;

/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
  USB_INTERFACE_DESC_SIZE,              /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
  0x01,                                 /* bInterfaceNumber */
  0x01,                                 /* bAlternateSetting */
  0x01,                                 /* bNumEndpoints */    <----- 0x02 (plus one, for the feedback EP)
  USB_DEVICE_CLASS_AUDIO,               /* bInterfaceClass */
  AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
  AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
  0x00,                                 /* iInterface */

Use USB Protocol Analyzer and USB Traffic Sniffer http://www.usblyzer.com/ to confirm.

  URB Isoch Transfer succeeded
Device Object	USBPDO-5
Driver Object	usbhub

URB Function	URB_FUNCTION_ISOCH_TRANSFER
URB Status	USBD_STATUS_SUCCESS

Endpoint 83h	3 In, Isochronous

Bytes Received	3

Start Frame	19095940
Number of Packets	1

  URB Isoch Transfer issued
Device Object	000000da
Driver Object	usbccgp

URB Function	URB_FUNCTION_ISOCH_TRANSFER

Endpoint 03h	3 Out, Isochronous

Bytes to Transfer	280h (640)

Start Frame	19095958
Number of Packets	10

Normal speaker bin file /media/uploads/mbed2f/usbaudioasynchronous.bin


Please log in to post comments.