【发布时间】:2022-06-18 07:30:00
【问题描述】:
目前我正在尝试在 STM32F407 上创建某种 USB 耳机 - 设备,能够播放来自主机的音频流并发送从麦克风接收的音频样本。
USB 音频设备拓扑如下所示(抱歉质量不好): topology
我在这里使用两个端点。因此我在 USB 描述符中描述了两个接口。
描述符如下所示:
static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] =
{
/* Configuration 1 */
0x09, /* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 183 bytes*/
HIBYTE(AUDIO_CONFIG_DESC_SIZE),
0x03, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xC0, /* bmAttributes BUS Powred*/
0x32, /* bMaxPower = 100 mA*/
/* 09 byte*/
/* USB Headset Standard interface descriptor */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* 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 Headset Class-specific AC Interface Descriptor */
0x0A, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
0x00, /* 1.00 */ /* bcdADC */
0x01,
0x3C, /* wTotalLength = 60*/
0x00,
0x02, /* bInCollection */
0x01, /* baInterfaceNr(1) - OUT */
0x02, /* baInterfaceNr(2) - IN */
/* 10 byte*/
/* USB Microphone Input Terminal Descriptor */
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
0x01, /* bTerminalID */
0x01, /* wTerminalType MICROPHONE 0x0201 */
0x02,
0x00, /* bAssocTerminal */
0x01, /* bNrChannels */
0x00, /* wChannelConfig 0x0000 Mono */
0x00,
0x00, /* iChannelNames */
0x00, /* iTerminal */
/* 12 byte*/
/*USB Microphone Output Terminal Descriptor */
0x09, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
0x02, /* bTerminalID */
0x01, /* wTerminalType USB_STREAMING 0x0101*/
0x01,
0x00, /* bAssocTerminal */
0x01, /* bSourceID */
0x00, /* iTerminal */
/* 09 byte*/
/* USB Speaker Input Terminal Descriptor */
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
0x05, /* 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_FEATURE_UNIT_ID, /* bUnitID */
0x05, /* bSourceID */
0x01, /* bControlSize */
AUDIO_CONTROL_MUTE, /* bmaControls(0) */
0x00, /* 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 */
0x04, /* bSourceID */
0x00, /* iTerminal */
/* 09 byte*/
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
/* Interface 1, Alternate Setting 0 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* 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_INTERFACE_DESCRIPTOR_TYPE, /* 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 */
0x05, /* 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_III, /* bFormatType */
0x02, /* bNrChannels */
0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
16, /* bBitResolution (16-bits per sample) */
0x01, /* bSamFreqType only one frequency supported */
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_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/
USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */
AUDIO_PACKET_SZE(USBD_AUDIO_FREQ, 2), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
0x01, /* 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*/
/* USB Microphone Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
/* Interface 2, Alternate Setting 0 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x02, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Microphone Standard AS Interface Descriptor - Audio Streaming Operational */
/* Interface 2, Alternate Setting 1 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x02, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Microphone Audio Streaming Interface Descriptor */
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
0x02, /* bTerminalLink */
0x01, /* bDelay */
0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/
0x00,
/* 07 byte*/
/* USB Microphone Type I Format Interface Descriptor */
0x0B, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
AUDIO_FORMAT_TYPE_I, /* bFormatType */
0x01, /* bNrChannels */
0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
16, /* bBitResolution (16-bits per sample) */
0x01, /* bSamFreqType only one frequency supported */
SAMPLE_FREQ(USBD_IN_FREQ), /* Audio sampling frequency coded on 3 bytes */
/* 11 byte*/
/* Endpoint 1 - Standard Descriptor */
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_IN_EP, /* bEndpointAddress 1 out endpoint*/
USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */
AUDIO_PACKET_SZE(USBD_IN_FREQ, 1), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
0x01, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* 09 byte*/
/* Endpoint - Audio Microphone 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*/
} ;
当我将此设备连接到主机时,主机似乎成功枚举它。
主机日志(Linux OS):
[12221.001223] usb 3-4: New USB device found, idVendor=0483, idProduct=5730, bcdDevice= 2.00
[12221.001246] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[12221.001248] usb 3-4: Product: STM32 AUDIO Streaming in FS Mode
[12221.001250] usb 3-4: Manufacturer: STMicroelectronics
[12221.001252] usb 3-4: SerialNumber: 347E37553434
[12221.037373] mc: Linux media interface: v0.10
[12221.073785] usbcore: registered new interface driver snd-usb-audio
这个新连接的设备能够播放它从主机接收的音频流。但是当我尝试记录某些内容时,我在日志中看到以下消息:
[12758.466715] usb 3-4: 2:1: usb_set_interface failed (-32)
[12758.466894] usb 3-4: 2:0: usb_set_interface failed (-32)
[12758.826837] usb 3-4: 2:0: usb_set_interface failed (-32)
[12758.827398] usb 3-4: 2:1: usb_set_interface failed (-32)
似乎,该主机未能设置第二个接口 - 从设备麦克风到主机的音频流接口。
当我尝试使用 Wireshark 嗅探 USB 数据包时,我看到以下内容:
- 设备成功发送他的所有描述符。
- 主机尝试为接口 1 设置不同的 alt 设置 - 所有请求均成功完成。
- 主机尝试对接口 2 执行相同的操作 - 失败并出现错误“管道损坏”
设置接口1.请求:
USB URB
[Source: host]
[Destination: 3.8.0]
URB id: 0xffff8ce44b991e40
URB type: URB_SUBMIT ('S')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x00, Direction: OUT
Device: 8
URB bus id: 3
Device setup request: relevant (0)
Data: present (0)
URB sec: 1645475418
URB usec: 822919
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 0
Data length [bytes]: 0
[Response in: 32]
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000000
Number of ISO descriptors: 0
Setup Data
bmRequestType: 0x01
bRequest: SET INTERFACE (11)
bAlternateSetting: 0
wInterface: 1
wLength: 0
设置界面1.响应:
USB URB
[Source: 3.8.0]
[Destination: host]
URB id: 0xffff8ce44b991e40
URB type: URB_COMPLETE ('C')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x00, Direction: OUT
Device: 8
URB bus id: 3
Device setup request: not relevant ('-')
Data: not present ('>')
URB sec: 1645475418
URB usec: 822989
URB status: Success (0)
URB length [bytes]: 0
Data length [bytes]: 0
[Request in: 31]
[Time from request: 0.000070000 seconds]
Unused Setup Header
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000000
Number of ISO descriptors: 0
设置接口2.请求:
USB URB
[Source: host]
[Destination: 3.8.0]
URB id: 0xffff8ce63c2d2840
URB type: URB_SUBMIT ('S')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x00, Direction: OUT
Device: 8
URB bus id: 3
Device setup request: relevant (0)
Data: present (0)
URB sec: 1645475418
URB usec: 823040
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 0
Data length [bytes]: 0
[Response in: 34]
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000000
Number of ISO descriptors: 0
Setup Data
bmRequestType: 0x01
bRequest: SET INTERFACE (11)
bAlternateSetting: 0
wInterface: 2
wLength: 0
设置界面2.响应:
USB URB
[Source: 3.8.0]
[Destination: host]
URB id: 0xffff8ce63c2d2840
URB type: URB_COMPLETE ('C')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x00, Direction: OUT
Device: 8
URB bus id: 3
Device setup request: not relevant ('-')
Data: not present ('>')
URB sec: 1645475418
URB usec: 823198
URB status: Broken pipe (-EPIPE) (-32)
URB length [bytes]: 0
Data length [bytes]: 0
[Request in: 33]
[Time from request: 0.000158000 seconds]
Unused Setup Header
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000000
Number of ISO descriptors: 0
我将整个wireshark .cap 文件放在我的google drive 磁盘中:
您可以在我的github (branch - task/usb_headset) 中找到我的整个项目的代码
我尝试将两个音频流的采样频率设置为 48 kHz。根据上述来自主机的音频流的描述符 - 48kHz,立体声;到主机的音频流 - 16kHz,单声道。同样的错误。
任何帮助将不胜感激。
【问题讨论】:
-
好的。在第二个接口的初始化过程中,我似乎已经解决了 -EPIPE(-32) 错误的问题。这是我在设备中配置 USB 堆栈的问题。
-
但现在我遇到了新问题 - 设备无法从主机播放音乐并同时从麦克风录制我的声音。如果我在从主机播放音乐期间尝试从麦克风录制某些内容 - 播放过程将停止并开始录制过程。我猜测。我的代码中有一个严重的错误。但是如果有人在描述符中看到一些明显的错误,请告诉我
标签: audio usb stm32f4discovery