文章目录
- 一、USB Audio的配置描述符
- 二、描述符的结构
- 三、关于反馈端点的几个说明
- 1.计算10.14格式采样率代码(audio 1.0)
- 2.计算16.16格式采样率代码(audio 2.0)
- 3.其它相关说明
- 四、关于STM32实现USB Audio的相关说明
- 1. 一些重要的函数,经常要修改的。
- 2.最好不使用USBD_malloc分配数据,有可能失败。
- 3.新增端点时的操作
- 五、资料下载与技术讨论
本使使用的是stm32F105开发,带USB OTG FS接口
一、USB Audio的配置描述符
__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration 1 */
0x09, /* bLength */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */
LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength 109 bytes*/
HIBYTE(USB_AUDIO_CONFIG_DESC_SIZ),
0x03, //NumInterfaces:3
0x01, //ConfigurationValue
0x00, //Configuration String
0x80, //Attributes:Bus Power
0xfa, //MaxPower = 0xfa*2ma
/**********************Audio Interface Descriptor(No.0):0x04**********************/
//第一个接口,控制接口
0x09, //Length
0x04, //DescriptorType:Inerface
0x00, //InterfaceNum:0
0x00, //AlternateSetting:0
0x00, //NumEndpoint:0
0x01, //InterfaceClass:audio
0x01, //InterfaceSubClass:audio ctl
0x00, //InterfaceProtocol
0x00, //Interface String
/*******************AC Header of Interface Descriptor:0x24 0x01*************************/
0x0a, //Length
0x24, //DescriptorType:audio interface descriptor
0x01, //DescriptorSubType:audio control header
0x00,
0x01, //bcdADC:audio Device Class v1.00
0x48,
0x00, //TotalLength:0x0048 (这个长度应该是特性单元跟Terminal描述符的总长度,包括自己 Total size of class specific descriptors.)
0x02, //InCollection:2 AudioStreaming interface
0x01, //InterfaceNr(2) - AS #1 id AudioStreaming interface 2 belongs to this AudioControl interface
0x02, //InterfaceNr(1) - AS #2 id AudioStreaming interface 1 belongs to this AudioControl interface
/******************* AC Specific type of Input Terminal:0x24 0x02*************************/
//ID1
0x0c, //Length
0x24, //DescriptorType:audio interface descriptor
0x02, //DescriptorSubType:Input Terminal
0x01, //TerminalID:0x01
0x01,
0x02, //TerminalType:USB Microphone
0x00, //AssocTerminal
0x02, //NrChannels:2 channel
0x03,
0x00, //ChannelConfig:Left Front,Right Front,
0x00, //ChannelName String
0x00, //Terminal String
/*******************Audio Class Specific type of Feature Unit:0x24 0x06*************************/
//ID2
0x0a, //Length
0x24, //DescriptorType:audio interface descriptor
0x06, //DescriptorSubType:Audio Feature Unit
0x02, //UnitID:0x02
0x01, //SourceID:1 #Microphone IT
0x01, //ControlSize:1 byte
0x01, //Controls:Mute
0x02, //Controls(0):Volume
0x02, //Controls(1):Volume
0x00, //Feature String
/*******************Audio Class Specific type of Output Terminal:0x24 0x03*************************/
//ID3
0x09, //Length
0x24, //DescriptorType:audio interface descriptor
0x03, //DescriptorSubTYpe:Output Terminal
0x03, //TerminalID:0x03
0x01,
0x01, //TerminalType:USB Streaming
0x00, //AssocTerminal:ID 0
0x02, //SourceID:2 #Feature UNIT (ID 2作为控制microphone音量 - by ywj)
0x00, //Terminal String
/******************* Audio Class Specific type of Input Terminal:0x24 0x02*************************/
//ID4
0x0c, //Length
0x24, //DescriptorType:audio interface descriptor
0x02, //DescriptorSubType:Input Terminal
0x04, //TerminalID:0x04
0x01,
0x01, //TerminalType:USB Streaming
0x00, //AssocTerminal
0x02, //NrChannels:2 channel
0x03,
0x00, //ChannelConfig:Left Front,Right Front,
0x00, //ChannelName String
0x00, //Terminal String
/*******************Audio Class Specific type of Feature Unit:0x24 0x06*************************/
//ID5
0x0a, //Length
0x24, //DescriptorType:audio interface descriptor
0x06, //DescriptorSubType:Audio Feature Unit
0x05, //UnitID:0x05
0x04, //SourceID:4 #USB Streaming IT
0x01, //ControlSize:1 byte
0x01, //Controls:Mute,
0x02, //Controls(0):Volume
0x02, //Controls(1):Volume
0x00, //Feature String
/*******************Audio Class Specific type of Output Terminal:0x24 0x03*************************/
//ID6
0x09, //Length
0x24, //DescriptorType:audio interface descriptor
0x03, //DescriptorSubTYpe:Output Terminal
0x06, //TerminalID:0x06
0x01,
0x03, //TerminalType:Speaker
0x00, //AssocTerminal:
0x05, //SourceID:5 #Feature UNIT (ID 5作为控制speak音量 - by ywj)
0x00, //Terminal String
/*****************Audio Recorder Interface descriptor(No.1):0x04***********************/
//录音部分 - audioStreaming interface 1
//Operational Alternate Setting 0
0x09, //Length
0x04, //DescriptorType:Interface
0x01, //InterfaceNum:1
0x00, //AlternateSetting:0
0x00, //NumEndpoint:0
0x01, //InterfaceClass:audio
0x02, //InterfaceSubClass:audio streaming
0x00, //InterfaceProtocol
0x00, //Interface String
/*****************Audio Recorder Interface descriptor(No.1):0x04***********************/
//Operational Alternate Setting 1
0x09, //Length
0x04, //DescriptorType:Interface
0x01, //InterfaceNum:1
0x01, //AlternateSetting:1
0x01, //NumEndpoint:1
0x01, //InterfaceClass:audio
0x02, //InterfaceSubClass:audio streaming
0x00, //InterfaceProtocol
0x00, //Interface String
/*******************AS descriptor subtype Descriptor:0x24 0x01*************************/
0x07, //Length
0x24, //DescriptorType:audio interface descriptor
0x01, //DescriptorSubType:AS_GENERAL
0x03, //TerminalLink:#3USB USB Streaming OT //Linked to USB Streaming In Terminal
0x00, //Delay:0 接口延时
0x01,
0x00, //FormatTag:PCM
/****************** Audio Class Specific type I format INTERFACE Descriptor: 0x24 0X02 ***********/
//设置音频流的格式
0x0b, //Length
0x24, //DescriptorType:audio interface descriptor
0x02, //DescriptorSubType:Format_type
0x01, //FormatType:Format type 1
0x02, //NumberOfChanne:2
0x03, //SubframeSize:2byte
24, //BitsResolution:16bit
0x01, //SampleFreqType:One sampling frequency.
AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), //采样率两个字节
/******************************* Audio Recorder IN ENDPOINT descriptor: 0x05 *******************************/
0x09, //Length
0x05, //DescriptorType:endpoint descriptor
0x82, //EndpointAddress:Input endpoint 2
0x01 | 0x04 | (0x2 << 4U),
AUDIO_PACKET_SZE(AUDIO_OUT_PACKET),
0x01, //Interval
0x00,
0x00,
/******************************* Audio Class Specific ENDPOINT Descriptor: 0x25 0x01*******************************/
0x07, //Length
0x25, //DescriptorType:audio endpoint descriptor
0x01, //DescriptorSubType:audio endpiont general
0x00, //Attributes:0x00........
0x00, //LockDelayUnits
0x00,
0x00, //LockDelay
/***********************Audio Speaker Interface descriptor(No.2):0x04*****************************/
//播放部分开始
0x09, //Length
0x04, //DescriptorType:Interface
0x02, //InterfaceNum:2
0x00, //AlternateSetting:0
0x00, //NumEndpoint:0
0x01, //InterfaceClass:audio
0x02, //InterfaceSubClass:audio streaming
0x00, //InterfaceProtocol
0x00, //Interface String
/***********************Audio Speaker Interface descriptor(No.2):0x04*****************************/
0x09, //Length
0x04, //DescriptorType:Interface
0x02, //InterfaceNum:2
0x01, //AlternateSetting:1
0x02, //NumEndpoint:2 //这里包括一个反馈端点
0x01, //InterfaceClass:audio
0x02, //InterfaceSubClass:audio streaming
0x00, //InterfaceProtocol
0x00, //Interface String
/*******************AS_GENERAL descriptor subtype Descriptor:0x24 0x01*************************/
0x07, //Length
0x24, //DescriptorType:audio interface descriptor
0x01, //DescriptorSubType:AS_GENERAL
0x04, //TerminalLink:#4 USB Streaming IT
0x01, //Delay:1
0x01,
0x00, //FormatTag:PCM
/****************** Audio Class Specific type I format INTERFACE Descriptor: 0x24 0X02 ***********/
0x0b, //Length
0x24, //DescriptorType:audio interface descriptor
0x02, //DescriptorSubType:Format_type
0x01, //FormatType:Format type 1
0x02, //NumberOfChanne:1
0x03, //SubframeSize:3byte
24, //BitsResolution:24bit
0x01, //SampleFreqType:One sampling frequency.
AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ),
/******************************* Audio Speaker OUT ENDPOINT descriptor: 0x05 *******************************/
//播放端点描述符
0x09, //Length
0x05, //DescriptorType:endpoint descriptor
0x01, //EndpointAddress:Output endpoint 01
0x01 | 0x04, //Attributes:0x05,Isochronous,Synchronization Type(Asynchronous).........
AUDIO_PACKET_SZE(AUDIO_OUT_PACKET),
0x01, //Interval AUDIO_OUT_PACKET
0x00, //没有使用
0x81, //这个值是反馈端点的端点号 bSynchAddress:同步端点的地址
/******************************* Audio Class Specific ENDPOINT Descriptor: 0x25 0x01*******************************/
0x07, //Length
0x25, //DescriptorType:audio endpoint descriptor
0x01, //DescriptorSubType:audio endpiont general
0x00, //Attributes:0x00.............
0x00, //LockDelayUnits
0x00,
0x00, //LockDelay
//反馈端点描述符
/******************************* Audio feedback IN ENDPOINT descriptor: 0x05 *******************************/
0x09, /* bLength */
0x05, /* bDescriptorType */
AUDIO_FEEDBACK_EP,
0x01 | 0x04 | 0x10, /* Types -
Transfer: ISOCHRONOUS
Sync: Async
Usage: Feedback EP */
0x04, /* wMaxPacketSize */
0x00, /* wMaxPacketSize */
0x03, /* interval polling(2^x ms) */
0x05, //这个字节也是有用的,好像是控制时间的。
0x00,
} ;
二、描述符的结构
下图从usb audio 1.0的规范里截取.规范的最后面有相关的描述符例程.
三、关于反馈端点的几个说明
1.计算10.14格式采样率代码(audio 1.0)
这里反馈端点反馈的数据是3个字节的。
/*该设备为:44.1K采样率,10.14格式*/
uint8_t audioFeedBackBuffer[4] = {0x40,0x06,0x0b};
void SetFeedBackSampleRate(uint32_t Rata)
{
Rata = ((Rata / 1000) << 14) | ((Rata % 1000) << 4);
audioFeedBackBuffer[0] = Rata;
audioFeedBackBuffer[1] = Rata>>8;
audioFeedBackBuffer[2] = Rata>>16;
}
2.计算16.16格式采样率代码(audio 2.0)
这部分代码是 通过USB声卡反推出来的,实测可以用。感觉跟USB2.0规范描述不一样。
这里反馈端点反馈的数据是4个字节的。
uint8_t audioFeedBackBuffer[4];
void SetFeedBackSampleRate(uint32_t Rata)
{
Rata = ((Rata / 1000) << 13) | ((Rata % 1000) << 3);
audioFeedBackBuffer[0] = Rata;
audioFeedBackBuffer[1] = Rata>>8;
audioFeedBackBuffer[2] = Rata>>16;
audioFeedBackBuffer[4] = Rata>>24;
}
3.其它相关说明
- 反馈端点描述符增加时,不要忘记在接口描述符中修改接口所使用的端点数量。要增加一个。
- 反馈端点没有数据发送完成中断(至少stm32跟RT1052是这样子的),也就是说主动反馈,不会收到发送完成中断。
- 使用反馈端点时,端点描述符要0x09字节的长度,最后一个字节也要改成反馈端点的地址。
- 反馈端点描述符好像是倒数第二字节用于计算主机访问时间的。
四、关于STM32实现USB Audio的相关说明
1. 一些重要的函数,经常要修改的。
USBD_AUDIO_Init,
USBD_AUDIO_DeInit,
USBD_AUDIO_Setup,
USBD_AUDIO_EP0_TxReady,
USBD_AUDIO_EP0_RxReady,
USBD_AUDIO_DataIn,
USBD_AUDIO_DataOut,
USBD_AUDIO_SOF,
USBD_AUDIO_IsoINIncomplete,
USBD_AUDIO_IsoOutIncomplete,
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetDeviceQualifierDesc,
2.最好不使用USBD_malloc分配数据,有可能失败。
pdev->pClassData = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef));
3.新增端点时的操作
- 1、USBD_AUDIO_Init 函数中打开端点 USBD_LL_OpenEP();
- 2、USBD_AUDIO_DeInit函数中关闭端点 USBD_LL_CloseEP();
- 3 、USBD_LL_Init 配置端点的缓冲区。HAL_PCDEx_SetTxFiFo、HAL_PCDEx_SetRxFiFo
- 4 、关于IN端点提交数据(有时候多次提交没有发送成功,应该会占用缓冲区.需要用HAL_PCD_EP_Flush清除下)
HAL_PCD_EP_Flush(pdev->pData, AUDIO_IN_EP);
HAL_PCD_EP_Transmit(pdev->pData,AUDIO_IN_EP,(uint8_t *)&dump_buffer[0],288);