如果需要麦克风阵列,回声消除,声源定位,波束成形,语音对话的产品请访问我好朋友的店铺。
店铺链接:首页-智能语音开发者联盟-淘宝网
大家好我是人见人爱、花见花开的大魔王。
usb协议还是很烦的,cube很大程度上减轻了工作量。但是不灵活是个大问题。
比如我要配置一个usb接口既有虚拟串口又有usb声卡又有hid控制的设备怎么办呢?
多弄几个芯片之后加个usb hub?不存在的!成年人的世界我都要~!
下面为所有项目的规划列表~~~
虚拟串口(已完成)
usb声卡(单独播放的已经完成了)。
usb的各种控制,比如静音接打电话控制音量。
多路麦克风阵列的usb设备怎么做。
打印机设备怎么搞。
hid设备怎么弄。
u盘怎么做。。。这个应该不会去写。
怎么把这些弄到一起,一根usb线一个漂漂亮亮的挂载一大串设备,cdc设备的集成到底怎么弄!
所有所有的这些,咱们慢慢来!
这次我们来一个usb的声卡的中等意思版本。本着柿子捡软的捏的原则开撸。。。
描述符看起来很乱,一眼瞎。这些以后不再是问题~~~~~~~~~~~
先把定时器还有SAI开了
因为主要是想做验证,顺便看看usb丢包和延时时间。就把SAI的输入和输出直接连起来。
懒就是懒还找了一堆这么合理的接口。。。
干活我不行,安慰起来自己那确实是一套一套的。
这样之后用pc测试的时候播放和录音就是一样的了。
usbd_desc 初始化代码、设备描述符
usbd_audio_if 音频接口
usbd_desc.c 设备描述符
usbd_conf.c 底层
先看一下设备描述符的类型
设备描述符#define USB_DESC_TYPE_DEVICE 0x01U
配置描述符#define USB_DESC_TYPE_CONFIGURATION 0x02U
字符串描述符#define USB_DESC_TYPE_STRING 0x03U
接口描述符#define USB_DESC_TYPE_INTERFACE 0x04U
端点描述符#define USB_DESC_TYPE_ENDPOINT 0x05U
设备限定描述符#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
速度配置描述符#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_IAD 0x0BU
#define USB_DESC_TYPE_BOS 0x0FU
这个描述符的难度确实不是很好搞。具体以配置描述符最难搞,看长度就能知道了。
柿子先捡软的捏!
搞一搞usb描述符其中的逻辑~~~~~~~~~
咱先弄逻辑再写代码。至少要知道自己写个什么东西,才能下得去手吧!!!
黄色背影字体的部分是cube自动生成的一个立体声播放的usb设备描述符。也就是实现了一个音频设备的上报,之后注册了一个windows、linux的声卡。
多往下翻翻就看到了黄色背影字体,绝对一眼瞎,密密麻麻的一段描述符,到底是什么意思,背后隐藏着什么逻辑。咱们慢慢研究。
接下来我们看一下这个信息是怎样让windows或者linux识别的。
先捋顺一下逻辑,所有的协议在编写的时候作者都是有自己的逻辑的。只要找到这个逻辑,咱们按照这个标准叙述逻辑去说话,这个东西也就很好解释了。
下段文字中红色背景的美商都是对应上面黄色背景中的一小端。
配置描述符说我这个描述符是一个有2个接口耗电xx mA的设备。
第一个接口中众成员对话
接口描述符说我这个是第0个接口描述符,使用端点数为0(也就是不使用),接口类型是audio控制。
AC接口描述符说我这个是音频1.00规范,有一群小兄弟(就是后面跟的一些其他描述符长度)
音频类输入终端描述符说ac接口是我大哥
特征单元描述符说ac接口是我大哥
音频类输出终端描述符说ac接口是我大哥
第二个接口中众成员对话
接口描述符交替0说我跟第一个接口有点不一样,我的接口类型是音频流。有一个端点。我跟音频控制类型还有点其他区别就是老子有交替配置。
接口描述符交替1说我就是交替配置1
Audio Streaming接口描述符说我的格式是pcm
Audio Type Format接口描述符说我是48k采样率、16位
音频标准端点描述符说我使用了1端点,最大长度是xxx
音频流端点描述符说我没啥意思,就是过来看看
从上面对话我们就可以看出,其实每个描述符都有他自己独立的想法。但是他们又分别属于各个不同的大哥。大哥靠小弟们说明事情的来龙去脉就把告诉windows和linux这个usb是什么类型的搞定了。
之后我就解释一下什么是接口什么是端点。
用通俗的话来讲呢,就好比我要开一家公司。这个公司卖usb声卡。这个声卡怎么卖呢。需要两个部门。一个部门有几个员工在淘宝当小二,另一个部门有几个人搞生产。
这个公司就是配置描述符,两个部门就是对接公司业务的接口,每个部门的员工就是接口下面做各个具体事务的人。
而端点呢?端点是这个公司的屋子。好比我一个屋子可以安排一个部门,那我这个公司现在有十个屋子是不是就可以放十个部门了?但是我现在主营业务用不了那么多屋子,怎么办。先空着呗。
万一咱哪天又想卖usb虚拟串口或者usb打印机就根据咱们的安排多安排几个部门呗。端点是由硬件决定的,每个单片机的端点数是不一样的。
既然都说道这里了,那么咱继续深入了解一下这个妹子。。。不对是这个描述符。
咱们增加一个功能,让它能放音也能录音。什么叫编程语音,就是把想做的通过语言描述出来。
那马上开始用描述符的语言描述一下这个公司怎么对话吧~~~~~
配置描述符说我这个描述符是一个有3个接口耗电xx mA的设备。因为功能多了嘛,增加一个部门不过分吧
第一个接口中众成员对话
接口描述符说我这个是第0个接口描述符,使用端点数为0(也就是不使用),接口类型是audio控制。
AC接口描述符说我这个是音频1.00规范,有一群小兄弟(就是后面跟的一些其他描述符长度)
音频类输入终端描述符说ac接口是我大哥,不过我是负责干播放端的
特征单元描述符说ac接口是我大哥,不过我是负责干播放端的
音频类输出终端描述符说ac接口是我大哥,不过我是负责干播放端的
音频类输入终端描述符说ac接口是我大哥,不过我是负责干录音端的
特征单元描述符说ac接口是我大哥,不过我是负责干录音端的
音频类输出终端描述符说ac接口是我大哥,不过我是负责干录音端的
第二个接口中众成员对话
接口描述符交替0说我跟第一个接口有点不一样,我的接口类型是音频流。有一个端点。我跟音频控制类型还有点其他区别就是老子有交替配置(因为上一端对话中是播放,所以这个还是播放)。
接口描述符交替1说我就是交替配置1
Audio Streaming接口描述符说我的格式是pcm
Audio Type Format接口描述符说我是48k采样率、16位
音频标准端点描述符说我使用了1端点,最大长度是xxx
音频流端点描述符说我没啥意思,就是过来看看
第三个接口中众成员对话
接口描述符交替0说我跟第一个接口有点不一样,我的接口类型是音频流。有一个端点。我跟音频控制类型还有点其他区别就是老子有交替配置。最重要的是老子是新部门,负责录音的。
接口描述符交替1说我就是交替配置1
Audio Streaming接口描述符说我的格式是pcm
Audio Type Format接口描述符说我是48k采样率、16位
音频标准端点描述符说我使用了1端点,最大长度是xxx
音频流端点描述符说我没啥意思,就是过来看看
对,就这样。这个公司的所有部门安排和人员安排就已经完事了。。。
惊不惊喜,意不意外。如果你按照上述对话的每一行去配置相应的描述符,肯定是可以识别的。
所以只要掌握核心逻辑,这些就都不是问题。
/****************************************************此区间查看如果犯困可以往下翻*******************************************************/
设备描述符(不重要看看就得了)
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01, /*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
设备描述符就不多说了,随便找找资料就应该差不多了。
字符串描述符(不重要看看就得了)
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
{
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)
};
这个没啥东西就是电脑上显示的的一段字符串,跟具体应用实现关系不大。过~~~
设备限定描述符(不重要看看就得了)
主要是描述有关高速设备的信息。如果设备是高速状态运行则直接返回。
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
bos描述符(不重要看看就得了)
/* USB_DeviceDescriptor */
/** BOS descriptor. */
#if (USBD_LPM_ENABLED == 1)
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
{
0x5,
USB_DESC_TYPE_BOS,
0xC,
0x0,
0x1, /* 1 device capability*/
/* device capability*/
0x7,
USB_DEVICE_CAPABITY_TYPE,
0x2,
0x2, /* LPM capability bit set*/
0x0,
0x0,
0x0
};
重头戏来了,从配置描述符开始(别闭眼)。
__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),
0x02, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* bMaxPower = 100 mA */
/* 09 byte*/
/* USB Speaker Standard interface descriptor */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Class-specific AC Interface Descriptor */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
0x00, /* 1.00 */ /* bcdADC */
0x01,
0x27, /* wTotalLength = 39*/
0x00,
0x01, /* bInCollection */
0x01, /* baInterfaceNr */
/* 09 byte*/
/* USB Speaker Input Terminal Descriptor */
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
0x01, /* bTerminalID */
0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */
0x01,
0x00, /* bAssocTerminal */
0x01, /* bNrChannels */
0x00, /* wChannelConfig 0x0000 Mono */
0x00,
0x00, /* iChannelNames */
0x00, /* iTerminal */
/* 12 byte*/
/* USB Speaker Audio Feature Unit Descriptor */
0x09, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
AUDIO_OUT_STREAMING_CTRL, /* bUnitID */
0x01, /* bSourceID */
0x01, /* bControlSize */
AUDIO_CONTROL_MUTE, /* bmaControls(0) */
0, /* bmaControls(1) */
0x00, /* iTerminal */
/* 09 byte*/
/*USB Speaker Output Terminal Descriptor */
0x09, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
0x03, /* bTerminalID */
0x01, /* wTerminalType 0x0301*/
0x03,
0x00, /* bAssocTerminal */
0x02, /* bSourceID */
0x00, /* iTerminal */
/* 09 byte*/
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */
/* Interface 1, Alternate Setting 0 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
/* Interface 1, Alternate Setting 1 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Audio Streaming Interface Descriptor */
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
0x01, /* bTerminalLink */
0x01, /* bDelay */
0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001 */
0x00,
/* 07 byte*/
/* USB Speaker Audio Type III Format Interface Descriptor */
0x0B, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
AUDIO_FORMAT_TYPE_I, /* bFormatType */
0x02, /* bNrChannels */
0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
16, /* bBitResolution (16-bits per sample) */
0x01, /* bSamFreqType only one frequency supported */
AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */
/* 11 byte*/
/* Endpoint 1 - Standard Descriptor */
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */
AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint */
USBD_EP_TYPE_ISOC, /* bmAttributes */
AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
AUDIO_FS_BINTERVAL, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* 09 byte*/
/* Endpoint - Audio Streaming Descriptor*/
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
0x00, /* bmAttributes */
0x00, /* bLockDelayUnits */
0x00, /* wLockDelay */
0x00,
/* 07 byte*/
} ;
/****************************************************犯困区间结束*******************************************************/
本章接下来还有,今天就更到这里。。。。。。。。。。。。。。。。。。。。