http://bluefish.blog.51cto.com/214870/1239090
先给出完整的usb描述符供参考:
const unsigned char Demo_DeviceDescriptor[] =
{
//Device:USB1.10,Vid=0x0435,Pid=0x2430,bNumConfigurations= 0x01,
0x12,//Length
0x01,//DescriptorType
0x10,
0x01,//bcdUSB
0x00,//DeviceClass
0x00,//DeviceSubClass
0x00,//DeviceProtocol
0x08,//bMaxPacketSize8
0x35,
0x04,//idVendor........
0x30,
0x24,//idProduct........
0x01,
0x00,//bcdDevice
1,//iManufacturer
2,//iProduct
3,//iSerialNumber
0x01//bNumConfigurations
};
/* USB Configuration Descriptor */
/*All Descriptors (Configuration,Interface, Endpoint, Class, Vendor */
const unsigned char Demo_ConfigDescriptor[] =
{
//Configuration:wTotalLength =0x00be,NumInterfaces = 0x03,
0x09,//Length
0x02,//DescriptorType: ConfigDescriptor
0xbe,
0x00,//TotalLength:0x00be
0x03,//NumInterfaces:3
0x01,//ConfigurationValue
0x00,//ConfigurationString
0x80,//Attributes:BusPower
0xfa,//MaxPower =0xfa*2ma
//standard interface ACdescriptor(Interface 0, Alternate Setting 0):
//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x01(audio ctl),
0x09,//Length
0x04,//DescriptorType:Inerface
0x00,//InterfaceNum:0
0x00, //AlternateSetting:0
0x00,//NumEndpoint:0
0x01,//InterfaceClass:audio
0x01,//InterfaceSubClass:audioctl
0x00,//InterfaceProtocol
0x00,//InterfaceString
//class-specific AC interfacedescriptor,audio interface(0x24),audio control header(0x01),
//Total Length 0x0048,Number ofstreaming interface 2,interfaceNr 2,1
0x0a,//Length
0x24,//DescriptorType:audiointerface descriptor
0x01,//DescriptorSubType:audiocontrol header
0x00,
0x01,//bcdADC:audio Device Class v1.00
0x48,
0x00,//TotalLength:0x0048
0x02,//InCollection:2AudioStreaming interface
0x02,//InterfaceNr(2)- AS #1 id AudioStreaming interface 2 belongs to this AudioControlinterface
0x01,//InterfaceNr(1)- AS #2 id AudioStreaming interface 1 belongs to this AudioControlinterface
//USB Microphone IT:audiointerface descriptor,audio control input terminal(0x02),terminal id 0x01,
//Microphone(0x0201),InputTerminal(0x02),2 channel:Left Front,Right Front
0x0c,//Length
0x24,//DescriptorType:audiointerface descriptor
0x02,//DescriptorSubType:InputTerminal
0x01,//TerminalID:0x01
0x01,
0x02,//TerminalType:USB Microphone
0x00,//AssocTerminal
0x02,//NrChannels:2channel
0x03,
0x00,//ChannelConfig:Left Front,Right Front,
0x00,//ChannelNameString
0x00,//TerminalString
//Audio Feature UnitDescriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x02,
//SourceId 0x01,ControlSize0x01,Mute,Volume,
0x0a,//Length
0x24,//DescriptorType:audiointerface descriptor
0x06,//DescriptorSubType:AudioFeature Unit
0x02,//UnitID:0x02
0x01,//SourceID:1#Microphone IT
0x01,//ControlSize:1byte
0x01,//Controls:Mute
0x02,//Controls(0):Volume
0x02,//Controls(1):Volume
0x00,//Feature String
//USB Streaming OT:audiointerface descriptor,audio control output terminal(0x03),terminal id 0x03,
//USB Streaming(0x0101),OutputTerminal(0x03),SourceId 0x02,
0x09,//Length
0x24,//DescriptorType:audiointerface descriptor
0x03,//DescriptorSubTYpe:OutputTerminal
0x03,//TerminalID:0x03
0x01,
0x01,//TerminalType:USB Streaming
0x00,//AssocTerminal:ID0
0x02,//SourceID:2#Feature UNIT
0x00,//TerminalString
//USB USB Streaming IT:audiointerface descriptor,audio control input terminal(0x02),terminal id 0x04,
//USB Streaming(0x0101),InputTerminal(0x02),2 channel:Left Front,Right Front
0x0c,//Length
0x24,//DescriptorType:audiointerface descriptor
0x02,//DescriptorSubType:InputTerminal
0x04,//TerminalID:0x04
0x01,
0x01,//TerminalType:USB Streaming
0x00,//AssocTerminal
0x02,//NrChannels:2channel
0x03,
0x00,//ChannelConfig:Left Front,Right Front,
0x00,//ChannelNameString
0x00,//TerminalString
//Audio Feature UnitDescriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x05,
//SourceId 0x04,ControlSize0x01,Mute,Volume,
0x0a,//Length
0x24,//DescriptorType:audiointerface descriptor
0x06,//DescriptorSubType:AudioFeature Unit
0x05,//UnitID:0x05
0x04,//SourceID:4 #USBStreaming IT
0x01,//ControlSize:1byte
0x01,//Controls:Mute,
0x02,//Controls(0):Volume
0x02,//Controls(1):Volume
0x00,//FeatureString
//USB Speaker OT:audio interfacedescriptor,audio control output terminal(0x03),terminal id 0x06,
//USB Speaker(0x0301),OutputTerminal(0x03),SourceId 0x05,
0x09,//Length
0x24,//DescriptorType:audiointerface descriptor
0x03,//DescriptorSubTYpe:OutputTerminal
0x06,//TerminalID:0x06
0x01,
0x03,//TerminalType:Speaker
0x00,//AssocTerminal:
0x05,//SourceID:5#Feature UNIT
0x00,//Terminal String
//-------------------Microphoneinterface---------------------//
//standardinterface AS descriptor(Interface 1, Alternate Setting 0):
//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audiostream),
0x09,//Length
0x04,//DescriptorType:Interface
0x01,//InterfaceNum:1
0x00,//AlternateSetting:0
0x00,//NumEndpoint:0
0x01,//InterfaceClass:audio
0x02,//InterfaceSubClass:audiostreaming
0x00,//InterfaceProtocol
0x00,//InterfaceString
//standard interface ASdescriptor(Interface 1, Alternate Setting 1):
//bNumEndpoints = 0x01,bInterFaceClass = 0x01(audio),bInterfaceSubClass= 0x02(audio stream),
0x09,//Length
0x04,//DescriptorType:Interface
0x01,//InterfaceNum:1
0x01,//AlternateSetting:1
0x01,//NumEndpoint:1
0x01,//InterfaceClass:audio
0x02,//InterfaceSubClass:audiostreaming
0x00,//InterfaceProtocol
0x00,//Interface String
//Audio Streaming InterfaceDescriptor:AS_GENERAL(0x01),
//TerminalLink 0x03,PCM(0x0001)
0x07,//Length
0x24,//DescriptorType:audiointerface descriptor
0x01,//DescriptorSubType:AS_GENERAL
0x03,//TerminalLink:#3USBUSB Streaming OT
0x01,//Delay:1
0x01,
0x00,//FormatTag:PCM
//Type 1 Format typedescriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),
//physical channels 0x02,twobyte per audio subframe(0x02),16bit,
//32K(0x007d00)
0x0b,//Length
0x24,//DescriptorType:audiointerface descriptor
0x02,//DescriptorSubType:Format_type
0x01,//FormatType:Formattype 1
0x02,//NumberOfChanne:2
0x02,//SubframeSize:2byte
0x10,//BitsResolution:16bit
0x01,//SampleFreqType:Onesampling frequency.
0x00,
0x7d,
0x00,//32K(0x007d00)
//Endpoint 1 - StandardDescriptor:Input Endpoint1
//Isochronous,SynchronizationType(Asynchronous),MaxPacketSize 0x0084,
0x07,//Length
0x05,//DescriptorType:endpointdescriptor
0x81,//EndpointAddress:Inputendpoint 1
0x05,//Attributes:0x05,Isochronous,SynchronizationType(Asynchronous).........
0x84,
0x00,//MaxPacketSize:0x0084=........
0x01,//Interval
//Endpoint - Audio StreamingDescriptor:
//Audio Endpointdescriptor,General,
0x07,//Length
0x25,//DescriptorType:audioendpoint descriptor
0x01,//DescriptorSubType:audioendpiont general
0x00,//Attributes:0x00........
0x00,//LockDelayUnits
0x00,
0x00,//LockDelay
//-------------------Speakerinterface---------------------//
//standard interfaceAS descriptor(Interface 2, Alternate Setting 0):
//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audio stream),
0x09,//Length
0x04,//DescriptorType:Interface
0x02,//InterfaceNum:2
0x00,//AlternateSetting:0
0x00,//NumEndpoint:0
0x01,//InterfaceClass:audio
0x02,//InterfaceSubClass:audiostreaming
0x00,//InterfaceProtocol
0x00,//InterfaceString
//standard interface ASdescriptor(Interface 2, Alternate Setting 1):
//bNumEndpoints =0x01,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audio stream),
0x09,//Length
0x04,//DescriptorType:Interface
0x02,//InterfaceNum:2
0x01,//AlternateSetting:1
0x01,//NumEndpoint:1
0x01,//InterfaceClass:audio
0x02,//InterfaceSubClass:audiostreaming
0x00,//InterfaceProtocol
0x00,//InterfaceString
//Audio Streaming InterfaceDescriptor:AS_GENERAL(0x01),
//TerminalLink 0x04,PCM(0x0001)
0x07,//Length
0x24,//DescriptorType:audiointerface descriptor
0x01,//DescriptorSubType:AS_GENERAL
0x04,//TerminalLink:#4USB Streaming IT
0x01,//Delay:1
0x01,
0x00,//FormatTag:PCM
//Type 1 Format typedescriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),
//physical channels 0x02,twobyte per audio subframe(0x02),16bit,
//32K(0x007d00)
0x0b,//Length
0x24,//DescriptorType:audiointerface descriptor
0x02,//DescriptorSubType:Format_type
0x01,//FormatType:Formattype 1
0x02,//NumberOfChanne:2
0x02,//SubframeSize:2byte
0x10,//BitsResolution:16bit
0x01,//SampleFreqType:Onesampling frequency.
0x00,
0x7d,
0x00,//32K(0x007d00)
//Endpoint 2 - StandardDescriptor:Output Endpoint2
//Isochronous,SynchronizationType(Asynchronous),MaxPacketSize 0x0084,
0x07,//Length
0x05,//DescriptorType:endpoint descriptor
0x02,//EndpointAddress:Outputendpoint 2
0x05,//Attributes:0x05,Isochronous,SynchronizationType(Asynchronous).........
0x84,
0x00,//MaxPacketSize:0x0084=.....
0x01,//Interval
//Endpoint - Audio StreamingDescriptor:
//Audio Endpointdescriptor,General,
0x07,//Length
0x25,//DescriptorType:audioendpoint descriptor
0x01,//DescriptorSubType:audioendpiont general
0x00,//Attributes:0x00.............
0x00,//LockDelayUnits
0x00,
0x00,//LockDelay
};
/* USB String Descriptor (optional) */
const unsigned char Demo_StringLangID[] =
{
0x04,
0x03,
0x09,
0x04
};
const unsigned char Demo_StringVendor[] =
{
0x26, //Length
0x03, //DescriptorType
'D', 0, 'e', 0, 'm', 0, 'o', 0, '-', 0, 's', 0, 'p', 0, 'e', 0,
'r', 0, 'k', 0, 'e', 0, 'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0,
'e', 0, '1', 0
};
const unsigned char Demo_StringProduct[] =
{
0x1c,//Length
0x03,//DescriptorType
'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0,
'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0, 'e', 0, '2', 0
};
const unsigned char Demo_StringSerial[] =
{
0x1c,//Length
0x03,//DescriptorType
'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0,
'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0, 'e', 0, '2', 0
};
相关说明:
这里就不针对整个描述符去作具体的分析,其实注释已经写的很详细了。这里只是对一些细节性的进行说明
1.根据USB描述符可以得到其拓扑图:
speakerphone拓扑图
2.描述符的分层组织结构
speakerphone描述符层次结构
3.设备描述符里采用的Vendor和Product ID号是随便写的一个用于测试。
4.设备描述符下包含一个配置描述符,配置描述符下包含了3组接口,IF0作为音频控制接口,IF1作为microphone接口,IF2作为speaker接口。
5.在IF0的定义中没有包含任何端点,所以与音频相关的控制信息将通过默认的控制端点0来进行信息的交付。也就是说端点0除了响应默认的控制事务(Setinterfance等等)以外还需要响应音频类相关控制事务(set cur,get max等等),音量调节就是通过控制端点0来完成的。
6.IF0中的Feature Unit定义了音量调节方式,mute和Volume,其中ID号为2的Unit控制microphone,ID 5控制speaker。具体关系常见其拓扑图。
7.IF0中两个IT(Input Terminal)定义了音频流逻辑通道数及其具体组成形式,在该示例中包含了2个逻辑通道,分别是LEFT&RIGHT,如果需要更多的通道可以通过修改相应描述符单元得到(同时注意修改相应的Streaming描述符中物理通道数,相应USB endpoint支持的包字节大小)。
8. IF1和IF2中都定义了2个setting,其中setting 0都不包含传输endpoint,setting 1都包含一个同步传输endpoint。这里要说明的是,之所以都要定义一个不含有任何传输endpoint(除了默认端点0)的setting,是由usb audio设备特性决定的,该setting不可省略,该setting用于在设备没有被使用时作为usb设备的设置。如果没有利用该usb设备进行放音和录音则主机使用的接口是IF(1,0)(接口1的设置0)和IF(2,0)(接口2的设置0),如果开始放音则使用的接口是IF(1,0)和IF(2,1),如果即用于放音又用于录音则使用IF(1,1)和IF(2,1)。这里叙述的有些累赘,其实大家可以利用USB协议相关分析软件得到其具体交互过程。
9.在IF1和IF2中定义了音频流格式为PCM格式(更多关于格式的信息参考USB audio相关文档)。支持一个采样频点:32K,如果需要更多的采样频点的支持,可以通过修改相应字段得到(注意修改相应同步端点支持的包大小)。
10.IF1(microphone)定义了endpoint 1 作为其同步传输输入端点。端点支持的最大传输字节为0x84(132byte),这里的0x44是由 32*2*2=128=0x80(采样率*通道数*每个样点的字节数)得到的(0x80byte/ms),之所以会多出4字节是因为在之前的应用中如果支持44.1K时的一个考虑,当然这里可以将其定义为0x80。
11.在IF1和IF2的AS endpoint Descriptor中的字段attributes可以用来定义是否支持采样率相关事务处理。也就是说如果在同一个IF的同一setting中支持多个采样率,那么在进行同步传输前,主机可以发起一个告知设备即将使用的采样率的事务处理,而这里的attributes用来定义设备是否支持这类事务处理。
12.支持多个采样率不仅可以通过在第9点所叙述的方式来实现(同一setting下支持多个采样率),也可以通过增加新的setting来支持(每个setting支持一个单独的采样率)。两种方式各有优缺点,第一种方式比较简洁不过需要由主机告知设备即将使用的采样率。第二种方式会较大幅度的增加整个描述符长度,但是不需要主机告知设备使用的采样率。也就是说在第一种方式下主机先告诉即将使用的接口setting,然后再发起一个采样率的SET CUR事务处理。而第二种方式只需要告诉即将使用的接口就可以了(因为一个setting只支持一个采样率,不同采样率将采用不同setting)。
13.同步问题,因为usb传输都是主机发起的,而设备只是被动的响应来进行数据传输。对于同步传输,usb在每一个 frame中启动一次同步传输,该同步传输的启动是基于主机USB主控制器所使用的时钟来进行的,而设备得到数据是依据自己的时钟源,所以这里就存在两个时钟源差异的问题。我采用的方式是利用设备响应主机的SOF中断来调整自身时钟来与主机同步。